UNPKG

henotic-cli

Version:

Henotic CLI is the ultimate multi-language backend generator, accelerating development with modular project structures and smart CRUD generation. Streamline your workflow from day one!

13,885 lines 443 kB
#!/usr/bin/env bun
// @bun
var __create = Object.create;
var __getProtoOf = Object.getPrototypeOf;
var __defProp = Object.defineProperty;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __toESM = (mod, isNodeMode, target) => {
  target = mod != null ? __create(__getProtoOf(mod)) : {};
  const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
  for (let key of __getOwnPropNames(mod))
    if (!__hasOwnProp.call(to, key))
      __defProp(to, key, {
        get: () => mod[key],
        enumerable: true
      });
  return to;
};
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, {
      get: all[name],
      enumerable: true,
      configurable: true,
      set: (newValue) => all[name] = () => newValue
    });
};
var __require = import.meta.require;

// node_modules/kleur/index.js
var require_kleur = __commonJS((exports, module) => {
  var { FORCE_COLOR, NODE_DISABLE_COLORS, TERM } = process.env;
  var $ = {
    enabled: !NODE_DISABLE_COLORS && TERM !== "dumb" && FORCE_COLOR !== "0",
    reset: init(0, 0),
    bold: init(1, 22),
    dim: init(2, 22),
    italic: init(3, 23),
    underline: init(4, 24),
    inverse: init(7, 27),
    hidden: init(8, 28),
    strikethrough: init(9, 29),
    black: init(30, 39),
    red: init(31, 39),
    green: init(32, 39),
    yellow: init(33, 39),
    blue: init(34, 39),
    magenta: init(35, 39),
    cyan: init(36, 39),
    white: init(37, 39),
    gray: init(90, 39),
    grey: init(90, 39),
    bgBlack: init(40, 49),
    bgRed: init(41, 49),
    bgGreen: init(42, 49),
    bgYellow: init(43, 49),
    bgBlue: init(44, 49),
    bgMagenta: init(45, 49),
    bgCyan: init(46, 49),
    bgWhite: init(47, 49)
  };
  function run(arr, str) {
    let i = 0, tmp, beg = "", end = "";
    for (;i < arr.length; i++) {
      tmp = arr[i];
      beg += tmp.open;
      end += tmp.close;
      if (str.includes(tmp.close)) {
        str = str.replace(tmp.rgx, tmp.close + tmp.open);
      }
    }
    return beg + str + end;
  }
  function chain(has, keys) {
    let ctx = { has, keys };
    ctx.reset = $.reset.bind(ctx);
    ctx.bold = $.bold.bind(ctx);
    ctx.dim = $.dim.bind(ctx);
    ctx.italic = $.italic.bind(ctx);
    ctx.underline = $.underline.bind(ctx);
    ctx.inverse = $.inverse.bind(ctx);
    ctx.hidden = $.hidden.bind(ctx);
    ctx.strikethrough = $.strikethrough.bind(ctx);
    ctx.black = $.black.bind(ctx);
    ctx.red = $.red.bind(ctx);
    ctx.green = $.green.bind(ctx);
    ctx.yellow = $.yellow.bind(ctx);
    ctx.blue = $.blue.bind(ctx);
    ctx.magenta = $.magenta.bind(ctx);
    ctx.cyan = $.cyan.bind(ctx);
    ctx.white = $.white.bind(ctx);
    ctx.gray = $.gray.bind(ctx);
    ctx.grey = $.grey.bind(ctx);
    ctx.bgBlack = $.bgBlack.bind(ctx);
    ctx.bgRed = $.bgRed.bind(ctx);
    ctx.bgGreen = $.bgGreen.bind(ctx);
    ctx.bgYellow = $.bgYellow.bind(ctx);
    ctx.bgBlue = $.bgBlue.bind(ctx);
    ctx.bgMagenta = $.bgMagenta.bind(ctx);
    ctx.bgCyan = $.bgCyan.bind(ctx);
    ctx.bgWhite = $.bgWhite.bind(ctx);
    return ctx;
  }
  function init(open, close) {
    let blk = {
      open: `\x1B[${open}m`,
      close: `\x1B[${close}m`,
      rgx: new RegExp(`\\x1b\\[${close}m`, "g")
    };
    return function(txt) {
      if (this !== undefined && this.has !== undefined) {
        this.has.includes(open) || (this.has.push(open), this.keys.push(blk));
        return txt === undefined ? this : $.enabled ? run(this.keys, txt + "") : txt + "";
      }
      return txt === undefined ? chain([open], [blk]) : $.enabled ? run([blk], txt + "") : txt + "";
    };
  }
  module.exports = $;
});

// node_modules/prompts/dist/util/action.js
var require_action = __commonJS((exports, module) => {
  module.exports = (key, isSelect) => {
    if (key.meta && key.name !== "escape")
      return;
    if (key.ctrl) {
      if (key.name === "a")
        return "first";
      if (key.name === "c")
        return "abort";
      if (key.name === "d")
        return "abort";
      if (key.name === "e")
        return "last";
      if (key.name === "g")
        return "reset";
    }
    if (isSelect) {
      if (key.name === "j")
        return "down";
      if (key.name === "k")
        return "up";
    }
    if (key.name === "return")
      return "submit";
    if (key.name === "enter")
      return "submit";
    if (key.name === "backspace")
      return "delete";
    if (key.name === "delete")
      return "deleteForward";
    if (key.name === "abort")
      return "abort";
    if (key.name === "escape")
      return "exit";
    if (key.name === "tab")
      return "next";
    if (key.name === "pagedown")
      return "nextPage";
    if (key.name === "pageup")
      return "prevPage";
    if (key.name === "home")
      return "home";
    if (key.name === "end")
      return "end";
    if (key.name === "up")
      return "up";
    if (key.name === "down")
      return "down";
    if (key.name === "right")
      return "right";
    if (key.name === "left")
      return "left";
    return false;
  };
});

// node_modules/prompts/dist/util/strip.js
var require_strip = __commonJS((exports, module) => {
  module.exports = (str) => {
    const pattern = ["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)", "(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PRZcf-ntqry=><~]))"].join("|");
    const RGX = new RegExp(pattern, "g");
    return typeof str === "string" ? str.replace(RGX, "") : str;
  };
});

// node_modules/sisteransi/src/index.js
var require_src = __commonJS((exports, module) => {
  var ESC = "\x1B";
  var CSI = `${ESC}[`;
  var beep = "\x07";
  var cursor = {
    to(x, y) {
      if (!y)
        return `${CSI}${x + 1}G`;
      return `${CSI}${y + 1};${x + 1}H`;
    },
    move(x, y) {
      let ret = "";
      if (x < 0)
        ret += `${CSI}${-x}D`;
      else if (x > 0)
        ret += `${CSI}${x}C`;
      if (y < 0)
        ret += `${CSI}${-y}A`;
      else if (y > 0)
        ret += `${CSI}${y}B`;
      return ret;
    },
    up: (count = 1) => `${CSI}${count}A`,
    down: (count = 1) => `${CSI}${count}B`,
    forward: (count = 1) => `${CSI}${count}C`,
    backward: (count = 1) => `${CSI}${count}D`,
    nextLine: (count = 1) => `${CSI}E`.repeat(count),
    prevLine: (count = 1) => `${CSI}F`.repeat(count),
    left: `${CSI}G`,
    hide: `${CSI}?25l`,
    show: `${CSI}?25h`,
    save: `${ESC}7`,
    restore: `${ESC}8`
  };
  var scroll = {
    up: (count = 1) => `${CSI}S`.repeat(count),
    down: (count = 1) => `${CSI}T`.repeat(count)
  };
  var erase = {
    screen: `${CSI}2J`,
    up: (count = 1) => `${CSI}1J`.repeat(count),
    down: (count = 1) => `${CSI}J`.repeat(count),
    line: `${CSI}2K`,
    lineEnd: `${CSI}K`,
    lineStart: `${CSI}1K`,
    lines(count) {
      let clear = "";
      for (let i = 0;i < count; i++)
        clear += this.line + (i < count - 1 ? cursor.up() : "");
      if (count)
        clear += cursor.left;
      return clear;
    }
  };
  module.exports = { cursor, scroll, erase, beep };
});

// node_modules/prompts/dist/util/clear.js
var require_clear = __commonJS((exports, module) => {
  function _createForOfIteratorHelper(o, allowArrayLike) {
    var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
    if (!it) {
      if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
        if (it)
          o = it;
        var i = 0;
        var F = function F() {};
        return { s: F, n: function n() {
          if (i >= o.length)
            return { done: true };
          return { done: false, value: o[i++] };
        }, e: function e(_e) {
          throw _e;
        }, f: F };
      }
      throw new TypeError(`Invalid attempt to iterate non-iterable instance.
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`);
    }
    var normalCompletion = true, didErr = false, err;
    return { s: function s() {
      it = it.call(o);
    }, n: function n() {
      var step = it.next();
      normalCompletion = step.done;
      return step;
    }, e: function e(_e2) {
      didErr = true;
      err = _e2;
    }, f: function f() {
      try {
        if (!normalCompletion && it.return != null)
          it.return();
      } finally {
        if (didErr)
          throw err;
      }
    } };
  }
  function _unsupportedIterableToArray(o, minLen) {
    if (!o)
      return;
    if (typeof o === "string")
      return _arrayLikeToArray(o, minLen);
    var n = Object.prototype.toString.call(o).slice(8, -1);
    if (n === "Object" && o.constructor)
      n = o.constructor.name;
    if (n === "Map" || n === "Set")
      return Array.from(o);
    if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))
      return _arrayLikeToArray(o, minLen);
  }
  function _arrayLikeToArray(arr, len) {
    if (len == null || len > arr.length)
      len = arr.length;
    for (var i = 0, arr2 = new Array(len);i < len; i++)
      arr2[i] = arr[i];
    return arr2;
  }
  var strip = require_strip();
  var _require = require_src();
  var erase = _require.erase;
  var cursor = _require.cursor;
  var width = (str) => [...strip(str)].length;
  module.exports = function(prompt, perLine) {
    if (!perLine)
      return erase.line + cursor.to(0);
    let rows = 0;
    const lines = prompt.split(/\r?\n/);
    var _iterator = _createForOfIteratorHelper(lines), _step;
    try {
      for (_iterator.s();!(_step = _iterator.n()).done; ) {
        let line = _step.value;
        rows += 1 + Math.floor(Math.max(width(line) - 1, 0) / perLine);
      }
    } catch (err) {
      _iterator.e(err);
    } finally {
      _iterator.f();
    }
    return erase.lines(rows);
  };
});

// node_modules/prompts/dist/util/figures.js
var require_figures = __commonJS((exports, module) => {
  var main = {
    arrowUp: "\u2191",
    arrowDown: "\u2193",
    arrowLeft: "\u2190",
    arrowRight: "\u2192",
    radioOn: "\u25C9",
    radioOff: "\u25EF",
    tick: "\u2714",
    cross: "\u2716",
    ellipsis: "\u2026",
    pointerSmall: "\u203A",
    line: "\u2500",
    pointer: "\u276F"
  };
  var win = {
    arrowUp: main.arrowUp,
    arrowDown: main.arrowDown,
    arrowLeft: main.arrowLeft,
    arrowRight: main.arrowRight,
    radioOn: "(*)",
    radioOff: "( )",
    tick: "\u221A",
    cross: "\xD7",
    ellipsis: "...",
    pointerSmall: "\xBB",
    line: "\u2500",
    pointer: ">"
  };
  var figures = process.platform === "win32" ? win : main;
  module.exports = figures;
});

// node_modules/prompts/dist/util/style.js
var require_style = __commonJS((exports, module) => {
  var c = require_kleur();
  var figures = require_figures();
  var styles3 = Object.freeze({
    password: {
      scale: 1,
      render: (input) => "*".repeat(input.length)
    },
    emoji: {
      scale: 2,
      render: (input) => "\uD83D\uDE03".repeat(input.length)
    },
    invisible: {
      scale: 0,
      render: (input) => ""
    },
    default: {
      scale: 1,
      render: (input) => `${input}`
    }
  });
  var render = (type) => styles3[type] || styles3.default;
  var symbols = Object.freeze({
    aborted: c.red(figures.cross),
    done: c.green(figures.tick),
    exited: c.yellow(figures.cross),
    default: c.cyan("?")
  });
  var symbol = (done, aborted, exited) => aborted ? symbols.aborted : exited ? symbols.exited : done ? symbols.done : symbols.default;
  var delimiter = (completing) => c.gray(completing ? figures.ellipsis : figures.pointerSmall);
  var item = (expandable, expanded) => c.gray(expandable ? expanded ? figures.pointerSmall : "+" : figures.line);
  module.exports = {
    styles: styles3,
    render,
    symbols,
    symbol,
    delimiter,
    item
  };
});

// node_modules/prompts/dist/util/lines.js
var require_lines = __commonJS((exports, module) => {
  var strip = require_strip();
  module.exports = function(msg, perLine) {
    let lines = String(strip(msg) || "").split(/\r?\n/);
    if (!perLine)
      return lines.length;
    return lines.map((l) => Math.ceil(l.length / perLine)).reduce((a, b) => a + b);
  };
});

// node_modules/prompts/dist/util/wrap.js
var require_wrap = __commonJS((exports, module) => {
  module.exports = (msg, opts = {}) => {
    const tab = Number.isSafeInteger(parseInt(opts.margin)) ? new Array(parseInt(opts.margin)).fill(" ").join("") : opts.margin || "";
    const width = opts.width;
    return (msg || "").split(/\r?\n/g).map((line) => line.split(/\s+/g).reduce((arr, w) => {
      if (w.length + tab.length >= width || arr[arr.length - 1].length + w.length + 1 < width)
        arr[arr.length - 1] += ` ${w}`;
      else
        arr.push(`${tab}${w}`);
      return arr;
    }, [tab]).join(`
`)).join(`
`);
  };
});

// node_modules/prompts/dist/util/entriesToDisplay.js
var require_entriesToDisplay = __commonJS((exports, module) => {
  module.exports = (cursor, total, maxVisible) => {
    maxVisible = maxVisible || total;
    let startIndex = Math.min(total - maxVisible, cursor - Math.floor(maxVisible / 2));
    if (startIndex < 0)
      startIndex = 0;
    let endIndex = Math.min(startIndex + maxVisible, total);
    return {
      startIndex,
      endIndex
    };
  };
});

// node_modules/prompts/dist/util/index.js
var require_util = __commonJS((exports, module) => {
  module.exports = {
    action: require_action(),
    clear: require_clear(),
    style: require_style(),
    strip: require_strip(),
    figures: require_figures(),
    lines: require_lines(),
    wrap: require_wrap(),
    entriesToDisplay: require_entriesToDisplay()
  };
});

// node_modules/prompts/dist/elements/prompt.js
var require_prompt = __commonJS((exports, module) => {
  var readline = __require("readline");
  var _require = require_util();
  var action = _require.action;
  var EventEmitter = __require("events");
  var _require2 = require_src();
  var beep = _require2.beep;
  var cursor = _require2.cursor;
  var color = require_kleur();

  class Prompt extends EventEmitter {
    constructor(opts = {}) {
      super();
      this.firstRender = true;
      this.in = opts.stdin || process.stdin;
      this.out = opts.stdout || process.stdout;
      this.onRender = (opts.onRender || (() => {
        return;
      })).bind(this);
      const rl = readline.createInterface({
        input: this.in,
        escapeCodeTimeout: 50
      });
      readline.emitKeypressEvents(this.in, rl);
      if (this.in.isTTY)
        this.in.setRawMode(true);
      const isSelect = ["SelectPrompt", "MultiselectPrompt"].indexOf(this.constructor.name) > -1;
      const keypress = (str, key) => {
        let a = action(key, isSelect);
        if (a === false) {
          this._ && this._(str, key);
        } else if (typeof this[a] === "function") {
          this[a](key);
        } else {
          this.bell();
        }
      };
      this.close = () => {
        this.out.write(cursor.show);
        this.in.removeListener("keypress", keypress);
        if (this.in.isTTY)
          this.in.setRawMode(false);
        rl.close();
        this.emit(this.aborted ? "abort" : this.exited ? "exit" : "submit", this.value);
        this.closed = true;
      };
      this.in.on("keypress", keypress);
    }
    fire() {
      this.emit("state", {
        value: this.value,
        aborted: !!this.aborted,
        exited: !!this.exited
      });
    }
    bell() {
      this.out.write(beep);
    }
    render() {
      this.onRender(color);
      if (this.firstRender)
        this.firstRender = false;
    }
  }
  module.exports = Prompt;
});

// node_modules/prompts/dist/elements/text.js
var require_text = __commonJS((exports, module) => {
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
    try {
      var info = gen[key](arg);
      var value = info.value;
    } catch (error) {
      reject(error);
      return;
    }
    if (info.done) {
      resolve(value);
    } else {
      Promise.resolve(value).then(_next, _throw);
    }
  }
  function _asyncToGenerator(fn) {
    return function() {
      var self = this, args = arguments;
      return new Promise(function(resolve, reject) {
        var gen = fn.apply(self, args);
        function _next(value) {
          asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
        }
        function _throw(err) {
          asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
        }
        _next(undefined);
      });
    };
  }
  var color = require_kleur();
  var Prompt = require_prompt();
  var _require = require_src();
  var erase = _require.erase;
  var cursor = _require.cursor;
  var _require2 = require_util();
  var style = _require2.style;
  var clear = _require2.clear;
  var lines = _require2.lines;
  var figures = _require2.figures;

  class TextPrompt extends Prompt {
    constructor(opts = {}) {
      super(opts);
      this.transform = style.render(opts.style);
      this.scale = this.transform.scale;
      this.msg = opts.message;
      this.initial = opts.initial || ``;
      this.validator = opts.validate || (() => true);
      this.value = ``;
      this.errorMsg = opts.error || `Please Enter A Valid Value`;
      this.cursor = Number(!!this.initial);
      this.cursorOffset = 0;
      this.clear = clear(``, this.out.columns);
      this.render();
    }
    set value(v) {
      if (!v && this.initial) {
        this.placeholder = true;
        this.rendered = color.gray(this.transform.render(this.initial));
      } else {
        this.placeholder = false;
        this.rendered = this.transform.render(v);
      }
      this._value = v;
      this.fire();
    }
    get value() {
      return this._value;
    }
    reset() {
      this.value = ``;
      this.cursor = Number(!!this.initial);
      this.cursorOffset = 0;
      this.fire();
      this.render();
    }
    exit() {
      this.abort();
    }
    abort() {
      this.value = this.value || this.initial;
      this.done = this.aborted = true;
      this.error = false;
      this.red = false;
      this.fire();
      this.render();
      this.out.write(`
`);
      this.close();
    }
    validate() {
      var _this = this;
      return _asyncToGenerator(function* () {
        let valid = yield _this.validator(_this.value);
        if (typeof valid === `string`) {
          _this.errorMsg = valid;
          valid = false;
        }
        _this.error = !valid;
      })();
    }
    submit() {
      var _this2 = this;
      return _asyncToGenerator(function* () {
        _this2.value = _this2.value || _this2.initial;
        _this2.cursorOffset = 0;
        _this2.cursor = _this2.rendered.length;
        yield _this2.validate();
        if (_this2.error) {
          _this2.red = true;
          _this2.fire();
          _this2.render();
          return;
        }
        _this2.done = true;
        _this2.aborted = false;
        _this2.fire();
        _this2.render();
        _this2.out.write(`
`);
        _this2.close();
      })();
    }
    next() {
      if (!this.placeholder)
        return this.bell();
      this.value = this.initial;
      this.cursor = this.rendered.length;
      this.fire();
      this.render();
    }
    moveCursor(n) {
      if (this.placeholder)
        return;
      this.cursor = this.cursor + n;
      this.cursorOffset += n;
    }
    _(c, key) {
      let s1 = this.value.slice(0, this.cursor);
      let s2 = this.value.slice(this.cursor);
      this.value = `${s1}${c}${s2}`;
      this.red = false;
      this.cursor = this.placeholder ? 0 : s1.length + 1;
      this.render();
    }
    delete() {
      if (this.isCursorAtStart())
        return this.bell();
      let s1 = this.value.slice(0, this.cursor - 1);
      let s2 = this.value.slice(this.cursor);
      this.value = `${s1}${s2}`;
      this.red = false;
      if (this.isCursorAtStart()) {
        this.cursorOffset = 0;
      } else {
        this.cursorOffset++;
        this.moveCursor(-1);
      }
      this.render();
    }
    deleteForward() {
      if (this.cursor * this.scale >= this.rendered.length || this.placeholder)
        return this.bell();
      let s1 = this.value.slice(0, this.cursor);
      let s2 = this.value.slice(this.cursor + 1);
      this.value = `${s1}${s2}`;
      this.red = false;
      if (this.isCursorAtEnd()) {
        this.cursorOffset = 0;
      } else {
        this.cursorOffset++;
      }
      this.render();
    }
    first() {
      this.cursor = 0;
      this.render();
    }
    last() {
      this.cursor = this.value.length;
      this.render();
    }
    left() {
      if (this.cursor <= 0 || this.placeholder)
        return this.bell();
      this.moveCursor(-1);
      this.render();
    }
    right() {
      if (this.cursor * this.scale >= this.rendered.length || this.placeholder)
        return this.bell();
      this.moveCursor(1);
      this.render();
    }
    isCursorAtStart() {
      return this.cursor === 0 || this.placeholder && this.cursor === 1;
    }
    isCursorAtEnd() {
      return this.cursor === this.rendered.length || this.placeholder && this.cursor === this.rendered.length + 1;
    }
    render() {
      if (this.closed)
        return;
      if (!this.firstRender) {
        if (this.outputError)
          this.out.write(cursor.down(lines(this.outputError, this.out.columns) - 1) + clear(this.outputError, this.out.columns));
        this.out.write(clear(this.outputText, this.out.columns));
      }
      super.render();
      this.outputError = "";
      this.outputText = [style.symbol(this.done, this.aborted), color.bold(this.msg), style.delimiter(this.done), this.red ? color.red(this.rendered) : this.rendered].join(` `);
      if (this.error) {
        this.outputError += this.errorMsg.split(`
`).reduce((a, l, i) => a + `
${i ? " " : figures.pointerSmall} ${color.red().italic(l)}`, ``);
      }
      this.out.write(erase.line + cursor.to(0) + this.outputText + cursor.save + this.outputError + cursor.restore + cursor.move(this.cursorOffset, 0));
    }
  }
  module.exports = TextPrompt;
});

// node_modules/prompts/dist/elements/select.js
var require_select = __commonJS((exports, module) => {
  var color = require_kleur();
  var Prompt = require_prompt();
  var _require = require_util();
  var style = _require.style;
  var clear = _require.clear;
  var figures = _require.figures;
  var wrap = _require.wrap;
  var entriesToDisplay = _require.entriesToDisplay;
  var _require2 = require_src();
  var cursor = _require2.cursor;

  class SelectPrompt extends Prompt {
    constructor(opts = {}) {
      super(opts);
      this.msg = opts.message;
      this.hint = opts.hint || "- Use arrow-keys. Return to submit.";
      this.warn = opts.warn || "- This option is disabled";
      this.cursor = opts.initial || 0;
      this.choices = opts.choices.map((ch, idx) => {
        if (typeof ch === "string")
          ch = {
            title: ch,
            value: idx
          };
        return {
          title: ch && (ch.title || ch.value || ch),
          value: ch && (ch.value === undefined ? idx : ch.value),
          description: ch && ch.description,
          selected: ch && ch.selected,
          disabled: ch && ch.disabled
        };
      });
      this.optionsPerPage = opts.optionsPerPage || 10;
      this.value = (this.choices[this.cursor] || {}).value;
      this.clear = clear("", this.out.columns);
      this.render();
    }
    moveCursor(n) {
      this.cursor = n;
      this.value = this.choices[n].value;
      this.fire();
    }
    reset() {
      this.moveCursor(0);
      this.fire();
      this.render();
    }
    exit() {
      this.abort();
    }
    abort() {
      this.done = this.aborted = true;
      this.fire();
      this.render();
      this.out.write(`
`);
      this.close();
    }
    submit() {
      if (!this.selection.disabled) {
        this.done = true;
        this.aborted = false;
        this.fire();
        this.render();
        this.out.write(`
`);
        this.close();
      } else
        this.bell();
    }
    first() {
      this.moveCursor(0);
      this.render();
    }
    last() {
      this.moveCursor(this.choices.length - 1);
      this.render();
    }
    up() {
      if (this.cursor === 0) {
        this.moveCursor(this.choices.length - 1);
      } else {
        this.moveCursor(this.cursor - 1);
      }
      this.render();
    }
    down() {
      if (this.cursor === this.choices.length - 1) {
        this.moveCursor(0);
      } else {
        this.moveCursor(this.cursor + 1);
      }
      this.render();
    }
    next() {
      this.moveCursor((this.cursor + 1) % this.choices.length);
      this.render();
    }
    _(c, key) {
      if (c === " ")
        return this.submit();
    }
    get selection() {
      return this.choices[this.cursor];
    }
    render() {
      if (this.closed)
        return;
      if (this.firstRender)
        this.out.write(cursor.hide);
      else
        this.out.write(clear(this.outputText, this.out.columns));
      super.render();
      let _entriesToDisplay = entriesToDisplay(this.cursor, this.choices.length, this.optionsPerPage), startIndex = _entriesToDisplay.startIndex, endIndex = _entriesToDisplay.endIndex;
      this.outputText = [style.symbol(this.done, this.aborted), color.bold(this.msg), style.delimiter(false), this.done ? this.selection.title : this.selection.disabled ? color.yellow(this.warn) : color.gray(this.hint)].join(" ");
      if (!this.done) {
        this.outputText += `
`;
        for (let i = startIndex;i < endIndex; i++) {
          let title, prefix, desc = "", v = this.choices[i];
          if (i === startIndex && startIndex > 0) {
            prefix = figures.arrowUp;
          } else if (i === endIndex - 1 && endIndex < this.choices.length) {
            prefix = figures.arrowDown;
          } else {
            prefix = " ";
          }
          if (v.disabled) {
            title = this.cursor === i ? color.gray().underline(v.title) : color.strikethrough().gray(v.title);
            prefix = (this.cursor === i ? color.bold().gray(figures.pointer) + " " : "  ") + prefix;
          } else {
            title = this.cursor === i ? color.cyan().underline(v.title) : v.title;
            prefix = (this.cursor === i ? color.cyan(figures.pointer) + " " : "  ") + prefix;
            if (v.description && this.cursor === i) {
              desc = ` - ${v.description}`;
              if (prefix.length + title.length + desc.length >= this.out.columns || v.description.split(/\r?\n/).length > 1) {
                desc = `
` + wrap(v.description, {
                  margin: 3,
                  width: this.out.columns
                });
              }
            }
          }
          this.outputText += `${prefix} ${title}${color.gray(desc)}
`;
        }
      }
      this.out.write(this.outputText);
    }
  }
  module.exports = SelectPrompt;
});

// node_modules/prompts/dist/elements/toggle.js
var require_toggle = __commonJS((exports, module) => {
  var color = require_kleur();
  var Prompt = require_prompt();
  var _require = require_util();
  var style = _require.style;
  var clear = _require.clear;
  var _require2 = require_src();
  var cursor = _require2.cursor;
  var erase = _require2.erase;

  class TogglePrompt extends Prompt {
    constructor(opts = {}) {
      super(opts);
      this.msg = opts.message;
      this.value = !!opts.initial;
      this.active = opts.active || "on";
      this.inactive = opts.inactive || "off";
      this.initialValue = this.value;
      this.render();
    }
    reset() {
      this.value = this.initialValue;
      this.fire();
      this.render();
    }
    exit() {
      this.abort();
    }
    abort() {
      this.done = this.aborted = true;
      this.fire();
      this.render();
      this.out.write(`
`);
      this.close();
    }
    submit() {
      this.done = true;
      this.aborted = false;
      this.fire();
      this.render();
      this.out.write(`
`);
      this.close();
    }
    deactivate() {
      if (this.value === false)
        return this.bell();
      this.value = false;
      this.render();
    }
    activate() {
      if (this.value === true)
        return this.bell();
      this.value = true;
      this.render();
    }
    delete() {
      this.deactivate();
    }
    left() {
      this.deactivate();
    }
    right() {
      this.activate();
    }
    down() {
      this.deactivate();
    }
    up() {
      this.activate();
    }
    next() {
      this.value = !this.value;
      this.fire();
      this.render();
    }
    _(c, key) {
      if (c === " ") {
        this.value = !this.value;
      } else if (c === "1") {
        this.value = true;
      } else if (c === "0") {
        this.value = false;
      } else
        return this.bell();
      this.render();
    }
    render() {
      if (this.closed)
        return;
      if (this.firstRender)
        this.out.write(cursor.hide);
      else
        this.out.write(clear(this.outputText, this.out.columns));
      super.render();
      this.outputText = [style.symbol(this.done, this.aborted), color.bold(this.msg), style.delimiter(this.done), this.value ? this.inactive : color.cyan().underline(this.inactive), color.gray("/"), this.value ? color.cyan().underline(this.active) : this.active].join(" ");
      this.out.write(erase.line + cursor.to(0) + this.outputText);
    }
  }
  module.exports = TogglePrompt;
});

// node_modules/prompts/dist/dateparts/datepart.js
var require_datepart = __commonJS((exports, module) => {
  class DatePart {
    constructor({
      token,
      date,
      parts,
      locales
    }) {
      this.token = token;
      this.date = date || new Date;
      this.parts = parts || [this];
      this.locales = locales || {};
    }
    up() {}
    down() {}
    next() {
      const currentIdx = this.parts.indexOf(this);
      return this.parts.find((part, idx) => idx > currentIdx && part instanceof DatePart);
    }
    setTo(val) {}
    prev() {
      let parts = [].concat(this.parts).reverse();
      const currentIdx = parts.indexOf(this);
      return parts.find((part, idx) => idx > currentIdx && part instanceof DatePart);
    }
    toString() {
      return String(this.date);
    }
  }
  module.exports = DatePart;
});

// node_modules/prompts/dist/dateparts/meridiem.js
var require_meridiem = __commonJS((exports, module) => {
  var DatePart = require_datepart();

  class Meridiem extends DatePart {
    constructor(opts = {}) {
      super(opts);
    }
    up() {
      this.date.setHours((this.date.getHours() + 12) % 24);
    }
    down() {
      this.up();
    }
    toString() {
      let meridiem = this.date.getHours() > 12 ? "pm" : "am";
      return /\A/.test(this.token) ? meridiem.toUpperCase() : meridiem;
    }
  }
  module.exports = Meridiem;
});

// node_modules/prompts/dist/dateparts/day.js
var require_day = __commonJS((exports, module) => {
  var DatePart = require_datepart();
  var pos = (n) => {
    n = n % 10;
    return n === 1 ? "st" : n === 2 ? "nd" : n === 3 ? "rd" : "th";
  };

  class Day extends DatePart {
    constructor(opts = {}) {
      super(opts);
    }
    up() {
      this.date.setDate(this.date.getDate() + 1);
    }
    down() {
      this.date.setDate(this.date.getDate() - 1);
    }
    setTo(val) {
      this.date.setDate(parseInt(val.substr(-2)));
    }
    toString() {
      let date = this.date.getDate();
      let day = this.date.getDay();
      return this.token === "DD" ? String(date).padStart(2, "0") : this.token === "Do" ? date + pos(date) : this.token === "d" ? day + 1 : this.token === "ddd" ? this.locales.weekdaysShort[day] : this.token === "dddd" ? this.locales.weekdays[day] : date;
    }
  }
  module.exports = Day;
});

// node_modules/prompts/dist/dateparts/hours.js
var require_hours = __commonJS((exports, module) => {
  var DatePart = require_datepart();

  class Hours extends DatePart {
    constructor(opts = {}) {
      super(opts);
    }
    up() {
      this.date.setHours(this.date.getHours() + 1);
    }
    down() {
      this.date.setHours(this.date.getHours() - 1);
    }
    setTo(val) {
      this.date.setHours(parseInt(val.substr(-2)));
    }
    toString() {
      let hours = this.date.getHours();
      if (/h/.test(this.token))
        hours = hours % 12 || 12;
      return this.token.length > 1 ? String(hours).padStart(2, "0") : hours;
    }
  }
  module.exports = Hours;
});

// node_modules/prompts/dist/dateparts/milliseconds.js
var require_milliseconds = __commonJS((exports, module) => {
  var DatePart = require_datepart();

  class Milliseconds extends DatePart {
    constructor(opts = {}) {
      super(opts);
    }
    up() {
      this.date.setMilliseconds(this.date.getMilliseconds() + 1);
    }
    down() {
      this.date.setMilliseconds(this.date.getMilliseconds() - 1);
    }
    setTo(val) {
      this.date.setMilliseconds(parseInt(val.substr(-this.token.length)));
    }
    toString() {
      return String(this.date.getMilliseconds()).padStart(4, "0").substr(0, this.token.length);
    }
  }
  module.exports = Milliseconds;
});

// node_modules/prompts/dist/dateparts/minutes.js
var require_minutes = __commonJS((exports, module) => {
  var DatePart = require_datepart();

  class Minutes extends DatePart {
    constructor(opts = {}) {
      super(opts);
    }
    up() {
      this.date.setMinutes(this.date.getMinutes() + 1);
    }
    down() {
      this.date.setMinutes(this.date.getMinutes() - 1);
    }
    setTo(val) {
      this.date.setMinutes(parseInt(val.substr(-2)));
    }
    toString() {
      let m = this.date.getMinutes();
      return this.token.length > 1 ? String(m).padStart(2, "0") : m;
    }
  }
  module.exports = Minutes;
});

// node_modules/prompts/dist/dateparts/month.js
var require_month = __commonJS((exports, module) => {
  var DatePart = require_datepart();

  class Month extends DatePart {
    constructor(opts = {}) {
      super(opts);
    }
    up() {
      this.date.setMonth(this.date.getMonth() + 1);
    }
    down() {
      this.date.setMonth(this.date.getMonth() - 1);
    }
    setTo(val) {
      val = parseInt(val.substr(-2)) - 1;
      this.date.setMonth(val < 0 ? 0 : val);
    }
    toString() {
      let month = this.date.getMonth();
      let tl = this.token.length;
      return tl === 2 ? String(month + 1).padStart(2, "0") : tl === 3 ? this.locales.monthsShort[month] : tl === 4 ? this.locales.months[month] : String(month + 1);
    }
  }
  module.exports = Month;
});

// node_modules/prompts/dist/dateparts/seconds.js
var require_seconds = __commonJS((exports, module) => {
  var DatePart = require_datepart();

  class Seconds extends DatePart {
    constructor(opts = {}) {
      super(opts);
    }
    up() {
      this.date.setSeconds(this.date.getSeconds() + 1);
    }
    down() {
      this.date.setSeconds(this.date.getSeconds() - 1);
    }
    setTo(val) {
      this.date.setSeconds(parseInt(val.substr(-2)));
    }
    toString() {
      let s = this.date.getSeconds();
      return this.token.length > 1 ? String(s).padStart(2, "0") : s;
    }
  }
  module.exports = Seconds;
});

// node_modules/prompts/dist/dateparts/year.js
var require_year = __commonJS((exports, module) => {
  var DatePart = require_datepart();

  class Year extends DatePart {
    constructor(opts = {}) {
      super(opts);
    }
    up() {
      this.date.setFullYear(this.date.getFullYear() + 1);
    }
    down() {
      this.date.setFullYear(this.date.getFullYear() - 1);
    }
    setTo(val) {
      this.date.setFullYear(val.substr(-4));
    }
    toString() {
      let year = String(this.date.getFullYear()).padStart(4, "0");
      return this.token.length === 2 ? year.substr(-2) : year;
    }
  }
  module.exports = Year;
});

// node_modules/prompts/dist/dateparts/index.js
var require_dateparts = __commonJS((exports, module) => {
  module.exports = {
    DatePart: require_datepart(),
    Meridiem: require_meridiem(),
    Day: require_day(),
    Hours: require_hours(),
    Milliseconds: require_milliseconds(),
    Minutes: require_minutes(),
    Month: require_month(),
    Seconds: require_seconds(),
    Year: require_year()
  };
});

// node_modules/prompts/dist/elements/date.js
var require_date = __commonJS((exports, module) => {
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
    try {
      var info = gen[key](arg);
      var value = info.value;
    } catch (error) {
      reject(error);
      return;
    }
    if (info.done) {
      resolve(value);
    } else {
      Promise.resolve(value).then(_next, _throw);
    }
  }
  function _asyncToGenerator(fn) {
    return function() {
      var self = this, args = arguments;
      return new Promise(function(resolve, reject) {
        var gen = fn.apply(self, args);
        function _next(value) {
          asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
        }
        function _throw(err) {
          asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
        }
        _next(undefined);
      });
    };
  }
  var color = require_kleur();
  var Prompt = require_prompt();
  var _require = require_util();
  var style = _require.style;
  var clear = _require.clear;
  var figures = _require.figures;
  var _require2 = require_src();
  var erase = _require2.erase;
  var cursor = _require2.cursor;
  var _require3 = require_dateparts();
  var DatePart = _require3.DatePart;
  var Meridiem = _require3.Meridiem;
  var Day = _require3.Day;
  var Hours = _require3.Hours;
  var Milliseconds = _require3.Milliseconds;
  var Minutes = _require3.Minutes;
  var Month = _require3.Month;
  var Seconds = _require3.Seconds;
  var Year = _require3.Year;
  var regex = /\\(.)|"((?:\\["\\]|[^"])+)"|(D[Do]?|d{3,4}|d)|(M{1,4})|(YY(?:YY)?)|([aA])|([Hh]{1,2})|(m{1,2})|(s{1,2})|(S{1,4})|./g;
  var regexGroups = {
    1: ({
      token
    }) => token.replace(/\\(.)/g, "$1"),
    2: (opts) => new Day(opts),
    3: (opts) => new Month(opts),
    4: (opts) => new Year(opts),
    5: (opts) => new Meridiem(opts),
    6: (opts) => new Hours(opts),
    7: (opts) => new Minutes(opts),
    8: (opts) => new Seconds(opts),
    9: (opts) => new Milliseconds(opts)
  };
  var dfltLocales = {
    months: "January,February,March,April,May,June,July,August,September,October,November,December".split(","),
    monthsShort: "Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec".split(","),
    weekdays: "Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday".split(","),
    weekdaysShort: "Sun,Mon,Tue,Wed,Thu,Fri,Sat".split(",")
  };

  class DatePrompt extends Prompt {
    constructor(opts = {}) {
      super(opts);
      this.msg = opts.message;
      this.cursor = 0;
      this.typed = "";
      this.locales = Object.assign(dfltLocales, opts.locales);
      this._date = opts.initial || new Date;
      this.errorMsg = opts.error || "Please Enter A Valid Value";
      this.validator = opts.validate || (() => true);
      this.mask = opts.mask || "YYYY-MM-DD HH:mm:ss";
      this.clear = clear("", this.out.columns);
      this.render();
    }
    get value() {
      return this.date;
    }
    get date() {
      return this._date;
    }
    set date(date) {
      if (date)
        this._date.setTime(date.getTime());
    }
    set mask(mask) {
      let result;
      this.parts = [];
      while (result = regex.exec(mask)) {
        let match = result.shift();
        let idx = result.findIndex((gr) => gr != null);
        this.parts.push(idx in regexGroups ? regexGroups[idx]({
          token: result[idx] || match,
          date: this.date,
          parts: this.parts,
          locales: this.locales
        }) : result[idx] || match);
      }
      let parts = this.parts.reduce((arr, i) => {
        if (typeof i === "string" && typeof arr[arr.length - 1] === "string")
          arr[arr.length - 1] += i;
        else
          arr.push(i);
        return arr;
      }, []);
      this.parts.splice(0);
      this.parts.push(...parts);
      this.reset();
    }
    moveCursor(n) {
      this.typed = "";
      this.cursor = n;
      this.fire();
    }
    reset() {
      this.moveCursor(this.parts.findIndex((p) => p instanceof DatePart));
      this.fire();
      this.render();
    }
    exit() {
      this.abort();
    }
    abort() {
      this.done = this.aborted = true;
      this.error = false;
      this.fire();
      this.render();
      this.out.write(`
`);
      this.close();
    }
    validate() {
      var _this = this;
      return _asyncToGenerator(function* () {
        let valid = yield _this.validator(_this.value);
        if (typeof valid === "string") {
          _this.errorMsg = valid;
          valid = false;
        }
        _this.error = !valid;
      })();
    }
    submit() {
      var _this2 = this;
      return _asyncToGenerator(function* () {
        yield _this2.validate();
        if (_this2.error) {
          _this2.color = "red";
          _this2.fire();
          _this2.render();
          return;
        }
        _this2.done = true;
        _this2.aborted = false;
        _this2.fire();
        _this2.render();
        _this2.out.write(`
`);
        _this2.close();
      })();
    }
    up() {
      this.typed = "";
      this.parts[this.cursor].up();
      this.render();
    }
    down() {
      this.typed = "";
      this.parts[this.cursor].down();
      this.render();
    }
    left() {
      let prev = this.parts[this.cursor].prev();
      if (prev == null)
        return this.bell();
      this.moveCursor(this.parts.indexOf(prev));
      this.render();
    }
    right() {
      let next = this.parts[this.cursor].next();
      if (next == null)
        return this.bell();
      this.moveCursor(this.parts.indexOf(next));
      this.render();
    }
    next() {
      let next = this.parts[this.cursor].next();
      this.moveCursor(next ? this.parts.indexOf(next) : this.parts.findIndex((part) => part instanceof DatePart));
      this.render();
    }
    _(c) {
      if (/\d/.test(c)) {
        this.typed += c;
        this.parts[this.cursor].setTo(this.typed);
        this.render();
      }
    }
    render() {
      if (this.closed)
        return;
      if (this.firstRender)
        this.out.write(cursor.hide);
      else
        this.out.write(clear(this.outputText, this.out.columns));
      super.render();
      this.outputText = [style.symbol(this.done, this.aborted), color.bold(this.msg), style.delimiter(false), this.parts.reduce((arr, p, idx) => arr.concat(idx === this.cursor && !this.done ? color.cyan().underline(p.toString()) : p), []).join("")].join(" ");
      if (this.error) {
        this.outputText += this.errorMsg.split(`
`).reduce((a, l, i) => a + `
${i ? ` ` : figures.pointerSmall} ${color.red().italic(l)}`, ``);
      }
      this.out.write(erase.line + cursor.to(0) + this.outputText);
    }
  }
  module.exports = DatePrompt;
});

// node_modules/prompts/dist/elements/number.js
var require_number = __commonJS((exports, module) => {
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
    try {
      var info = gen[key](arg);
      var value = info.value;
    } catch (error) {
      reject(error);
      return;
    }
    if (info.done) {
      resolve(value);
    } else {
      Promise.resolve(value).then(_next, _throw);
    }
  }
  function _asyncToGenerator(fn) {
    return function() {
      var self = this, args = arguments;
      return new Promise(function(resolve, reject) {
        var gen = fn.apply(self, args);
        function _next(value) {
          asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
        }
        function _throw(err) {
          asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
        }
        _next(undefined);
      });
    };
  }
  var color = require_kleur();
  var Prompt = require_prompt();
  var _require = require_src();
  var cursor = _require.cursor;
  var erase = _require.erase;
  var _require2 = require_util();
  var style = _require2.style;
  var figures = _require2.figures;
  var clear = _require2.clear;
  var lines = _require2.lines;
  var isNumber = /[0-9]/;
  var isDef = (any) => any !== undefined;
  var round = (number, precision) => {
    let factor = Math.pow(10, precision);
    return Math.round(number * factor) / factor;
  };

  class NumberPrompt extends Prompt {
    constructor(opts = {}) {
      super(opts);
      this.transform = style.render(opts.style);
      this.msg = opts.message;
      this.initial = isDef(opts.initial) ? opts.initial : "";
      this.float = !!opts.float;
      this.round = opts.round || 2;
      this.inc = opts.increment || 1;
      this.min = isDef(opts.min) ? opts.min : -Infinity;
      this.max = isDef(opts.max) ? opts.max : Infinity;
      this.errorMsg = opts.error || `Please Enter A Valid Value`;
      this.validator = opts.validate || (() => true);
      this.color = `cyan`;
      this.value = ``;
      this.typed = ``;
      this.lastHit = 0;
      this.render();
    }
    set value(v) {
      if (!v && v !== 0) {
        this.placeholder = true;
        this.rendered = color.gray(this.transform.render(`${this.initial}`));
        this._value = ``;
      } else {
        this.placeholder = false;
        this.rendered = this.transform.render(`${round(v, this.round)}`);
        this._value = round(v, this.round);
      }
      this.fire();
    }
    get value() {
      return this._value;
    }
    parse(x) {
      return this.float ? parseFloat(x) : parseInt(x);
    }
    valid(c) {
      return c === `-` || c === `.` && this.float || isNumber.test(c);
    }
    reset() {
      this.typed = ``;
      this.value = ``;
      this.fire();
      this.render();
    }
    exit() {
      this.abort();
    }
    abort() {
      let x = this.value;
      this.value = x !== `` ? x : this.initial;
      this.done = this.aborted = true;
      this.error = false;
      this.fire();
      this.render();
      this.out.write(`
`);
      this.close();
    }
    validate() {
      var _this = this;
      return _asyncToGenerator(function* () {
        let valid = yield _this.validator(_this.value);
        if (typeof valid === `string`) {
          _this.errorMsg = valid;
          valid = false;
        }
        _this.error = !valid;
      })();
    }
    submit() {
      var _this2 = this;
      return _asyncToGenerator(function* () {
        yield _this2.validate();
        if (_this2.error) {
          _this2.color = `red`;
          _this2.fire();
          _this2.render();
          return;
        }
        let x = _this2.value;
        _this2.value = x !== `` ? x : _this2.initial;
        _this2.done = true;
        _this2.aborted = false;
        _this2.error = false;
        _this2.fire();
        _this2.render();
        _this2.out.write(`
`);
        _this2.close();
      })();
    }
    up() {
      this.typed = ``;
      if (this.value === "") {
        this.value = this.min - this.inc;
      }
      if (this.value >= this.max)
        return this.bell();
      this.value += this.inc;
      this.color = `cyan`;
      this.fire();
      this.render();
    }
    down() {
      this.typed = ``;
      if (this.value === "") {
        this.value = this.min + this.inc;
      }
      if (this.value <= this.min)
        return this.bell();
      this.value -= this.inc;
      this.color = `cyan`;
      this.fire();
      this.render();
    }
    delete() {
      let val = this.value.toString();
      if (val.length === 0)
        return this.bell();
      this.value = this.parse(val = val.slice(0, -1)) || ``;
      if (this.value !== "" && this.value < this.min) {
        this.value = this.min;
      }
      this.color = `cyan`;
      this.fire();
      this.render();
    }
    next() {
      this.value = this.initial;
      this.fire();
      this.render();
    }
    _(c, key) {
      if (!this.valid(c))
        return this.bell();
      const now = Date.now();
      if (now - this.lastHit > 1000)
        this.typed = ``;
      this.typed += c;
      this.lastHit = now;
      this.color = `cyan`;
      if (c === `.`)
        return this.fire();
      this.value = Math.min(this.parse(this.typed), this.max);
      if (this.value > this.max)
        this.value = this.max;
      if (this.value < this.min)
        this.value = this.min;
      this.fire();
      this.render();
    }
    render() {
      if (this.closed)
        return;
      if (!this.firstRender) {
        if (this.outputError)
          this.out.write(cursor.down(lines(this.outputError, this.out.columns) - 1) + clear(this.outputError, this.out.columns));
        this.out.write(clear(this.outputText, this.out.columns));
      }
      super.render();
      this.outputError = "";
      this.outputText = [style.symbol(this.done, this.aborted), color.bold(this.msg), style.delimiter(this.done), !this.done || !this.done && !this.placeholder ? color[this.color]().underline(this.rendered) : this.rendered].join(` `);
      if (this.error) {
        this.outputError += this.errorMsg.split(`
`).reduce((a, l, i) => a + `
${i ? ` ` : figures.pointerSmall} ${color.red().italic(l)}`, ``);
      }
      this.out.write(erase.line + cursor.to(0) + this.outputText + cursor.save + this.outputError + cursor.restore);
    }
  }
  module.exports = NumberPrompt;
});

// node_modules/prompts/dist/elements/multiselect.js
var require_multiselect = __commonJS((exports, module) => {
  var color = require_kleur();
  var _require = require_src();
  var cursor = _require.cursor;
  var Prompt = require_prompt();
  var _require2 = require_util();
  var clear = _require2.clear;
  var figures = _require2.figures;
  var style = _require2.style;
  var wrap = _require2.wrap;
  var entriesToDisplay = _require2.entriesToDisplay;

  class MultiselectPrompt extends Prompt {
    constructor(opts = {}) {
      super(opts);
      this.msg = opts.message;
      this.cursor = opts.cursor || 0;
      this.scrollIndex = opts.cursor || 0;
      this.hint = opts.hint || "";
      this.warn = opts.warn || "- This option is disabled -";
      this.minSelected = opts.min;
      this.showMinError = false;
      this.maxChoices = opts.max;
      this.instructions = opts.instructions;
      this.optionsPerPage = opts.optionsPerPage || 10;
      this.value = opts.choices.map((ch, idx) => {
        if (typeof ch === "string")
          ch = {
            title: ch,
            value: idx
          };
        return {
          title: ch && (ch.title || ch.value || ch),
          description: ch && ch.description,
          value: ch && (ch.value === undefined ? idx : ch.value),
          selected: ch && ch.selected,
          disabled: ch && ch.disabled
        };
      });
      this.clear = clear("", this.out.columns);
      if (!opts.overrideRender) {
        this.render();
      }
    }
    reset() {
      this.value.map((v) => !v.selected);
      this.cursor = 0;
      this.fire();
      this.render();
    }
    selected() {
      return this.value.filter((v) => v.selected);
    }
    exit() {
      this.abort();
    }
    abort() {
      this.done = this.aborted = true;
      this.fire();
      this.render();
      this.out.write(`
`);
      this.close();
    }
    submit() {
      const selected = this.value.filter((e) => e.selected);
      if (this.minSelected && selected.length < this.minSelected) {
        this.showMinError = true;
        this.render();
      } else {
        this.done = true;
        this.aborted = false;
        this.fire();
        this.render();
        this.out.write(`
`);
        this.close();
      }
    }
    first() {
      this.cursor = 0;
      this.render();
    }
    last() {
      this.cursor = this.value.length - 1;
      this.render();
    }
    next() {
      this.cursor = (this.cursor + 1) % this.value.length;
      this.render();
    }
    up() {
      if (this.cursor === 0) {
        this.cursor = this.value.length - 1;
      } else {
        this.cursor--;
      }
      this.render();
    }
    down() {
      if (this.cursor === this.value.length - 1) {
        this.cursor = 0;
      } else {
        this.cursor++;
      }
      this.render();
    }
    left() {
      this.value[this.cursor].selected = false;
      this.render();
    }
    right() {
      if (this.value.filter((e) => e.selected).length >= this.maxChoices)
        return this.bell();
      this.value[this.cursor].selected = true;
      this.render();
    }
    handleSpaceToggle() {
      const v = this.value[this.cursor];
      if (v.selected) {
        v.selected = false;
        this.render();
      } else if (v.disabled || this.value.filter((e) => e.selected).length >= this.maxChoices) {
        return this.bell();
      } else {
        v.selected = true;
        this.render();
      }
    }
    toggleAll() {
      if (this.maxChoices !== undefined || this.value[this.cursor].disabled) {
        return this.bell();
      }
      const newSelected = !this.value[this.cursor].selected;
      this.value.filter((v) => !v.disabled).forEach((v) => v.selected = newSelected);
      this.render();
    }
    _(c, key) {
      if (c === " ") {
        this.handleSpaceToggle();
      } else if (c === "a") {
        this.toggleAll();
      } else {
        return this.bell();
      }
    }
    renderInstructions() {
      if (this.instructions === undefined || this.instructions) {
        if (typeof this.instructions === "string") {
          return this.instructions;
        }
        return `
Instructions:
` + `    ${figures.arrowUp}/${figures.arrowDown}: Highlight option
` + `    ${figures.arrowLeft}/${figures.arrowRight}/[space]: Toggle selection
` + (this.maxChoices === undefined ? `    a: Toggle all
` : "") + `    enter/return: Complete answer`;
      }
      return "";
    }
    renderOption(cursor2, v, i, arrowIndicator) {
      const prefix = (v.selected ? color.green(figures.radioOn) : figures.radioOff) + " " + arrowIndicator + " ";
      let title, desc;
      if (v.disabled) {
        title = cursor2 === i ? color.gray().underline(v.title) : color.strikethrough().gray(v.title);
      } else {
        title = cursor2 === i ? color.cyan().underline(v.title) : v.title;
        if (cursor2 === i && v.description) {
          desc = ` - ${v.description}`;
          if (prefix.length + title.length + desc.length >= this.out.columns || v.description.split(/\r?\n/).length > 1) {
            desc = `
` + wrap(v.description, {
              margin: prefix.length,
              width: this.out.columns
            });
          }
        }
      }
      return prefix + title + color.gray(desc || "");
    }
    paginateOptions(options) {
      if (options.length === 0) {
        return color.red("No matches for this query.");
      }
      let _entriesToDisplay = entriesToDisplay(this.cursor, options.length, this.optionsPerPage), startIndex = _entriesToDisplay.startIndex, endIndex = _entriesToDisplay.endIndex;
      let prefix, styledOptions = [];
      for (let i = startIndex;i < endIndex; i++) {
        if (i === startIndex && startIndex > 0) {
          prefix = figures.arrowUp;
        } else if (i === endIndex - 1 && endIndex < options.length) {
          prefix = figures.arrowDown;
        } else {
          prefix = " ";
        }
        styledOptions.push(this.renderOption(this.cursor, options[i], i, prefix));
      }
      return `
` + styledOptions.join(`
`);
    }
    renderOptions(options) {
      if (!this.done) {
        return this.paginateOptions(options);
      }
      return "";
    }
    renderDoneOrInstructions() {
      if (this.done) {
        return this.value.filter((e) => e.selected).map((v) => v.title).join(", ");
      }
      const output = [color.gray(this.hint), this.renderInstructions()];
      if (this.value[this.cursor].disabled) {
        output.push(color.yellow(this.warn));
      }
      return output.join(" ");
    }
    render() {
      if (this.closed)
        return;
      if (this.firstRender)
        this.out.write(cursor.hide);
      super.render();
      let prompt = [style.symbol(this.done, this.aborted), color.bold(this.msg), style.delimiter(false), this.renderDoneOrInstructions()].join(" ");
      if (this.showMinError) {
        prompt += color.red(`You must select a minimum of ${this.minSelected} choices.`);
        this.showMinError = false;
      }
      prompt += this.renderOptions(this.value);
      this.out.write(this.clear + prompt);
      this.clear = clear(prompt, this.out.columns);
    }
  }
  module.exports = MultiselectPrompt;
});

// node_modules/prompts/dist/elements/autocomplete.js
var require_autocomplete = __commonJS((exports, module) => {
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
    try {
      var info = gen[key](arg);
      var value = info.value;
    } catch (error) {
      reject(error);
      return;
    }
    if (info.done) {
      resolve(value);
    } else {
      Promise.resolve(value).then(_next, _throw);
    }
  }
  function _asyncToGenerator(fn) {
    return function() {
      var self = this, args = arguments;
      return new Promise(function(resolve, reject) {
        var gen = fn.apply(self, args);
        function _next(value) {
          asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
        }
        function _throw(err) {
          asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
        }
        _next(undefined);
      });
    };
  }
  var color = require_kleur();
  var Prompt = require_prompt();
  var _require = require_src();
  var erase = _require.erase;
  var cursor = _require.cursor;
  var _require2 = require_util();
  var style = _require2.style;
  var clear = _require2.clear;
  var figures = _require2.figures;
  var wrap = _require2.wrap;
  var entriesToDisplay = _require2.entriesToDisplay;
  var getVal = (arr, i) => arr[i] && (arr[i].value || arr[i].title || arr[i]);
  var getTitle = (arr, i) => arr[i] && (arr[i].title || arr[i].value || arr[i]);
  var getIndex = (arr, valOrTitle) => {
    const index = arr.findIndex((el) => el.value === valOrTitle || el.title === valOrTitle);
    return index > -1 ? index : undefined;
  };

  class AutocompletePrompt extends Prompt {
    constructor(opts = {}) {
      super(opts);
      this.msg = opts.message;
      this.suggest = opts.suggest;
      this.choices = opts.choices;
      this.initial = typeof opts.initial === "number" ? opts.initial : getIndex(opts.choices, opts.initial);
      this.select = this.initial || opts.cursor || 0;
      this.i18n = {
        noMatches: opts.noMatches || "no matches found"
      };
      this.fallback = opts.fallback || this.initial;
      this.clearFirst = opts.clearFirst || false;
      this.suggestions = [];
      this.input = "";
      this.limit = opts.limit || 10;
      this.cursor = 0;
      this.transform = style.render(opts.style);
      this.scale = this.transform.scale;
      this.render = this.render.bind(this);
      this.complete = this.complete.bind(this);
      this.clear = clear("", this.out.columns);
      this.complete(this.render);
      this.render();
    }
    set fallback(fb) {
      this._fb = Number.isSafeInteger(parseInt(fb)) ? parseInt(fb) : fb;
    }
    get fallback() {
      let choice;
      if (typeof this._fb === "number")
        choice = this.choices[this._fb];
      else if (typeof this._fb === "string")
        choice = {
          title: this._fb
        };
      return choice || this._fb || {
        title: this.i18n.noMatches
      };
    }
    moveSelect(i) {
      this.select = i;
      if (this.suggestions.length > 0)
        this.value = getVal(this.suggestions, i);
      else
        this.value = this.fallback.value;
      this.fire();
    }
    complete(cb) {
      var _this = this;
      return _asyncToGenerator(function* () {
        const p = _this.completing = _this.suggest(_this.input, _this.choices);
        const suggestions = yield p;
        if (_this.completing !== p)
          return;
        _this.suggestions = suggestions.map((s, i, arr) => ({
          title: getTitle(arr, i),
          value: getVal(arr, i),
          description: s.description
        }));
        _this.completing = false;
        const l = Math.max(suggestions.length - 1, 0);
        _this.moveSelect(Math.min(l, _this.select));
        cb && cb();
      })();
    }
    reset() {
      this.input = "";
      this.complete(() => {
        this.moveSelect(this.initial !== undefined ? this.initial : 0);
        this.render();
      });
      this.render();
    }
    exit() {
      if (this.clearFirst && this.input.length > 0) {
        this.reset();
      } else {
        this.done = this.exited = true;
        this.aborted = false;
        this.fire();
        this.render();
        this.out.write(`
`);
        this.close();
      }
    }
    abort() {
      this.done = this.aborted = true;
      this.exited = false;
      this.fire();
      this.render();
      this.out.write(`
`);
      this.close();
    }
    submit() {
      this.done = true;
      this.aborted = this.exited = false;
      this.fire();
      this.render();
      this.out.write(`
`);
      this.close();
    }
    _(c, key) {
      let s1 = this.input.slice(0, this.cursor);
      let s2 = this.input.slice(this.cursor);
      this.input = `${s1}${c}${s2}`;
      this.cursor = s1.length + 1;
      this.complete(this.render);
      this.render();
    }
    delete() {
      if (this.cursor === 0)
        return this.bell();
      let s1 = this.input.slice(0, this.cursor - 1);
      let s2 = this.input.slice(this.cursor);
      this.input = `${s1}${s2}`;
      this.complete(this.render);
      this.cursor = this.cursor - 1;
      this.render();
    }
    deleteForward() {
      if (this.cursor * this.scale >= this.rendered.length)
        return this.bell();
      let s1 = this.input.slice(0, this.cursor);
      let s2 = this.input.slice(this.cursor + 1);
      this.input = `${s1}${s2}`;
      this.complete(this.render);
      this.render();
    }
    first() {
      this.moveSelect(0);
      this.render();
    }
    last() {
      this.moveSelect(this.suggestions.length - 1);
      this.render();
    }
    up() {
      if (this.select === 0) {
        this.moveSelect(this.suggestions.length - 1);
      } else {
        this.moveSelect(this.select - 1);
      }
      this.render();
    }
    down() {
      if (this.select === this.suggestions.length - 1) {
        this.moveSelect(0);
      } else {
        this.moveSelect(this.select + 1);
      }
      this.render();
    }
    next() {
      if (this.select === this.suggestions.length - 1) {
        this.moveSelect(0);
      } else
        this.moveSelect(this.select + 1);
      this.render();
    }
    nextPage() {
      this.moveSelect(Math.min(this.select + this.limit, this.suggestions.length - 1));
      this.render();
    }
    prevPage() {
      this.moveSelect(Math.max(this.select - this.limit, 0));
      this.render();
    }
    left() {
      if (this.cursor <= 0)
        return this.bell();
      this.cursor = this.cursor - 1;
      this.render();
    }
    right() {
      if (this.cursor * this.scale >= this.rendered.length)
        return this.bell();
      this.cursor = this.cursor + 1;
      this.render();
    }
    renderOption(v, hovered, isStart, isEnd) {
      let desc;
      let prefix = isStart ? figures.arrowUp : isEnd ? figures.arrowDown : " ";
      let title = hovered ? color.cyan().underline(v.title) : v.title;
      prefix = (hovered ? color.cyan(figures.pointer) + " " : "  ") + prefix;
      if (v.description) {
        desc = ` - ${v.description}`;
        if (prefix.length + title.length + desc.length >= this.out.columns || v.description.split(/\r?\n/).length > 1) {
          desc = `
` + wrap(v.description, {
            margin: 3,
            width: this.out.columns
          });
        }
      }
      return prefix + " " + title + color.gray(desc || "");
    }
    render() {
      if (this.closed)
        return;
      if (this.firstRender)
        this.out.write(cursor.hide);
      else
        this.out.write(clear(this.outputText, this.out.columns));
      super.render();
      let _entriesToDisplay = entriesToDisplay(this.select, this.choices.length, this.limit), startIndex = _entriesToDisplay.startIndex, endIndex = _entriesToDisplay.endIndex;
      this.outputText = [style.symbol(this.done, this.aborted, this.exited), color.bold(this.msg), style.delimiter(this.completing), this.done && this.suggestions[this.select] ? this.suggestions[this.select].title : this.rendered = this.transform.render(this.input)].join(" ");
      if (!this.done) {
        const suggestions = this.suggestions.slice(startIndex, endIndex).map((item, i) => this.renderOption(item, this.select === i + startIndex, i === 0 && startIndex > 0, i + startIndex === endIndex - 1 && endIndex < this.choices.length)).join(`
`);
        this.outputText += `
` + (suggestions || color.gray(this.fallback.title));
      }
      this.out.write(erase.line + cursor.to(0) + this.outputText);
    }
  }
  module.exports = AutocompletePrompt;
});

// node_modules/prompts/dist/elements/autocompleteMultiselect.js
var require_autocompleteMultiselect = __commonJS((exports, module) => {
  var color = require_kleur();
  var _require = require_src();
  var cursor = _require.cursor;
  var MultiselectPrompt = require_multiselect();
  var _require2 = require_util();
  var clear = _require2.clear;
  var style = _require2.style;
  var figures = _require2.figures;

  class AutocompleteMultiselectPrompt extends MultiselectPrompt {
    constructor(opts = {}) {
      opts.overrideRender = true;
      super(opts);
      this.inputValue = "";
      this.clear = clear("", this.out.columns);
      this.filteredOptions = this.value;
      this.render();
    }
    last() {
      this.cursor = this.filteredOptions.length - 1;
      this.render();
    }
    next() {
      this.cursor = (this.cursor + 1) % this.filteredOptions.length;
      this.render();
    }
    up() {
      if (this.cursor === 0) {
        this.cursor = this.filteredOptions.length - 1;
      } else {
        this.cursor--;
      }
      this.render();
    }
    down() {
      if (this.cursor === this.filteredOptions.length - 1) {
        this.cursor = 0;
      } else {
        this.cursor++;
      }
      this.render();
    }
    left() {
      this.filteredOptions[this.cursor].selected = false;
      this.render();
    }
    right() {
      if (this.value.filter((e) => e.selected).length >= this.maxChoices)
        return this.bell();
      this.filteredOptions[this.cursor].selected = true;
      this.render();
    }
    delete() {
      if (this.inputValue.length) {
        this.inputValue = this.inputValue.substr(0, this.inputValue.length - 1);
        this.updateFilteredOptions();
      }
    }
    updateFilteredOptions() {
      const currentHighlight = this.filteredOptions[this.cursor];
      this.filteredOptions = this.value.filter((v) => {
        if (this.inputValue) {
          if (typeof v.title === "string") {
            if (v.title.toLowerCase().includes(this.inputValue.toLowerCase())) {
              return true;
            }
          }
          if (typeof v.value === "string") {
            if (v.value.toLowerCase().includes(this.inputValue.toLowerCase())) {
              return true;
            }
          }
          return false;
        }
        return true;
      });
      const newHighlightIndex = this.filteredOptions.findIndex((v) => v === currentHighlight);
      this.cursor = newHighlightIndex < 0 ? 0 : newHighlightIndex;
      this.render();
    }
    handleSpaceToggle() {
      const v = this.filteredOptions[this.cursor];
      if (v.selected) {
        v.selected = false;
        this.render();
      } else if (v.disabled || this.value.filter((e) => e.selected).length >= this.maxChoices) {
        return this.bell();
      } else {
        v.selected = true;
        this.render();
      }
    }
    handleInputChange(c) {
      this.inputValue = this.inputValue + c;
      this.updateFilteredOptions();
    }
    _(c, key) {
      if (c === " ") {
        this.handleSpaceToggle();
      } else {
        this.handleInputChange(c);
      }
    }
    renderInstructions() {
      if (this.instructions === undefined || this.instructions) {
        if (typeof this.instructions === "string") {
          return this.instructions;
        }
        return `
Instructions:
    ${figures.arrowUp}/${figures.arrowDown}: Highlight option
    ${figures.arrowLeft}/${figures.arrowRight}/[space]: Toggle selection
    [a,b,c]/delete: Filter choices
    enter/return: Complete answer
`;
      }
      return "";
    }
    renderCurrentInput() {
      return `
Filtered results for: ${this.inputValue ? this.inputValue : color.gray("Enter something to filter")}
`;
    }
    renderOption(cursor2, v, i) {
      let title;
      if (v.disabled)
        title = cursor2 === i ? color.gray().underline(v.title) : color.strikethrough().gray(v.title);
      else
        title = cursor2 === i ? color.cyan().underline(v.title) : v.title;
      return (v.selected ? color.green(figures.radioOn) : figures.radioOff) + "  " + title;
    }
    renderDoneOrInstructions() {
      if (this.done) {
        return this.value.filter((e) => e.selected).map((v) => v.title).join(", ");
      }
      const output = [color.gray(this.hint), this.renderInstructions(), this.renderCurrentInput()];
      if (this.filteredOptions.length && this.filteredOptions[this.cursor].disabled) {
        output.push(color.yellow(this.warn));
      }
      return output.join(" ");
    }
    render() {
      if (this.closed)
        return;
      if (this.firstRender)
        this.out.write(cursor.hide);
      super.render();
      let prompt = [style.symbol(this.done, this.aborted), color.bold(this.msg), style.delimiter(false), this.renderDoneOrInstructions()].join(" ");
      if (this.showMinError) {
        prompt += color.red(`You must select a minimum of ${this.minSelected} choices.`);
        this.showMinError = false;
      }
      prompt += this.renderOptions(this.filteredOptions);
      this.out.write(this.clear + prompt);
      this.clear = clear(prompt, this.out.columns);
    }
  }
  module.exports = AutocompleteMultiselectPrompt;
});

// node_modules/prompts/dist/elements/confirm.js
var require_confirm = __commonJS((exports, module) => {
  var color = require_kleur();
  var Prompt = require_prompt();
  var _require = require_util();
  var style = _require.style;
  var clear = _require.clear;
  var _require2 = require_src();
  var erase = _require2.erase;
  var cursor = _require2.cursor;

  class ConfirmPrompt extends Prompt {
    constructor(opts = {}) {
      super(opts);
      this.msg = opts.message;
      this.value = opts.initial;
      this.initialValue = !!opts.initial;
      this.yesMsg = opts.yes || "yes";
      this.yesOption = opts.yesOption || "(Y/n)";
      this.noMsg = opts.no || "no";
      this.noOption = opts.noOption || "(y/N)";
      this.render();
    }
    reset() {
      this.value = this.initialValue;
      this.fire();
      this.render();
    }
    exit() {
      this.abort();
    }
    abort() {
      this.done = this.aborted = true;
      this.fire();
      this.render();
      this.out.write(`
`);
      this.close();
    }
    submit() {
      this.value = this.value || false;
      this.done = true;
      this.aborted = false;
      this.fire();
      this.render();
      this.out.write(`
`);
      this.close();
    }
    _(c, key) {
      if (c.toLowerCase() === "y") {
        this.value = true;
        return this.submit();
      }
      if (c.toLowerCase() === "n") {
        this.value = false;
        return this.submit();
      }
      return this.bell();
    }
    render() {
      if (this.closed)
        return;
      if (this.firstRender)
        this.out.write(cursor.hide);
      else
        this.out.write(clear(this.outputText, this.out.columns));
      super.render();
      this.outputText = [style.symbol(this.done, this.aborted), color.bold(this.msg), style.delimiter(this.done), this.done ? this.value ? this.yesMsg : this.noMsg : color.gray(this.initialValue ? this.yesOption : this.noOption)].join(" ");
      this.out.write(erase.line + cursor.to(0) + this.outputText);
    }
  }
  module.exports = ConfirmPrompt;
});

// node_modules/prompts/dist/elements/index.js
var require_elements = __commonJS((exports, module) => {
  module.exports = {
    TextPrompt: require_text(),
    SelectPrompt: require_select(),
    TogglePrompt: require_toggle(),
    DatePrompt: require_date(),
    NumberPrompt: require_number(),
    MultiselectPrompt: require_multiselect(),
    AutocompletePrompt: require_autocomplete(),
    AutocompleteMultiselectPrompt: require_autocompleteMultiselect(),
    ConfirmPrompt: require_confirm()
  };
});

// node_modules/prompts/dist/prompts.js
var require_prompts = __commonJS((exports) => {
  var $ = exports;
  var el = require_elements();
  var noop = (v) => v;
  function toPrompt(type, args, opts = {}) {
    return new Promise((res, rej) => {
      const p = new el[type](args);
      const onAbort = opts.onAbort || noop;
      const onSubmit = opts.onSubmit || noop;
      const onExit = opts.onExit || noop;
      p.on("state", args.onState || noop);
      p.on("submit", (x) => res(onSubmit(x)));
      p.on("exit", (x) => res(onExit(x)));
      p.on("abort", (x) => rej(onAbort(x)));
    });
  }
  $.text = (args) => toPrompt("TextPrompt", args);
  $.password = (args) => {
    args.style = "password";
    return $.text(args);
  };
  $.invisible = (args) => {
    args.style = "invisible";
    return $.text(args);
  };
  $.number = (args) => toPrompt("NumberPrompt", args);
  $.date = (args) => toPrompt("DatePrompt", args);
  $.confirm = (args) => toPrompt("ConfirmPrompt", args);
  $.list = (args) => {
    const sep = args.separator || ",";
    return toPrompt("TextPrompt", args, {
      onSubmit: (str) => str.split(sep).map((s) => s.trim())
    });
  };
  $.toggle = (args) => toPrompt("TogglePrompt", args);
  $.select = (args) => toPrompt("SelectPrompt", args);
  $.multiselect = (args) => {
    args.choices = [].concat(args.choices || []);
    const toSelected = (items) => items.filter((item) => item.selected).map((item) => item.value);
    return toPrompt("MultiselectPrompt", args, {
      onAbort: toSelected,
      onSubmit: toSelected
    });
  };
  $.autocompleteMultiselect = (args) => {
    args.choices = [].concat(args.choices || []);
    const toSelected = (items) => items.filter((item) => item.selected).map((item) => item.value);
    return toPrompt("AutocompleteMultiselectPrompt", args, {
      onAbort: toSelected,
      onSubmit: toSelected
    });
  };
  var byTitle = (input, choices) => Promise.resolve(choices.filter((item) => item.title.slice(0, input.length).toLowerCase() === input.toLowerCase()));
  $.autocomplete = (args) => {
    args.suggest = args.suggest || byTitle;
    args.choices = [].concat(args.choices || []);
    return toPrompt("AutocompletePrompt", args);
  };
});

// node_modules/prompts/dist/index.js
var require_dist = __commonJS((exports, module) => {
  function ownKeys(object, enumerableOnly) {
    var keys = Object.keys(object);
    if (Object.getOwnPropertySymbols) {
      var symbols = Object.getOwnPropertySymbols(object);
      if (enumerableOnly) {
        symbols = symbols.filter(function(sym) {
          return Object.getOwnPropertyDescriptor(object, sym).enumerable;
        });
      }
      keys.push.apply(keys, symbols);
    }
    return keys;
  }
  function _objectSpread(target) {
    for (var i = 1;i < arguments.length; i++) {
      var source = arguments[i] != null ? arguments[i] : {};
      if (i % 2) {
        ownKeys(Object(source), true).forEach(function(key) {
          _defineProperty(target, key, source[key]);
        });
      } else if (Object.getOwnPropertyDescriptors) {
        Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
      } else {
        ownKeys(Object(source)).forEach(function(key) {
          Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
        });
      }
    }
    return target;
  }
  function _defineProperty(obj, key, value) {
    if (key in obj) {
      Object.defineProperty(obj, key, { value, enumerable: true, configurable: true, writable: true });
    } else {
      obj[key] = value;
    }
    return obj;
  }
  function _createForOfIteratorHelper(o, allowArrayLike) {
    var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
    if (!it) {
      if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
        if (it)
          o = it;
        var i = 0;
        var F = function F() {};
        return { s: F, n: function n() {
          if (i >= o.length)
            return { done: true };
          return { done: false, value: o[i++] };
        }, e: function e(_e) {
          throw _e;
        }, f: F };
      }
      throw new TypeError(`Invalid attempt to iterate non-iterable instance.
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`);
    }
    var normalCompletion = true, didErr = false, err;
    return { s: function s() {
      it = it.call(o);
    }, n: function n() {
      var step = it.next();
      normalCompletion = step.done;
      return step;
    }, e: function e(_e2) {
      didErr = true;
      err = _e2;
    }, f: function f() {
      try {
        if (!normalCompletion && it.return != null)
          it.return();
      } finally {
        if (didErr)
          throw err;
      }
    } };
  }
  function _unsupportedIterableToArray(o, minLen) {
    if (!o)
      return;
    if (typeof o === "string")
      return _arrayLikeToArray(o, minLen);
    var n = Object.prototype.toString.call(o).slice(8, -1);
    if (n === "Object" && o.constructor)
      n = o.constructor.name;
    if (n === "Map" || n === "Set")
      return Array.from(o);
    if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))
      return _arrayLikeToArray(o, minLen);
  }
  function _arrayLikeToArray(arr, len) {
    if (len == null || len > arr.length)
      len = arr.length;
    for (var i = 0, arr2 = new Array(len);i < len; i++)
      arr2[i] = arr[i];
    return arr2;
  }
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
    try {
      var info = gen[key](arg);
      var value = info.value;
    } catch (error) {
      reject(error);
      return;
    }
    if (info.done) {
      resolve(value);
    } else {
      Promise.resolve(value).then(_next, _throw);
    }
  }
  function _asyncToGenerator(fn) {
    return function() {
      var self = this, args = arguments;
      return new Promise(function(resolve, reject) {
        var gen = fn.apply(self, args);
        function _next(value) {
          asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
        }
        function _throw(err) {
          asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
        }
        _next(undefined);
      });
    };
  }
  var prompts = require_prompts();
  var passOn = ["suggest", "format", "onState", "validate", "onRender", "type"];
  var noop = () => {};
  function prompt() {
    return _prompt.apply(this, arguments);
  }
  function _prompt() {
    _prompt = _asyncToGenerator(function* (questions = [], {
      onSubmit = noop,
      onCancel = noop
    } = {}) {
      const answers = {};
      const override2 = prompt._override || {};
      questions = [].concat(questions);
      let answer, question, quit, name, type, lastPrompt;
      const getFormattedAnswer = /* @__PURE__ */ function() {
        var _ref = _asyncToGenerator(function* (question2, answer2, skipValidation = false) {
          if (!skipValidation && question2.validate && question2.validate(answer2) !== true) {
            return;
          }
          return question2.format ? yield question2.format(answer2, answers) : answer2;
        });
        return function getFormattedAnswer(_x, _x2) {
          return _ref.apply(this, arguments);
        };
      }();
      var _iterator = _createForOfIteratorHelper(questions), _step;
      try {
        for (_iterator.s();!(_step = _iterator.n()).done; ) {
          question = _step.value;
          var _question = question;
          name = _question.name;
          type = _question.type;
          if (typeof type === "function") {
            type = yield type(answer, _objectSpread({}, answers), question);
            question["type"] = type;
          }
          if (!type)
            continue;
          for (let key in question) {
            if (passOn.includes(key))
              continue;
            let value = question[key];
            question[key] = typeof value === "function" ? yield value(answer, _objectSpread({}, answers), lastPrompt) : value;
          }
          lastPrompt = question;
          if (typeof question.message !== "string") {
            throw new Error("prompt message is required");
          }
          var _question2 = question;
          name = _question2.name;
          type = _question2.type;
          if (prompts[type] === undefined) {
            throw new Error(`prompt type (${type}) is not defined`);
          }
          if (override2[question.name] !== undefined) {
            answer = yield getFormattedAnswer(question, override2[question.name]);
            if (answer !== undefined) {
              answers[name] = answer;
              continue;
            }
          }
          try {
            answer = prompt._injected ? getInjectedAnswer(prompt._injected, question.initial) : yield prompts[type](question);
            answers[name] = answer = yield getFormattedAnswer(question, answer, true);
            quit = yield onSubmit(question, answer, answers);
          } catch (err) {
            quit = !(yield onCancel(question, answers));
          }
          if (quit)
            return answers;
        }
      } catch (err) {
        _iterator.e(err);
      } finally {
        _iterator.f();
      }
      return answers;
    });
    return _prompt.apply(this, arguments);
  }
  function getInjectedAnswer(injected, deafultValue) {
    const answer = injected.shift();
    if (answer instanceof Error) {
      throw answer;
    }
    return answer === undefined ? deafultValue : answer;
  }
  function inject(answers) {
    prompt._injected = (prompt._injected || []).concat(answers);
  }
  function override(answers) {
    prompt._override = Object.assign({}, answers);
  }
  module.exports = Object.assign(prompt, {
    prompt,
    prompts,
    inject,
    override
  });
});

// node_modules/prompts/lib/util/action.js
var require_action2 = __commonJS((exports, module) => {
  module.exports = (key, isSelect) => {
    if (key.meta && key.name !== "escape")
      return;
    if (key.ctrl) {
      if (key.name === "a")
        return "first";
      if (key.name === "c")
        return "abort";
      if (key.name === "d")
        return "abort";
      if (key.name === "e")
        return "last";
      if (key.name === "g")
        return "reset";
    }
    if (isSelect) {
      if (key.name === "j")
        return "down";
      if (key.name === "k")
        return "up";
    }
    if (key.name === "return")
      return "submit";
    if (key.name === "enter")
      return "submit";
    if (key.name === "backspace")
      return "delete";
    if (key.name === "delete")
      return "deleteForward";
    if (key.name === "abort")
      return "abort";
    if (key.name === "escape")
      return "exit";
    if (key.name === "tab")
      return "next";
    if (key.name === "pagedown")
      return "nextPage";
    if (key.name === "pageup")
      return "prevPage";
    if (key.name === "home")
      return "home";
    if (key.name === "end")
      return "end";
    if (key.name === "up")
      return "up";
    if (key.name === "down")
      return "down";
    if (key.name === "right")
      return "right";
    if (key.name === "left")
      return "left";
    return false;
  };
});

// node_modules/prompts/lib/util/strip.js
var require_strip2 = __commonJS((exports, module) => {
  module.exports = (str) => {
    const pattern = [
      "[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)",
      "(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PRZcf-ntqry=><~]))"
    ].join("|");
    const RGX = new RegExp(pattern, "g");
    return typeof str === "string" ? str.replace(RGX, "") : str;
  };
});

// node_modules/prompts/lib/util/clear.js
var require_clear2 = __commonJS((exports, module) => {
  var strip = require_strip2();
  var { erase, cursor } = require_src();
  var width = (str) => [...strip(str)].length;
  module.exports = function(prompt, perLine) {
    if (!perLine)
      return erase.line + cursor.to(0);
    let rows = 0;
    const lines = prompt.split(/\r?\n/);
    for (let line of lines) {
      rows += 1 + Math.floor(Math.max(width(line) - 1, 0) / perLine);
    }
    return erase.lines(rows);
  };
});

// node_modules/prompts/lib/util/figures.js
var require_figures2 = __commonJS((exports, module) => {
  var main = {
    arrowUp: "\u2191",
    arrowDown: "\u2193",
    arrowLeft: "\u2190",
    arrowRight: "\u2192",
    radioOn: "\u25C9",
    radioOff: "\u25EF",
    tick: "\u2714",
    cross: "\u2716",
    ellipsis: "\u2026",
    pointerSmall: "\u203A",
    line: "\u2500",
    pointer: "\u276F"
  };
  var win = {
    arrowUp: main.arrowUp,
    arrowDown: main.arrowDown,
    arrowLeft: main.arrowLeft,
    arrowRight: main.arrowRight,
    radioOn: "(*)",
    radioOff: "( )",
    tick: "\u221A",
    cross: "\xD7",
    ellipsis: "...",
    pointerSmall: "\xBB",
    line: "\u2500",
    pointer: ">"
  };
  var figures = process.platform === "win32" ? win : main;
  module.exports = figures;
});

// node_modules/prompts/lib/util/style.js
var require_style2 = __commonJS((exports, module) => {
  var c = require_kleur();
  var figures = require_figures2();
  var styles3 = Object.freeze({
    password: { scale: 1, render: (input) => "*".repeat(input.length) },
    emoji: { scale: 2, render: (input) => "\uD83D\uDE03".repeat(input.length) },
    invisible: { scale: 0, render: (input) => "" },
    default: { scale: 1, render: (input) => `${input}` }
  });
  var render = (type) => styles3[type] || styles3.default;
  var symbols = Object.freeze({
    aborted: c.red(figures.cross),
    done: c.green(figures.tick),
    exited: c.yellow(figures.cross),
    default: c.cyan("?")
  });
  var symbol = (done, aborted, exited) => aborted ? symbols.aborted : exited ? symbols.exited : done ? symbols.done : symbols.default;
  var delimiter = (completing) => c.gray(completing ? figures.ellipsis : figures.pointerSmall);
  var item = (expandable, expanded) => c.gray(expandable ? expanded ? figures.pointerSmall : "+" : figures.line);
  module.exports = {
    styles: styles3,
    render,
    symbols,
    symbol,
    delimiter,
    item
  };
});

// node_modules/prompts/lib/util/lines.js
var require_lines2 = __commonJS((exports, module) => {
  var strip = require_strip2();
  module.exports = function(msg, perLine) {
    let lines = String(strip(msg) || "").split(/\r?\n/);
    if (!perLine)
      return lines.length;
    return lines.map((l) => Math.ceil(l.length / perLine)).reduce((a, b) => a + b);
  };
});

// node_modules/prompts/lib/util/wrap.js
var require_wrap2 = __commonJS((exports, module) => {
  module.exports = (msg, opts = {}) => {
    const tab = Number.isSafeInteger(parseInt(opts.margin)) ? new Array(parseInt(opts.margin)).fill(" ").join("") : opts.margin || "";
    const width = opts.width;
    return (msg || "").split(/\r?\n/g).map((line) => line.split(/\s+/g).reduce((arr, w) => {
      if (w.length + tab.length >= width || arr[arr.length - 1].length + w.length + 1 < width)
        arr[arr.length - 1] += ` ${w}`;
      else
        arr.push(`${tab}${w}`);
      return arr;
    }, [tab]).join(`
`)).join(`
`);
  };
});

// node_modules/prompts/lib/util/entriesToDisplay.js
var require_entriesToDisplay2 = __commonJS((exports, module) => {
  module.exports = (cursor, total, maxVisible) => {
    maxVisible = maxVisible || total;
    let startIndex = Math.min(total - maxVisible, cursor - Math.floor(maxVisible / 2));
    if (startIndex < 0)
      startIndex = 0;
    let endIndex = Math.min(startIndex + maxVisible, total);
    return { startIndex, endIndex };
  };
});

// node_modules/prompts/lib/util/index.js
var require_util2 = __commonJS((exports, module) => {
  module.exports = {
    action: require_action2(),
    clear: require_clear2(),
    style: require_style2(),
    strip: require_strip2(),
    figures: require_figures2(),
    lines: require_lines2(),
    wrap: require_wrap2(),
    entriesToDisplay: require_entriesToDisplay2()
  };
});

// node_modules/prompts/lib/elements/prompt.js
var require_prompt2 = __commonJS((exports, module) => {
  var readline = __require("readline");
  var { action } = require_util2();
  var EventEmitter = __require("events");
  var { beep, cursor } = require_src();
  var color = require_kleur();

  class Prompt extends EventEmitter {
    constructor(opts = {}) {
      super();
      this.firstRender = true;
      this.in = opts.stdin || process.stdin;
      this.out = opts.stdout || process.stdout;
      this.onRender = (opts.onRender || (() => {
        return;
      })).bind(this);
      const rl = readline.createInterface({ input: this.in, escapeCodeTimeout: 50 });
      readline.emitKeypressEvents(this.in, rl);
      if (this.in.isTTY)
        this.in.setRawMode(true);
      const isSelect = ["SelectPrompt", "MultiselectPrompt"].indexOf(this.constructor.name) > -1;
      const keypress = (str, key) => {
        let a = action(key, isSelect);
        if (a === false) {
          this._ && this._(str, key);
        } else if (typeof this[a] === "function") {
          this[a](key);
        } else {
          this.bell();
        }
      };
      this.close = () => {
        this.out.write(cursor.show);
        this.in.removeListener("keypress", keypress);
        if (this.in.isTTY)
          this.in.setRawMode(false);
        rl.close();
        this.emit(this.aborted ? "abort" : this.exited ? "exit" : "submit", this.value);
        this.closed = true;
      };
      this.in.on("keypress", keypress);
    }
    fire() {
      this.emit("state", {
        value: this.value,
        aborted: !!this.aborted,
        exited: !!this.exited
      });
    }
    bell() {
      this.out.write(beep);
    }
    render() {
      this.onRender(color);
      if (this.firstRender)
        this.firstRender = false;
    }
  }
  module.exports = Prompt;
});

// node_modules/prompts/lib/elements/text.js
var require_text2 = __commonJS((exports, module) => {
  var color = require_kleur();
  var Prompt = require_prompt2();
  var { erase, cursor } = require_src();
  var { style, clear, lines, figures } = require_util2();

  class TextPrompt extends Prompt {
    constructor(opts = {}) {
      super(opts);
      this.transform = style.render(opts.style);
      this.scale = this.transform.scale;
      this.msg = opts.message;
      this.initial = opts.initial || ``;
      this.validator = opts.validate || (() => true);
      this.value = ``;
      this.errorMsg = opts.error || `Please Enter A Valid Value`;
      this.cursor = Number(!!this.initial);
      this.cursorOffset = 0;
      this.clear = clear(``, this.out.columns);
      this.render();
    }
    set value(v) {
      if (!v && this.initial) {
        this.placeholder = true;
        this.rendered = color.gray(this.transform.render(this.initial));
      } else {
        this.placeholder = false;
        this.rendered = this.transform.render(v);
      }
      this._value = v;
      this.fire();
    }
    get value() {
      return this._value;
    }
    reset() {
      this.value = ``;
      this.cursor = Number(!!this.initial);
      this.cursorOffset = 0;
      this.fire();
      this.render();
    }
    exit() {
      this.abort();
    }
    abort() {
      this.value = this.value || this.initial;
      this.done = this.aborted = true;
      this.error = false;
      this.red = false;
      this.fire();
      this.render();
      this.out.write(`
`);
      this.close();
    }
    async validate() {
      let valid = await this.validator(this.value);
      if (typeof valid === `string`) {
        this.errorMsg = valid;
        valid = false;
      }
      this.error = !valid;
    }
    async submit() {
      this.value = this.value || this.initial;
      this.cursorOffset = 0;
      this.cursor = this.rendered.length;
      await this.validate();
      if (this.error) {
        this.red = true;
        this.fire();
        this.render();
        return;
      }
      this.done = true;
      this.aborted = false;
      this.fire();
      this.render();
      this.out.write(`
`);
      this.close();
    }
    next() {
      if (!this.placeholder)
        return this.bell();
      this.value = this.initial;
      this.cursor = this.rendered.length;
      this.fire();
      this.render();
    }
    moveCursor(n) {
      if (this.placeholder)
        return;
      this.cursor = this.cursor + n;
      this.cursorOffset += n;
    }
    _(c, key) {
      let s1 = this.value.slice(0, this.cursor);
      let s2 = this.value.slice(this.cursor);
      this.value = `${s1}${c}${s2}`;
      this.red = false;
      this.cursor = this.placeholder ? 0 : s1.length + 1;
      this.render();
    }
    delete() {
      if (this.isCursorAtStart())
        return this.bell();
      let s1 = this.value.slice(0, this.cursor - 1);
      let s2 = this.value.slice(this.cursor);
      this.value = `${s1}${s2}`;
      this.red = false;
      if (this.isCursorAtStart()) {
        this.cursorOffset = 0;
      } else {
        this.cursorOffset++;
        this.moveCursor(-1);
      }
      this.render();
    }
    deleteForward() {
      if (this.cursor * this.scale >= this.rendered.length || this.placeholder)
        return this.bell();
      let s1 = this.value.slice(0, this.cursor);
      let s2 = this.value.slice(this.cursor + 1);
      this.value = `${s1}${s2}`;
      this.red = false;
      if (this.isCursorAtEnd()) {
        this.cursorOffset = 0;
      } else {
        this.cursorOffset++;
      }
      this.render();
    }
    first() {
      this.cursor = 0;
      this.render();
    }
    last() {
      this.cursor = this.value.length;
      this.render();
    }
    left() {
      if (this.cursor <= 0 || this.placeholder)
        return this.bell();
      this.moveCursor(-1);
      this.render();
    }
    right() {
      if (this.cursor * this.scale >= this.rendered.length || this.placeholder)
        return this.bell();
      this.moveCursor(1);
      this.render();
    }
    isCursorAtStart() {
      return this.cursor === 0 || this.placeholder && this.cursor === 1;
    }
    isCursorAtEnd() {
      return this.cursor === this.rendered.length || this.placeholder && this.cursor === this.rendered.length + 1;
    }
    render() {
      if (this.closed)
        return;
      if (!this.firstRender) {
        if (this.outputError)
          this.out.write(cursor.down(lines(this.outputError, this.out.columns) - 1) + clear(this.outputError, this.out.columns));
        this.out.write(clear(this.outputText, this.out.columns));
      }
      super.render();
      this.outputError = "";
      this.outputText = [
        style.symbol(this.done, this.aborted),
        color.bold(this.msg),
        style.delimiter(this.done),
        this.red ? color.red(this.rendered) : this.rendered
      ].join(` `);
      if (this.error) {
        this.outputError += this.errorMsg.split(`
`).reduce((a, l, i) => a + `
${i ? " " : figures.pointerSmall} ${color.red().italic(l)}`, ``);
      }
      this.out.write(erase.line + cursor.to(0) + this.outputText + cursor.save + this.outputError + cursor.restore + cursor.move(this.cursorOffset, 0));
    }
  }
  module.exports = TextPrompt;
});

// node_modules/prompts/lib/elements/select.js
var require_select2 = __commonJS((exports, module) => {
  var color = require_kleur();
  var Prompt = require_prompt2();
  var { style, clear, figures, wrap, entriesToDisplay } = require_util2();
  var { cursor } = require_src();

  class SelectPrompt extends Prompt {
    constructor(opts = {}) {
      super(opts);
      this.msg = opts.message;
      this.hint = opts.hint || "- Use arrow-keys. Return to submit.";
      this.warn = opts.warn || "- This option is disabled";
      this.cursor = opts.initial || 0;
      this.choices = opts.choices.map((ch, idx) => {
        if (typeof ch === "string")
          ch = { title: ch, value: idx };
        return {
          title: ch && (ch.title || ch.value || ch),
          value: ch && (ch.value === undefined ? idx : ch.value),
          description: ch && ch.description,
          selected: ch && ch.selected,
          disabled: ch && ch.disabled
        };
      });
      this.optionsPerPage = opts.optionsPerPage || 10;
      this.value = (this.choices[this.cursor] || {}).value;
      this.clear = clear("", this.out.columns);
      this.render();
    }
    moveCursor(n) {
      this.cursor = n;
      this.value = this.choices[n].value;
      this.fire();
    }
    reset() {
      this.moveCursor(0);
      this.fire();
      this.render();
    }
    exit() {
      this.abort();
    }
    abort() {
      this.done = this.aborted = true;
      this.fire();
      this.render();
      this.out.write(`
`);
      this.close();
    }
    submit() {
      if (!this.selection.disabled) {
        this.done = true;
        this.aborted = false;
        this.fire();
        this.render();
        this.out.write(`
`);
        this.close();
      } else
        this.bell();
    }
    first() {
      this.moveCursor(0);
      this.render();
    }
    last() {
      this.moveCursor(this.choices.length - 1);
      this.render();
    }
    up() {
      if (this.cursor === 0) {
        this.moveCursor(this.choices.length - 1);
      } else {
        this.moveCursor(this.cursor - 1);
      }
      this.render();
    }
    down() {
      if (this.cursor === this.choices.length - 1) {
        this.moveCursor(0);
      } else {
        this.moveCursor(this.cursor + 1);
      }
      this.render();
    }
    next() {
      this.moveCursor((this.cursor + 1) % this.choices.length);
      this.render();
    }
    _(c, key) {
      if (c === " ")
        return this.submit();
    }
    get selection() {
      return this.choices[this.cursor];
    }
    render() {
      if (this.closed)
        return;
      if (this.firstRender)
        this.out.write(cursor.hide);
      else
        this.out.write(clear(this.outputText, this.out.columns));
      super.render();
      let { startIndex, endIndex } = entriesToDisplay(this.cursor, this.choices.length, this.optionsPerPage);
      this.outputText = [
        style.symbol(this.done, this.aborted),
        color.bold(this.msg),
        style.delimiter(false),
        this.done ? this.selection.title : this.selection.disabled ? color.yellow(this.warn) : color.gray(this.hint)
      ].join(" ");
      if (!this.done) {
        this.outputText += `
`;
        for (let i = startIndex;i < endIndex; i++) {
          let title, prefix, desc = "", v = this.choices[i];
          if (i === startIndex && startIndex > 0) {
            prefix = figures.arrowUp;
          } else if (i === endIndex - 1 && endIndex < this.choices.length) {
            prefix = figures.arrowDown;
          } else {
            prefix = " ";
          }
          if (v.disabled) {
            title = this.cursor === i ? color.gray().underline(v.title) : color.strikethrough().gray(v.title);
            prefix = (this.cursor === i ? color.bold().gray(figures.pointer) + " " : "  ") + prefix;
          } else {
            title = this.cursor === i ? color.cyan().underline(v.title) : v.title;
            prefix = (this.cursor === i ? color.cyan(figures.pointer) + " " : "  ") + prefix;
            if (v.description && this.cursor === i) {
              desc = ` - ${v.description}`;
              if (prefix.length + title.length + desc.length >= this.out.columns || v.description.split(/\r?\n/).length > 1) {
                desc = `
` + wrap(v.description, { margin: 3, width: this.out.columns });
              }
            }
          }
          this.outputText += `${prefix} ${title}${color.gray(desc)}
`;
        }
      }
      this.out.write(this.outputText);
    }
  }
  module.exports = SelectPrompt;
});

// node_modules/prompts/lib/elements/toggle.js
var require_toggle2 = __commonJS((exports, module) => {
  var color = require_kleur();
  var Prompt = require_prompt2();
  var { style, clear } = require_util2();
  var { cursor, erase } = require_src();

  class TogglePrompt extends Prompt {
    constructor(opts = {}) {
      super(opts);
      this.msg = opts.message;
      this.value = !!opts.initial;
      this.active = opts.active || "on";
      this.inactive = opts.inactive || "off";
      this.initialValue = this.value;
      this.render();
    }
    reset() {
      this.value = this.initialValue;
      this.fire();
      this.render();
    }
    exit() {
      this.abort();
    }
    abort() {
      this.done = this.aborted = true;
      this.fire();
      this.render();
      this.out.write(`
`);
      this.close();
    }
    submit() {
      this.done = true;
      this.aborted = false;
      this.fire();
      this.render();
      this.out.write(`
`);
      this.close();
    }
    deactivate() {
      if (this.value === false)
        return this.bell();
      this.value = false;
      this.render();
    }
    activate() {
      if (this.value === true)
        return this.bell();
      this.value = true;
      this.render();
    }
    delete() {
      this.deactivate();
    }
    left() {
      this.deactivate();
    }
    right() {
      this.activate();
    }
    down() {
      this.deactivate();
    }
    up() {
      this.activate();
    }
    next() {
      this.value = !this.value;
      this.fire();
      this.render();
    }
    _(c, key) {
      if (c === " ") {
        this.value = !this.value;
      } else if (c === "1") {
        this.value = true;
      } else if (c === "0") {
        this.value = false;
      } else
        return this.bell();
      this.render();
    }
    render() {
      if (this.closed)
        return;
      if (this.firstRender)
        this.out.write(cursor.hide);
      else
        this.out.write(clear(this.outputText, this.out.columns));
      super.render();
      this.outputText = [
        style.symbol(this.done, this.aborted),
        color.bold(this.msg),
        style.delimiter(this.done),
        this.value ? this.inactive : color.cyan().underline(this.inactive),
        color.gray("/"),
        this.value ? color.cyan().underline(this.active) : this.active
      ].join(" ");
      this.out.write(erase.line + cursor.to(0) + this.outputText);
    }
  }
  module.exports = TogglePrompt;
});

// node_modules/prompts/lib/dateparts/datepart.js
var require_datepart2 = __commonJS((exports, module) => {
  class DatePart {
    constructor({ token, date, parts, locales }) {
      this.token = token;
      this.date = date || new Date;
      this.parts = parts || [this];
      this.locales = locales || {};
    }
    up() {}
    down() {}
    next() {
      const currentIdx = this.parts.indexOf(this);
      return this.parts.find((part, idx) => idx > currentIdx && part instanceof DatePart);
    }
    setTo(val) {}
    prev() {
      let parts = [].concat(this.parts).reverse();
      const currentIdx = parts.indexOf(this);
      return parts.find((part, idx) => idx > currentIdx && part instanceof DatePart);
    }
    toString() {
      return String(this.date);
    }
  }
  module.exports = DatePart;
});

// node_modules/prompts/lib/dateparts/meridiem.js
var require_meridiem2 = __commonJS((exports, module) => {
  var DatePart = require_datepart2();

  class Meridiem extends DatePart {
    constructor(opts = {}) {
      super(opts);
    }
    up() {
      this.date.setHours((this.date.getHours() + 12) % 24);
    }
    down() {
      this.up();
    }
    toString() {
      let meridiem = this.date.getHours() > 12 ? "pm" : "am";
      return /\A/.test(this.token) ? meridiem.toUpperCase() : meridiem;
    }
  }
  module.exports = Meridiem;
});

// node_modules/prompts/lib/dateparts/day.js
var require_day2 = __commonJS((exports, module) => {
  var DatePart = require_datepart2();
  var pos = (n) => {
    n = n % 10;
    return n === 1 ? "st" : n === 2 ? "nd" : n === 3 ? "rd" : "th";
  };

  class Day extends DatePart {
    constructor(opts = {}) {
      super(opts);
    }
    up() {
      this.date.setDate(this.date.getDate() + 1);
    }
    down() {
      this.date.setDate(this.date.getDate() - 1);
    }
    setTo(val) {
      this.date.setDate(parseInt(val.substr(-2)));
    }
    toString() {
      let date = this.date.getDate();
      let day = this.date.getDay();
      return this.token === "DD" ? String(date).padStart(2, "0") : this.token === "Do" ? date + pos(date) : this.token === "d" ? day + 1 : this.token === "ddd" ? this.locales.weekdaysShort[day] : this.token === "dddd" ? this.locales.weekdays[day] : date;
    }
  }
  module.exports = Day;
});

// node_modules/prompts/lib/dateparts/hours.js
var require_hours2 = __commonJS((exports, module) => {
  var DatePart = require_datepart2();

  class Hours extends DatePart {
    constructor(opts = {}) {
      super(opts);
    }
    up() {
      this.date.setHours(this.date.getHours() + 1);
    }
    down() {
      this.date.setHours(this.date.getHours() - 1);
    }
    setTo(val) {
      this.date.setHours(parseInt(val.substr(-2)));
    }
    toString() {
      let hours = this.date.getHours();
      if (/h/.test(this.token))
        hours = hours % 12 || 12;
      return this.token.length > 1 ? String(hours).padStart(2, "0") : hours;
    }
  }
  module.exports = Hours;
});

// node_modules/prompts/lib/dateparts/milliseconds.js
var require_milliseconds2 = __commonJS((exports, module) => {
  var DatePart = require_datepart2();

  class Milliseconds extends DatePart {
    constructor(opts = {}) {
      super(opts);
    }
    up() {
      this.date.setMilliseconds(this.date.getMilliseconds() + 1);
    }
    down() {
      this.date.setMilliseconds(this.date.getMilliseconds() - 1);
    }
    setTo(val) {
      this.date.setMilliseconds(parseInt(val.substr(-this.token.length)));
    }
    toString() {
      return String(this.date.getMilliseconds()).padStart(4, "0").substr(0, this.token.length);
    }
  }
  module.exports = Milliseconds;
});

// node_modules/prompts/lib/dateparts/minutes.js
var require_minutes2 = __commonJS((exports, module) => {
  var DatePart = require_datepart2();

  class Minutes extends DatePart {
    constructor(opts = {}) {
      super(opts);
    }
    up() {
      this.date.setMinutes(this.date.getMinutes() + 1);
    }
    down() {
      this.date.setMinutes(this.date.getMinutes() - 1);
    }
    setTo(val) {
      this.date.setMinutes(parseInt(val.substr(-2)));
    }
    toString() {
      let m = this.date.getMinutes();
      return this.token.length > 1 ? String(m).padStart(2, "0") : m;
    }
  }
  module.exports = Minutes;
});

// node_modules/prompts/lib/dateparts/month.js
var require_month2 = __commonJS((exports, module) => {
  var DatePart = require_datepart2();

  class Month extends DatePart {
    constructor(opts = {}) {
      super(opts);
    }
    up() {
      this.date.setMonth(this.date.getMonth() + 1);
    }
    down() {
      this.date.setMonth(this.date.getMonth() - 1);
    }
    setTo(val) {
      val = parseInt(val.substr(-2)) - 1;
      this.date.setMonth(val < 0 ? 0 : val);
    }
    toString() {
      let month = this.date.getMonth();
      let tl = this.token.length;
      return tl === 2 ? String(month + 1).padStart(2, "0") : tl === 3 ? this.locales.monthsShort[month] : tl === 4 ? this.locales.months[month] : String(month + 1);
    }
  }
  module.exports = Month;
});

// node_modules/prompts/lib/dateparts/seconds.js
var require_seconds2 = __commonJS((exports, module) => {
  var DatePart = require_datepart2();

  class Seconds extends DatePart {
    constructor(opts = {}) {
      super(opts);
    }
    up() {
      this.date.setSeconds(this.date.getSeconds() + 1);
    }
    down() {
      this.date.setSeconds(this.date.getSeconds() - 1);
    }
    setTo(val) {
      this.date.setSeconds(parseInt(val.substr(-2)));
    }
    toString() {
      let s = this.date.getSeconds();
      return this.token.length > 1 ? String(s).padStart(2, "0") : s;
    }
  }
  module.exports = Seconds;
});

// node_modules/prompts/lib/dateparts/year.js
var require_year2 = __commonJS((exports, module) => {
  var DatePart = require_datepart2();

  class Year extends DatePart {
    constructor(opts = {}) {
      super(opts);
    }
    up() {
      this.date.setFullYear(this.date.getFullYear() + 1);
    }
    down() {
      this.date.setFullYear(this.date.getFullYear() - 1);
    }
    setTo(val) {
      this.date.setFullYear(val.substr(-4));
    }
    toString() {
      let year = String(this.date.getFullYear()).padStart(4, "0");
      return this.token.length === 2 ? year.substr(-2) : year;
    }
  }
  module.exports = Year;
});

// node_modules/prompts/lib/dateparts/index.js
var require_dateparts2 = __commonJS((exports, module) => {
  module.exports = {
    DatePart: require_datepart2(),
    Meridiem: require_meridiem2(),
    Day: require_day2(),
    Hours: require_hours2(),
    Milliseconds: require_milliseconds2(),
    Minutes: require_minutes2(),
    Month: require_month2(),
    Seconds: require_seconds2(),
    Year: require_year2()
  };
});

// node_modules/prompts/lib/elements/date.js
var require_date2 = __commonJS((exports, module) => {
  var color = require_kleur();
  var Prompt = require_prompt2();
  var { style, clear, figures } = require_util2();
  var { erase, cursor } = require_src();
  var { DatePart, Meridiem, Day, Hours, Milliseconds, Minutes, Month, Seconds, Year } = require_dateparts2();
  var regex = /\\(.)|"((?:\\["\\]|[^"])+)"|(D[Do]?|d{3,4}|d)|(M{1,4})|(YY(?:YY)?)|([aA])|([Hh]{1,2})|(m{1,2})|(s{1,2})|(S{1,4})|./g;
  var regexGroups = {
    1: ({ token }) => token.replace(/\\(.)/g, "$1"),
    2: (opts) => new Day(opts),
    3: (opts) => new Month(opts),
    4: (opts) => new Year(opts),
    5: (opts) => new Meridiem(opts),
    6: (opts) => new Hours(opts),
    7: (opts) => new Minutes(opts),
    8: (opts) => new Seconds(opts),
    9: (opts) => new Milliseconds(opts)
  };
  var dfltLocales = {
    months: "January,February,March,April,May,June,July,August,September,October,November,December".split(","),
    monthsShort: "Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec".split(","),
    weekdays: "Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday".split(","),
    weekdaysShort: "Sun,Mon,Tue,Wed,Thu,Fri,Sat".split(",")
  };

  class DatePrompt extends Prompt {
    constructor(opts = {}) {
      super(opts);
      this.msg = opts.message;
      this.cursor = 0;
      this.typed = "";
      this.locales = Object.assign(dfltLocales, opts.locales);
      this._date = opts.initial || new Date;
      this.errorMsg = opts.error || "Please Enter A Valid Value";
      this.validator = opts.validate || (() => true);
      this.mask = opts.mask || "YYYY-MM-DD HH:mm:ss";
      this.clear = clear("", this.out.columns);
      this.render();
    }
    get value() {
      return this.date;
    }
    get date() {
      return this._date;
    }
    set date(date) {
      if (date)
        this._date.setTime(date.getTime());
    }
    set mask(mask) {
      let result;
      this.parts = [];
      while (result = regex.exec(mask)) {
        let match = result.shift();
        let idx = result.findIndex((gr) => gr != null);
        this.parts.push(idx in regexGroups ? regexGroups[idx]({ token: result[idx] || match, date: this.date, parts: this.parts, locales: this.locales }) : result[idx] || match);
      }
      let parts = this.parts.reduce((arr, i) => {
        if (typeof i === "string" && typeof arr[arr.length - 1] === "string")
          arr[arr.length - 1] += i;
        else
          arr.push(i);
        return arr;
      }, []);
      this.parts.splice(0);
      this.parts.push(...parts);
      this.reset();
    }
    moveCursor(n) {
      this.typed = "";
      this.cursor = n;
      this.fire();
    }
    reset() {
      this.moveCursor(this.parts.findIndex((p) => p instanceof DatePart));
      this.fire();
      this.render();
    }
    exit() {
      this.abort();
    }
    abort() {
      this.done = this.aborted = true;
      this.error = false;
      this.fire();
      this.render();
      this.out.write(`
`);
      this.close();
    }
    async validate() {
      let valid = await this.validator(this.value);
      if (typeof valid === "string") {
        this.errorMsg = valid;
        valid = false;
      }
      this.error = !valid;
    }
    async submit() {
      await this.validate();
      if (this.error) {
        this.color = "red";
        this.fire();
        this.render();
        return;
      }
      this.done = true;
      this.aborted = false;
      this.fire();
      this.render();
      this.out.write(`
`);
      this.close();
    }
    up() {
      this.typed = "";
      this.parts[this.cursor].up();
      this.render();
    }
    down() {
      this.typed = "";
      this.parts[this.cursor].down();
      this.render();
    }
    left() {
      let prev = this.parts[this.cursor].prev();
      if (prev == null)
        return this.bell();
      this.moveCursor(this.parts.indexOf(prev));
      this.render();
    }
    right() {
      let next = this.parts[this.cursor].next();
      if (next == null)
        return this.bell();
      this.moveCursor(this.parts.indexOf(next));
      this.render();
    }
    next() {
      let next = this.parts[this.cursor].next();
      this.moveCursor(next ? this.parts.indexOf(next) : this.parts.findIndex((part) => part instanceof DatePart));
      this.render();
    }
    _(c) {
      if (/\d/.test(c)) {
        this.typed += c;
        this.parts[this.cursor].setTo(this.typed);
        this.render();
      }
    }
    render() {
      if (this.closed)
        return;
      if (this.firstRender)
        this.out.write(cursor.hide);
      else
        this.out.write(clear(this.outputText, this.out.columns));
      super.render();
      this.outputText = [
        style.symbol(this.done, this.aborted),
        color.bold(this.msg),
        style.delimiter(false),
        this.parts.reduce((arr, p, idx) => arr.concat(idx === this.cursor && !this.done ? color.cyan().underline(p.toString()) : p), []).join("")
      ].join(" ");
      if (this.error) {
        this.outputText += this.errorMsg.split(`
`).reduce((a, l, i) => a + `
${i ? ` ` : figures.pointerSmall} ${color.red().italic(l)}`, ``);
      }
      this.out.write(erase.line + cursor.to(0) + this.outputText);
    }
  }
  module.exports = DatePrompt;
});

// node_modules/prompts/lib/elements/number.js
var require_number2 = __commonJS((exports, module) => {
  var color = require_kleur();
  var Prompt = require_prompt2();
  var { cursor, erase } = require_src();
  var { style, figures, clear, lines } = require_util2();
  var isNumber = /[0-9]/;
  var isDef = (any) => any !== undefined;
  var round = (number, precision) => {
    let factor = Math.pow(10, precision);
    return Math.round(number * factor) / factor;
  };

  class NumberPrompt extends Prompt {
    constructor(opts = {}) {
      super(opts);
      this.transform = style.render(opts.style);
      this.msg = opts.message;
      this.initial = isDef(opts.initial) ? opts.initial : "";
      this.float = !!opts.float;
      this.round = opts.round || 2;
      this.inc = opts.increment || 1;
      this.min = isDef(opts.min) ? opts.min : -Infinity;
      this.max = isDef(opts.max) ? opts.max : Infinity;
      this.errorMsg = opts.error || `Please Enter A Valid Value`;
      this.validator = opts.validate || (() => true);
      this.color = `cyan`;
      this.value = ``;
      this.typed = ``;
      this.lastHit = 0;
      this.render();
    }
    set value(v) {
      if (!v && v !== 0) {
        this.placeholder = true;
        this.rendered = color.gray(this.transform.render(`${this.initial}`));
        this._value = ``;
      } else {
        this.placeholder = false;
        this.rendered = this.transform.render(`${round(v, this.round)}`);
        this._value = round(v, this.round);
      }
      this.fire();
    }
    get value() {
      return this._value;
    }
    parse(x) {
      return this.float ? parseFloat(x) : parseInt(x);
    }
    valid(c) {
      return c === `-` || c === `.` && this.float || isNumber.test(c);
    }
    reset() {
      this.typed = ``;
      this.value = ``;
      this.fire();
      this.render();
    }
    exit() {
      this.abort();
    }
    abort() {
      let x = this.value;
      this.value = x !== `` ? x : this.initial;
      this.done = this.aborted = true;
      this.error = false;
      this.fire();
      this.render();
      this.out.write(`
`);
      this.close();
    }
    async validate() {
      let valid = await this.validator(this.value);
      if (typeof valid === `string`) {
        this.errorMsg = valid;
        valid = false;
      }
      this.error = !valid;
    }
    async submit() {
      await this.validate();
      if (this.error) {
        this.color = `red`;
        this.fire();
        this.render();
        return;
      }
      let x = this.value;
      this.value = x !== `` ? x : this.initial;
      this.done = true;
      this.aborted = false;
      this.error = false;
      this.fire();
      this.render();
      this.out.write(`
`);
      this.close();
    }
    up() {
      this.typed = ``;
      if (this.value === "") {
        this.value = this.min - this.inc;
      }
      if (this.value >= this.max)
        return this.bell();
      this.value += this.inc;
      this.color = `cyan`;
      this.fire();
      this.render();
    }
    down() {
      this.typed = ``;
      if (this.value === "") {
        this.value = this.min + this.inc;
      }
      if (this.value <= this.min)
        return this.bell();
      this.value -= this.inc;
      this.color = `cyan`;
      this.fire();
      this.render();
    }
    delete() {
      let val = this.value.toString();
      if (val.length === 0)
        return this.bell();
      this.value = this.parse(val = val.slice(0, -1)) || ``;
      if (this.value !== "" && this.value < this.min) {
        this.value = this.min;
      }
      this.color = `cyan`;
      this.fire();
      this.render();
    }
    next() {
      this.value = this.initial;
      this.fire();
      this.render();
    }
    _(c, key) {
      if (!this.valid(c))
        return this.bell();
      const now = Date.now();
      if (now - this.lastHit > 1000)
        this.typed = ``;
      this.typed += c;
      this.lastHit = now;
      this.color = `cyan`;
      if (c === `.`)
        return this.fire();
      this.value = Math.min(this.parse(this.typed), this.max);
      if (this.value > this.max)
        this.value = this.max;
      if (this.value < this.min)
        this.value = this.min;
      this.fire();
      this.render();
    }
    render() {
      if (this.closed)
        return;
      if (!this.firstRender) {
        if (this.outputError)
          this.out.write(cursor.down(lines(this.outputError, this.out.columns) - 1) + clear(this.outputError, this.out.columns));
        this.out.write(clear(this.outputText, this.out.columns));
      }
      super.render();
      this.outputError = "";
      this.outputText = [
        style.symbol(this.done, this.aborted),
        color.bold(this.msg),
        style.delimiter(this.done),
        !this.done || !this.done && !this.placeholder ? color[this.color]().underline(this.rendered) : this.rendered
      ].join(` `);
      if (this.error) {
        this.outputError += this.errorMsg.split(`
`).reduce((a, l, i) => a + `
${i ? ` ` : figures.pointerSmall} ${color.red().italic(l)}`, ``);
      }
      this.out.write(erase.line + cursor.to(0) + this.outputText + cursor.save + this.outputError + cursor.restore);
    }
  }
  module.exports = NumberPrompt;
});

// node_modules/prompts/lib/elements/multiselect.js
var require_multiselect2 = __commonJS((exports, module) => {
  var color = require_kleur();
  var { cursor } = require_src();
  var Prompt = require_prompt2();
  var { clear, figures, style, wrap, entriesToDisplay } = require_util2();

  class MultiselectPrompt extends Prompt {
    constructor(opts = {}) {
      super(opts);
      this.msg = opts.message;
      this.cursor = opts.cursor || 0;
      this.scrollIndex = opts.cursor || 0;
      this.hint = opts.hint || "";
      this.warn = opts.warn || "- This option is disabled -";
      this.minSelected = opts.min;
      this.showMinError = false;
      this.maxChoices = opts.max;
      this.instructions = opts.instructions;
      this.optionsPerPage = opts.optionsPerPage || 10;
      this.value = opts.choices.map((ch, idx) => {
        if (typeof ch === "string")
          ch = { title: ch, value: idx };
        return {
          title: ch && (ch.title || ch.value || ch),
          description: ch && ch.description,
          value: ch && (ch.value === undefined ? idx : ch.value),
          selected: ch && ch.selected,
          disabled: ch && ch.disabled
        };
      });
      this.clear = clear("", this.out.columns);
      if (!opts.overrideRender) {
        this.render();
      }
    }
    reset() {
      this.value.map((v) => !v.selected);
      this.cursor = 0;
      this.fire();
      this.render();
    }
    selected() {
      return this.value.filter((v) => v.selected);
    }
    exit() {
      this.abort();
    }
    abort() {
      this.done = this.aborted = true;
      this.fire();
      this.render();
      this.out.write(`
`);
      this.close();
    }
    submit() {
      const selected = this.value.filter((e) => e.selected);
      if (this.minSelected && selected.length < this.minSelected) {
        this.showMinError = true;
        this.render();
      } else {
        this.done = true;
        this.aborted = false;
        this.fire();
        this.render();
        this.out.write(`
`);
        this.close();
      }
    }
    first() {
      this.cursor = 0;
      this.render();
    }
    last() {
      this.cursor = this.value.length - 1;
      this.render();
    }
    next() {
      this.cursor = (this.cursor + 1) % this.value.length;
      this.render();
    }
    up() {
      if (this.cursor === 0) {
        this.cursor = this.value.length - 1;
      } else {
        this.cursor--;
      }
      this.render();
    }
    down() {
      if (this.cursor === this.value.length - 1) {
        this.cursor = 0;
      } else {
        this.cursor++;
      }
      this.render();
    }
    left() {
      this.value[this.cursor].selected = false;
      this.render();
    }
    right() {
      if (this.value.filter((e) => e.selected).length >= this.maxChoices)
        return this.bell();
      this.value[this.cursor].selected = true;
      this.render();
    }
    handleSpaceToggle() {
      const v = this.value[this.cursor];
      if (v.selected) {
        v.selected = false;
        this.render();
      } else if (v.disabled || this.value.filter((e) => e.selected).length >= this.maxChoices) {
        return this.bell();
      } else {
        v.selected = true;
        this.render();
      }
    }
    toggleAll() {
      if (this.maxChoices !== undefined || this.value[this.cursor].disabled) {
        return this.bell();
      }
      const newSelected = !this.value[this.cursor].selected;
      this.value.filter((v) => !v.disabled).forEach((v) => v.selected = newSelected);
      this.render();
    }
    _(c, key) {
      if (c === " ") {
        this.handleSpaceToggle();
      } else if (c === "a") {
        this.toggleAll();
      } else {
        return this.bell();
      }
    }
    renderInstructions() {
      if (this.instructions === undefined || this.instructions) {
        if (typeof this.instructions === "string") {
          return this.instructions;
        }
        return `
Instructions:
` + `    ${figures.arrowUp}/${figures.arrowDown}: Highlight option
` + `    ${figures.arrowLeft}/${figures.arrowRight}/[space]: Toggle selection
` + (this.maxChoices === undefined ? `    a: Toggle all
` : "") + `    enter/return: Complete answer`;
      }
      return "";
    }
    renderOption(cursor2, v, i, arrowIndicator) {
      const prefix = (v.selected ? color.green(figures.radioOn) : figures.radioOff) + " " + arrowIndicator + " ";
      let title, desc;
      if (v.disabled) {
        title = cursor2 === i ? color.gray().underline(v.title) : color.strikethrough().gray(v.title);
      } else {
        title = cursor2 === i ? color.cyan().underline(v.title) : v.title;
        if (cursor2 === i && v.description) {
          desc = ` - ${v.description}`;
          if (prefix.length + title.length + desc.length >= this.out.columns || v.description.split(/\r?\n/).length > 1) {
            desc = `
` + wrap(v.description, { margin: prefix.length, width: this.out.columns });
          }
        }
      }
      return prefix + title + color.gray(desc || "");
    }
    paginateOptions(options) {
      if (options.length === 0) {
        return color.red("No matches for this query.");
      }
      let { startIndex, endIndex } = entriesToDisplay(this.cursor, options.length, this.optionsPerPage);
      let prefix, styledOptions = [];
      for (let i = startIndex;i < endIndex; i++) {
        if (i === startIndex && startIndex > 0) {
          prefix = figures.arrowUp;
        } else if (i === endIndex - 1 && endIndex < options.length) {
          prefix = figures.arrowDown;
        } else {
          prefix = " ";
        }
        styledOptions.push(this.renderOption(this.cursor, options[i], i, prefix));
      }
      return `
` + styledOptions.join(`
`);
    }
    renderOptions(options) {
      if (!this.done) {
        return this.paginateOptions(options);
      }
      return "";
    }
    renderDoneOrInstructions() {
      if (this.done) {
        return this.value.filter((e) => e.selected).map((v) => v.title).join(", ");
      }
      const output = [color.gray(this.hint), this.renderInstructions()];
      if (this.value[this.cursor].disabled) {
        output.push(color.yellow(this.warn));
      }
      return output.join(" ");
    }
    render() {
      if (this.closed)
        return;
      if (this.firstRender)
        this.out.write(cursor.hide);
      super.render();
      let prompt = [
        style.symbol(this.done, this.aborted),
        color.bold(this.msg),
        style.delimiter(false),
        this.renderDoneOrInstructions()
      ].join(" ");
      if (this.showMinError) {
        prompt += color.red(`You must select a minimum of ${this.minSelected} choices.`);
        this.showMinError = false;
      }
      prompt += this.renderOptions(this.value);
      this.out.write(this.clear + prompt);
      this.clear = clear(prompt, this.out.columns);
    }
  }
  module.exports = MultiselectPrompt;
});

// node_modules/prompts/lib/elements/autocomplete.js
var require_autocomplete2 = __commonJS((exports, module) => {
  var color = require_kleur();
  var Prompt = require_prompt2();
  var { erase, cursor } = require_src();
  var { style, clear, figures, wrap, entriesToDisplay } = require_util2();
  var getVal = (arr, i) => arr[i] && (arr[i].value || arr[i].title || arr[i]);
  var getTitle = (arr, i) => arr[i] && (arr[i].title || arr[i].value || arr[i]);
  var getIndex = (arr, valOrTitle) => {
    const index = arr.findIndex((el) => el.value === valOrTitle || el.title === valOrTitle);
    return index > -1 ? index : undefined;
  };

  class AutocompletePrompt extends Prompt {
    constructor(opts = {}) {
      super(opts);
      this.msg = opts.message;
      this.suggest = opts.suggest;
      this.choices = opts.choices;
      this.initial = typeof opts.initial === "number" ? opts.initial : getIndex(opts.choices, opts.initial);
      this.select = this.initial || opts.cursor || 0;
      this.i18n = { noMatches: opts.noMatches || "no matches found" };
      this.fallback = opts.fallback || this.initial;
      this.clearFirst = opts.clearFirst || false;
      this.suggestions = [];
      this.input = "";
      this.limit = opts.limit || 10;
      this.cursor = 0;
      this.transform = style.render(opts.style);
      this.scale = this.transform.scale;
      this.render = this.render.bind(this);
      this.complete = this.complete.bind(this);
      this.clear = clear("", this.out.columns);
      this.complete(this.render);
      this.render();
    }
    set fallback(fb) {
      this._fb = Number.isSafeInteger(parseInt(fb)) ? parseInt(fb) : fb;
    }
    get fallback() {
      let choice;
      if (typeof this._fb === "number")
        choice = this.choices[this._fb];
      else if (typeof this._fb === "string")
        choice = { title: this._fb };
      return choice || this._fb || { title: this.i18n.noMatches };
    }
    moveSelect(i) {
      this.select = i;
      if (this.suggestions.length > 0)
        this.value = getVal(this.suggestions, i);
      else
        this.value = this.fallback.value;
      this.fire();
    }
    async complete(cb) {
      const p = this.completing = this.suggest(this.input, this.choices);
      const suggestions = await p;
      if (this.completing !== p)
        return;
      this.suggestions = suggestions.map((s, i, arr) => ({ title: getTitle(arr, i), value: getVal(arr, i), description: s.description }));
      this.completing = false;
      const l = Math.max(suggestions.length - 1, 0);
      this.moveSelect(Math.min(l, this.select));
      cb && cb();
    }
    reset() {
      this.input = "";
      this.complete(() => {
        this.moveSelect(this.initial !== undefined ? this.initial : 0);
        this.render();
      });
      this.render();
    }
    exit() {
      if (this.clearFirst && this.input.length > 0) {
        this.reset();
      } else {
        this.done = this.exited = true;
        this.aborted = false;
        this.fire();
        this.render();
        this.out.write(`
`);
        this.close();
      }
    }
    abort() {
      this.done = this.aborted = true;
      this.exited = false;
      this.fire();
      this.render();
      this.out.write(`
`);
      this.close();
    }
    submit() {
      this.done = true;
      this.aborted = this.exited = false;
      this.fire();
      this.render();
      this.out.write(`
`);
      this.close();
    }
    _(c, key) {
      let s1 = this.input.slice(0, this.cursor);
      let s2 = this.input.slice(this.cursor);
      this.input = `${s1}${c}${s2}`;
      this.cursor = s1.length + 1;
      this.complete(this.render);
      this.render();
    }
    delete() {
      if (this.cursor === 0)
        return this.bell();
      let s1 = this.input.slice(0, this.cursor - 1);
      let s2 = this.input.slice(this.cursor);
      this.input = `${s1}${s2}`;
      this.complete(this.render);
      this.cursor = this.cursor - 1;
      this.render();
    }
    deleteForward() {
      if (this.cursor * this.scale >= this.rendered.length)
        return this.bell();
      let s1 = this.input.slice(0, this.cursor);
      let s2 = this.input.slice(this.cursor + 1);
      this.input = `${s1}${s2}`;
      this.complete(this.render);
      this.render();
    }
    first() {
      this.moveSelect(0);
      this.render();
    }
    last() {
      this.moveSelect(this.suggestions.length - 1);
      this.render();
    }
    up() {
      if (this.select === 0) {
        this.moveSelect(this.suggestions.length - 1);
      } else {
        this.moveSelect(this.select - 1);
      }
      this.render();
    }
    down() {
      if (this.select === this.suggestions.length - 1) {
        this.moveSelect(0);
      } else {
        this.moveSelect(this.select + 1);
      }
      this.render();
    }
    next() {
      if (this.select === this.suggestions.length - 1) {
        this.moveSelect(0);
      } else
        this.moveSelect(this.select + 1);
      this.render();
    }
    nextPage() {
      this.moveSelect(Math.min(this.select + this.limit, this.suggestions.length - 1));
      this.render();
    }
    prevPage() {
      this.moveSelect(Math.max(this.select - this.limit, 0));
      this.render();
    }
    left() {
      if (this.cursor <= 0)
        return this.bell();
      this.cursor = this.cursor - 1;
      this.render();
    }
    right() {
      if (this.cursor * this.scale >= this.rendered.length)
        return this.bell();
      this.cursor = this.cursor + 1;
      this.render();
    }
    renderOption(v, hovered, isStart, isEnd) {
      let desc;
      let prefix = isStart ? figures.arrowUp : isEnd ? figures.arrowDown : " ";
      let title = hovered ? color.cyan().underline(v.title) : v.title;
      prefix = (hovered ? color.cyan(figures.pointer) + " " : "  ") + prefix;
      if (v.description) {
        desc = ` - ${v.description}`;
        if (prefix.length + title.length + desc.length >= this.out.columns || v.description.split(/\r?\n/).length > 1) {
          desc = `
` + wrap(v.description, { margin: 3, width: this.out.columns });
        }
      }
      return prefix + " " + title + color.gray(desc || "");
    }
    render() {
      if (this.closed)
        return;
      if (this.firstRender)
        this.out.write(cursor.hide);
      else
        this.out.write(clear(this.outputText, this.out.columns));
      super.render();
      let { startIndex, endIndex } = entriesToDisplay(this.select, this.choices.length, this.limit);
      this.outputText = [
        style.symbol(this.done, this.aborted, this.exited),
        color.bold(this.msg),
        style.delimiter(this.completing),
        this.done && this.suggestions[this.select] ? this.suggestions[this.select].title : this.rendered = this.transform.render(this.input)
      ].join(" ");
      if (!this.done) {
        const suggestions = this.suggestions.slice(startIndex, endIndex).map((item, i) => this.renderOption(item, this.select === i + startIndex, i === 0 && startIndex > 0, i + startIndex === endIndex - 1 && endIndex < this.choices.length)).join(`
`);
        this.outputText += `
` + (suggestions || color.gray(this.fallback.title));
      }
      this.out.write(erase.line + cursor.to(0) + this.outputText);
    }
  }
  module.exports = AutocompletePrompt;
});

// node_modules/prompts/lib/elements/autocompleteMultiselect.js
var require_autocompleteMultiselect2 = __commonJS((exports, module) => {
  var color = require_kleur();
  var { cursor } = require_src();
  var MultiselectPrompt = require_multiselect2();
  var { clear, style, figures } = require_util2();

  class AutocompleteMultiselectPrompt extends MultiselectPrompt {
    constructor(opts = {}) {
      opts.overrideRender = true;
      super(opts);
      this.inputValue = "";
      this.clear = clear("", this.out.columns);
      this.filteredOptions = this.value;
      this.render();
    }
    last() {
      this.cursor = this.filteredOptions.length - 1;
      this.render();
    }
    next() {
      this.cursor = (this.cursor + 1) % this.filteredOptions.length;
      this.render();
    }
    up() {
      if (this.cursor === 0) {
        this.cursor = this.filteredOptions.length - 1;
      } else {
        this.cursor--;
      }
      this.render();
    }
    down() {
      if (this.cursor === this.filteredOptions.length - 1) {
        this.cursor = 0;
      } else {
        this.cursor++;
      }
      this.render();
    }
    left() {
      this.filteredOptions[this.cursor].selected = false;
      this.render();
    }
    right() {
      if (this.value.filter((e) => e.selected).length >= this.maxChoices)
        return this.bell();
      this.filteredOptions[this.cursor].selected = true;
      this.render();
    }
    delete() {
      if (this.inputValue.length) {
        this.inputValue = this.inputValue.substr(0, this.inputValue.length - 1);
        this.updateFilteredOptions();
      }
    }
    updateFilteredOptions() {
      const currentHighlight = this.filteredOptions[this.cursor];
      this.filteredOptions = this.value.filter((v) => {
        if (this.inputValue) {
          if (typeof v.title === "string") {
            if (v.title.toLowerCase().includes(this.inputValue.toLowerCase())) {
              return true;
            }
          }
          if (typeof v.value === "string") {
            if (v.value.toLowerCase().includes(this.inputValue.toLowerCase())) {
              return true;
            }
          }
          return false;
        }
        return true;
      });
      const newHighlightIndex = this.filteredOptions.findIndex((v) => v === currentHighlight);
      this.cursor = newHighlightIndex < 0 ? 0 : newHighlightIndex;
      this.render();
    }
    handleSpaceToggle() {
      const v = this.filteredOptions[this.cursor];
      if (v.selected) {
        v.selected = false;
        this.render();
      } else if (v.disabled || this.value.filter((e) => e.selected).length >= this.maxChoices) {
        return this.bell();
      } else {
        v.selected = true;
        this.render();
      }
    }
    handleInputChange(c) {
      this.inputValue = this.inputValue + c;
      this.updateFilteredOptions();
    }
    _(c, key) {
      if (c === " ") {
        this.handleSpaceToggle();
      } else {
        this.handleInputChange(c);
      }
    }
    renderInstructions() {
      if (this.instructions === undefined || this.instructions) {
        if (typeof this.instructions === "string") {
          return this.instructions;
        }
        return `
Instructions:
    ${figures.arrowUp}/${figures.arrowDown}: Highlight option
    ${figures.arrowLeft}/${figures.arrowRight}/[space]: Toggle selection
    [a,b,c]/delete: Filter choices
    enter/return: Complete answer
`;
      }
      return "";
    }
    renderCurrentInput() {
      return `
Filtered results for: ${this.inputValue ? this.inputValue : color.gray("Enter something to filter")}
`;
    }
    renderOption(cursor2, v, i) {
      let title;
      if (v.disabled)
        title = cursor2 === i ? color.gray().underline(v.title) : color.strikethrough().gray(v.title);
      else
        title = cursor2 === i ? color.cyan().underline(v.title) : v.title;
      return (v.selected ? color.green(figures.radioOn) : figures.radioOff) + "  " + title;
    }
    renderDoneOrInstructions() {
      if (this.done) {
        return this.value.filter((e) => e.selected).map((v) => v.title).join(", ");
      }
      const output = [color.gray(this.hint), this.renderInstructions(), this.renderCurrentInput()];
      if (this.filteredOptions.length && this.filteredOptions[this.cursor].disabled) {
        output.push(color.yellow(this.warn));
      }
      return output.join(" ");
    }
    render() {
      if (this.closed)
        return;
      if (this.firstRender)
        this.out.write(cursor.hide);
      super.render();
      let prompt = [
        style.symbol(this.done, this.aborted),
        color.bold(this.msg),
        style.delimiter(false),
        this.renderDoneOrInstructions()
      ].join(" ");
      if (this.showMinError) {
        prompt += color.red(`You must select a minimum of ${this.minSelected} choices.`);
        this.showMinError = false;
      }
      prompt += this.renderOptions(this.filteredOptions);
      this.out.write(this.clear + prompt);
      this.clear = clear(prompt, this.out.columns);
    }
  }
  module.exports = AutocompleteMultiselectPrompt;
});

// node_modules/prompts/lib/elements/confirm.js
var require_confirm2 = __commonJS((exports, module) => {
  var color = require_kleur();
  var Prompt = require_prompt2();
  var { style, clear } = require_util2();
  var { erase, cursor } = require_src();

  class ConfirmPrompt extends Prompt {
    constructor(opts = {}) {
      super(opts);
      this.msg = opts.message;
      this.value = opts.initial;
      this.initialValue = !!opts.initial;
      this.yesMsg = opts.yes || "yes";
      this.yesOption = opts.yesOption || "(Y/n)";
      this.noMsg = opts.no || "no";
      this.noOption = opts.noOption || "(y/N)";
      this.render();
    }
    reset() {
      this.value = this.initialValue;
      this.fire();
      this.render();
    }
    exit() {
      this.abort();
    }
    abort() {
      this.done = this.aborted = true;
      this.fire();
      this.render();
      this.out.write(`
`);
      this.close();
    }
    submit() {
      this.value = this.value || false;
      this.done = true;
      this.aborted = false;
      this.fire();
      this.render();
      this.out.write(`
`);
      this.close();
    }
    _(c, key) {
      if (c.toLowerCase() === "y") {
        this.value = true;
        return this.submit();
      }
      if (c.toLowerCase() === "n") {
        this.value = false;
        return this.submit();
      }
      return this.bell();
    }
    render() {
      if (this.closed)
        return;
      if (this.firstRender)
        this.out.write(cursor.hide);
      else
        this.out.write(clear(this.outputText, this.out.columns));
      super.render();
      this.outputText = [
        style.symbol(this.done, this.aborted),
        color.bold(this.msg),
        style.delimiter(this.done),
        this.done ? this.value ? this.yesMsg : this.noMsg : color.gray(this.initialValue ? this.yesOption : this.noOption)
      ].join(" ");
      this.out.write(erase.line + cursor.to(0) + this.outputText);
    }
  }
  module.exports = ConfirmPrompt;
});

// node_modules/prompts/lib/elements/index.js
var require_elements2 = __commonJS((exports, module) => {
  module.exports = {
    TextPrompt: require_text2(),
    SelectPrompt: require_select2(),
    TogglePrompt: require_toggle2(),
    DatePrompt: require_date2(),
    NumberPrompt: require_number2(),
    MultiselectPrompt: require_multiselect2(),
    AutocompletePrompt: require_autocomplete2(),
    AutocompleteMultiselectPrompt: require_autocompleteMultiselect2(),
    ConfirmPrompt: require_confirm2()
  };
});

// node_modules/prompts/lib/prompts.js
var require_prompts2 = __commonJS((exports) => {
  var $ = exports;
  var el = require_elements2();
  var noop = (v) => v;
  function toPrompt(type, args, opts = {}) {
    return new Promise((res, rej) => {
      const p = new el[type](args);
      const onAbort = opts.onAbort || noop;
      const onSubmit = opts.onSubmit || noop;
      const onExit = opts.onExit || noop;
      p.on("state", args.onState || noop);
      p.on("submit", (x) => res(onSubmit(x)));
      p.on("exit", (x) => res(onExit(x)));
      p.on("abort", (x) => rej(onAbort(x)));
    });
  }
  $.text = (args) => toPrompt("TextPrompt", args);
  $.password = (args) => {
    args.style = "password";
    return $.text(args);
  };
  $.invisible = (args) => {
    args.style = "invisible";
    return $.text(args);
  };
  $.number = (args) => toPrompt("NumberPrompt", args);
  $.date = (args) => toPrompt("DatePrompt", args);
  $.confirm = (args) => toPrompt("ConfirmPrompt", args);
  $.list = (args) => {
    const sep = args.separator || ",";
    return toPrompt("TextPrompt", args, {
      onSubmit: (str) => str.split(sep).map((s) => s.trim())
    });
  };
  $.toggle = (args) => toPrompt("TogglePrompt", args);
  $.select = (args) => toPrompt("SelectPrompt", args);
  $.multiselect = (args) => {
    args.choices = [].concat(args.choices || []);
    const toSelected = (items) => items.filter((item) => item.selected).map((item) => item.value);
    return toPrompt("MultiselectPrompt", args, {
      onAbort: toSelected,
      onSubmit: toSelected
    });
  };
  $.autocompleteMultiselect = (args) => {
    args.choices = [].concat(args.choices || []);
    const toSelected = (items) => items.filter((item) => item.selected).map((item) => item.value);
    return toPrompt("AutocompleteMultiselectPrompt", args, {
      onAbort: toSelected,
      onSubmit: toSelected
    });
  };
  var byTitle = (input, choices) => Promise.resolve(choices.filter((item) => item.title.slice(0, input.length).toLowerCase() === input.toLowerCase()));
  $.autocomplete = (args) => {
    args.suggest = args.suggest || byTitle;
    args.choices = [].concat(args.choices || []);
    return toPrompt("AutocompletePrompt", args);
  };
});

// node_modules/prompts/lib/index.js
var require_lib = __commonJS((exports, module) => {
  var prompts = require_prompts2();
  var passOn = ["suggest", "format", "onState", "validate", "onRender", "type"];
  var noop = () => {};
  async function prompt(questions = [], { onSubmit = noop, onCancel = noop } = {}) {
    const answers = {};
    const override2 = prompt._override || {};
    questions = [].concat(questions);
    let answer, question, quit, name, type, lastPrompt;
    const getFormattedAnswer = async (question2, answer2, skipValidation = false) => {
      if (!skipValidation && question2.validate && question2.validate(answer2) !== true) {
        return;
      }
      return question2.format ? await question2.format(answer2, answers) : answer2;
    };
    for (question of questions) {
      ({ name, type } = question);
      if (typeof type === "function") {
        type = await type(answer, { ...answers }, question);
        question["type"] = type;
      }
      if (!type)
        continue;
      for (let key in question) {
        if (passOn.includes(key))
          continue;
        let value = question[key];
        question[key] = typeof value === "function" ? await value(answer, { ...answers }, lastPrompt) : value;
      }
      lastPrompt = question;
      if (typeof question.message !== "string") {
        throw new Error("prompt message is required");
      }
      ({ name, type } = question);
      if (prompts[type] === undefined) {
        throw new Error(`prompt type (${type}) is not defined`);
      }
      if (override2[question.name] !== undefined) {
        answer = await getFormattedAnswer(question, override2[question.name]);
        if (answer !== undefined) {
          answers[name] = answer;
          continue;
        }
      }
      try {
        answer = prompt._injected ? getInjectedAnswer(prompt._injected, question.initial) : await prompts[type](question);
        answers[name] = answer = await getFormattedAnswer(question, answer, true);
        quit = await onSubmit(question, answer, answers);
      } catch (err) {
        quit = !await onCancel(question, answers);
      }
      if (quit)
        return answers;
    }
    return answers;
  }
  function getInjectedAnswer(injected, deafultValue) {
    const answer = injected.shift();
    if (answer instanceof Error) {
      throw answer;
    }
    return answer === undefined ? deafultValue : answer;
  }
  function inject(answers) {
    prompt._injected = (prompt._injected || []).concat(answers);
  }
  function override(answers) {
    prompt._override = Object.assign({}, answers);
  }
  module.exports = Object.assign(prompt, { prompt, prompts, inject, override });
});

// node_modules/prompts/index.js
var require_prompts3 = __commonJS((exports, module) => {
  function isNodeLT(tar) {
    tar = (Array.isArray(tar) ? tar : tar.split(".")).map(Number);
    let i = 0, src = process.versions.node.split(".").map(Number);
    for (;i < tar.length; i++) {
      if (src[i] > tar[i])
        return false;
      if (tar[i] > src[i])
        return true;
    }
    return false;
  }
  module.exports = isNodeLT("8.6.0") ? require_dist() : require_lib();
});

// node_modules/chalk/source/vendor/ansi-styles/index.js
var ANSI_BACKGROUND_OFFSET = 10;
var wrapAnsi16 = (offset = 0) => (code) => `\x1B[${code + offset}m`;
var wrapAnsi256 = (offset = 0) => (code) => `\x1B[${38 + offset};5;${code}m`;
var wrapAnsi16m = (offset = 0) => (red, green, blue) => `\x1B[${38 + offset};2;${red};${green};${blue}m`;
var styles = {
  modifier: {
    reset: [0, 0],
    bold: [1, 22],
    dim: [2, 22],
    italic: [3, 23],
    underline: [4, 24],
    overline: [53, 55],
    inverse: [7, 27],
    hidden: [8, 28],
    strikethrough: [9, 29]
  },
  color: {
    black: [30, 39],
    red: [31, 39],
    green: [32, 39],
    yellow: [33, 39],
    blue: [34, 39],
    magenta: [35, 39],
    cyan: [36, 39],
    white: [37, 39],
    blackBright: [90, 39],
    gray: [90, 39],
    grey: [90, 39],
    redBright: [91, 39],
    greenBright: [92, 39],
    yellowBright: [93, 39],
    blueBright: [94, 39],
    magentaBright: [95, 39],
    cyanBright: [96, 39],
    whiteBright: [97, 39]
  },
  bgColor: {
    bgBlack: [40, 49],
    bgRed: [41, 49],
    bgGreen: [42, 49],
    bgYellow: [43, 49],
    bgBlue: [44, 49],
    bgMagenta: [45, 49],
    bgCyan: [46, 49],
    bgWhite: [47, 49],
    bgBlackBright: [100, 49],
    bgGray: [100, 49],
    bgGrey: [100, 49],
    bgRedBright: [101, 49],
    bgGreenBright: [102, 49],
    bgYellowBright: [103, 49],
    bgBlueBright: [104, 49],
    bgMagentaBright: [105, 49],
    bgCyanBright: [106, 49],
    bgWhiteBright: [107, 49]
  }
};
var modifierNames = Object.keys(styles.modifier);
var foregroundColorNames = Object.keys(styles.color);
var backgroundColorNames = Object.keys(styles.bgColor);
var colorNames = [...foregroundColorNames, ...backgroundColorNames];
function assembleStyles() {
  const codes = new Map;
  for (const [groupName, group] of Object.entries(styles)) {
    for (const [styleName, style] of Object.entries(group)) {
      styles[styleName] = {
        open: `\x1B[${style[0]}m`,
        close: `\x1B[${style[1]}m`
      };
      group[styleName] = styles[styleName];
      codes.set(style[0], style[1]);
    }
    Object.defineProperty(styles, groupName, {
      value: group,
      enumerable: false
    });
  }
  Object.defineProperty(styles, "codes", {
    value: codes,
    enumerable: false
  });
  styles.color.close = "\x1B[39m";
  styles.bgColor.close = "\x1B[49m";
  styles.color.ansi = wrapAnsi16();
  styles.color.ansi256 = wrapAnsi256();
  styles.color.ansi16m = wrapAnsi16m();
  styles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET);
  styles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET);
  styles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET);
  Object.defineProperties(styles, {
    rgbToAnsi256: {
      value(red, green, blue) {
        if (red === green && green === blue) {
          if (red < 8) {
            return 16;
          }
          if (red > 248) {
            return 231;
          }
          return Math.round((red - 8) / 247 * 24) + 232;
        }
        return 16 + 36 * Math.round(red / 255 * 5) + 6 * Math.round(green / 255 * 5) + Math.round(blue / 255 * 5);
      },
      enumerable: false
    },
    hexToRgb: {
      value(hex) {
        const matches = /[a-f\d]{6}|[a-f\d]{3}/i.exec(hex.toString(16));
        if (!matches) {
          return [0, 0, 0];
        }
        let [colorString] = matches;
        if (colorString.length === 3) {
          colorString = [...colorString].map((character) => character + character).join("");
        }
        const integer = Number.parseInt(colorString, 16);
        return [
          integer >> 16 & 255,
          integer >> 8 & 255,
          integer & 255
        ];
      },
      enumerable: false
    },
    hexToAnsi256: {
      value: (hex) => styles.rgbToAnsi256(...styles.hexToRgb(hex)),
      enumerable: false
    },
    ansi256ToAnsi: {
      value(code) {
        if (code < 8) {
          return 30 + code;
        }
        if (code < 16) {
          return 90 + (code - 8);
        }
        let red;
        let green;
        let blue;
        if (code >= 232) {
          red = ((code - 232) * 10 + 8) / 255;
          green = red;
          blue = red;
        } else {
          code -= 16;
          const remainder = code % 36;
          red = Math.floor(code / 36) / 5;
          green = Math.floor(remainder / 6) / 5;
          blue = remainder % 6 / 5;
        }
        const value = Math.max(red, green, blue) * 2;
        if (value === 0) {
          return 30;
        }
        let result = 30 + (Math.round(blue) << 2 | Math.round(green) << 1 | Math.round(red));
        if (value === 2) {
          result += 60;
        }
        return result;
      },
      enumerable: false
    },
    rgbToAnsi: {
      value: (red, green, blue) => styles.ansi256ToAnsi(styles.rgbToAnsi256(red, green, blue)),
      enumerable: false
    },
    hexToAnsi: {
      value: (hex) => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)),
      enumerable: false
    }
  });
  return styles;
}
var ansiStyles = assembleStyles();
var ansi_styles_default = ansiStyles;

// node_modules/chalk/source/vendor/supports-color/index.js
import process2 from "process";
import os from "os";
import tty from "tty";
function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process2.argv) {
  const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
  const position = argv.indexOf(prefix + flag);
  const terminatorPosition = argv.indexOf("--");
  return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
}
var { env } = process2;
var flagForceColor;
if (hasFlag("no-color") || hasFlag("no-colors") || hasFlag("color=false") || hasFlag("color=never")) {
  flagForceColor = 0;
} else if (hasFlag("color") || hasFlag("colors") || hasFlag("color=true") || hasFlag("color=always")) {
  flagForceColor = 1;
}
function envForceColor() {
  if ("FORCE_COLOR" in env) {
    if (env.FORCE_COLOR === "true") {
      return 1;
    }
    if (env.FORCE_COLOR === "false") {
      return 0;
    }
    return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);
  }
}
function translateLevel(level) {
  if (level === 0) {
    return false;
  }
  return {
    level,
    hasBasic: true,
    has256: level >= 2,
    has16m: level >= 3
  };
}
function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
  const noFlagForceColor = envForceColor();
  if (noFlagForceColor !== undefined) {
    flagForceColor = noFlagForceColor;
  }
  const forceColor = sniffFlags ? flagForceColor : noFlagForceColor;
  if (forceColor === 0) {
    return 0;
  }
  if (sniffFlags) {
    if (hasFlag("color=16m") || hasFlag("color=full") || hasFlag("color=truecolor")) {
      return 3;
    }
    if (hasFlag("color=256")) {
      return 2;
    }
  }
  if ("TF_BUILD" in env && "AGENT_NAME" in env) {
    return 1;
  }
  if (haveStream && !streamIsTTY && forceColor === undefined) {
    return 0;
  }
  const min = forceColor || 0;
  if (env.TERM === "dumb") {
    return min;
  }
  if (process2.platform === "win32") {
    const osRelease = os.release().split(".");
    if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
      return Number(osRelease[2]) >= 14931 ? 3 : 2;
    }
    return 1;
  }
  if ("CI" in env) {
    if (["GITHUB_ACTIONS", "GITEA_ACTIONS", "CIRCLECI"].some((key) => (key in env))) {
      return 3;
    }
    if (["TRAVIS", "APPVEYOR", "GITLAB_CI", "BUILDKITE", "DRONE"].some((sign) => (sign in env)) || env.CI_NAME === "codeship") {
      return 1;
    }
    return min;
  }
  if ("TEAMCITY_VERSION" in env) {
    return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
  }
  if (env.COLORTERM === "truecolor") {
    return 3;
  }
  if (env.TERM === "xterm-kitty") {
    return 3;
  }
  if ("TERM_PROGRAM" in env) {
    const version = Number.parseInt((env.TERM_PROGRAM_VERSION || "").split(".")[0], 10);
    switch (env.TERM_PROGRAM) {
      case "iTerm.app": {
        return version >= 3 ? 3 : 2;
      }
      case "Apple_Terminal": {
        return 2;
      }
    }
  }
  if (/-256(color)?$/i.test(env.TERM)) {
    return 2;
  }
  if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
    return 1;
  }
  if ("COLORTERM" in env) {
    return 1;
  }
  return min;
}
function createSupportsColor(stream, options = {}) {
  const level = _supportsColor(stream, {
    streamIsTTY: stream && stream.isTTY,
    ...options
  });
  return translateLevel(level);
}
var supportsColor = {
  stdout: createSupportsColor({ isTTY: tty.isatty(1) }),
  stderr: createSupportsColor({ isTTY: tty.isatty(2) })
};
var supports_color_default = supportsColor;

// node_modules/chalk/source/utilities.js
function stringReplaceAll(string, substring, replacer) {
  let index = string.indexOf(substring);
  if (index === -1) {
    return string;
  }
  const substringLength = substring.length;
  let endIndex = 0;
  let returnValue = "";
  do {
    returnValue += string.slice(endIndex, index) + substring + replacer;
    endIndex = index + substringLength;
    index = string.indexOf(substring, endIndex);
  } while (index !== -1);
  returnValue += string.slice(endIndex);
  return returnValue;
}
function stringEncaseCRLFWithFirstIndex(string, prefix, postfix, index) {
  let endIndex = 0;
  let returnValue = "";
  do {
    const gotCR = string[index - 1] === "\r";
    returnValue += string.slice(endIndex, gotCR ? index - 1 : index) + prefix + (gotCR ? `\r
` : `
`) + postfix;
    endIndex = index + 1;
    index = string.indexOf(`
`, endIndex);
  } while (index !== -1);
  returnValue += string.slice(endIndex);
  return returnValue;
}

// node_modules/chalk/source/index.js
var { stdout: stdoutColor, stderr: stderrColor } = supports_color_default;
var GENERATOR = Symbol("GENERATOR");
var STYLER = Symbol("STYLER");
var IS_EMPTY = Symbol("IS_EMPTY");
var levelMapping = [
  "ansi",
  "ansi",
  "ansi256",
  "ansi16m"
];
var styles2 = Object.create(null);
var applyOptions = (object, options = {}) => {
  if (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) {
    throw new Error("The `level` option should be an integer from 0 to 3");
  }
  const colorLevel = stdoutColor ? stdoutColor.level : 0;
  object.level = options.level === undefined ? colorLevel : options.level;
};
var chalkFactory = (options) => {
  const chalk = (...strings) => strings.join(" ");
  applyOptions(chalk, options);
  Object.setPrototypeOf(chalk, createChalk.prototype);
  return chalk;
};
function createChalk(options) {
  return chalkFactory(options);
}
Object.setPrototypeOf(createChalk.prototype, Function.prototype);
for (const [styleName, style] of Object.entries(ansi_styles_default)) {
  styles2[styleName] = {
    get() {
      const builder = createBuilder(this, createStyler(style.open, style.close, this[STYLER]), this[IS_EMPTY]);
      Object.defineProperty(this, styleName, { value: builder });
      return builder;
    }
  };
}
styles2.visible = {
  get() {
    const builder = createBuilder(this, this[STYLER], true);
    Object.defineProperty(this, "visible", { value: builder });
    return builder;
  }
};
var getModelAnsi = (model, level, type, ...arguments_) => {
  if (model === "rgb") {
    if (level === "ansi16m") {
      return ansi_styles_default[type].ansi16m(...arguments_);
    }
    if (level === "ansi256") {
      return ansi_styles_default[type].ansi256(ansi_styles_default.rgbToAnsi256(...arguments_));
    }
    return ansi_styles_default[type].ansi(ansi_styles_default.rgbToAnsi(...arguments_));
  }
  if (model === "hex") {
    return getModelAnsi("rgb", level, type, ...ansi_styles_default.hexToRgb(...arguments_));
  }
  return ansi_styles_default[type][model](...arguments_);
};
var usedModels = ["rgb", "hex", "ansi256"];
for (const model of usedModels) {
  styles2[model] = {
    get() {
      const { level } = this;
      return function(...arguments_) {
        const styler = createStyler(getModelAnsi(model, levelMapping[level], "color", ...arguments_), ansi_styles_default.color.close, this[STYLER]);
        return createBuilder(this, styler, this[IS_EMPTY]);
      };
    }
  };
  const bgModel = "bg" + model[0].toUpperCase() + model.slice(1);
  styles2[bgModel] = {
    get() {
      const { level } = this;
      return function(...arguments_) {
        const styler = createStyler(getModelAnsi(model, levelMapping[level], "bgColor", ...arguments_), ansi_styles_default.bgColor.close, this[STYLER]);
        return createBuilder(this, styler, this[IS_EMPTY]);
      };
    }
  };
}
var proto = Object.defineProperties(() => {}, {
  ...styles2,
  level: {
    enumerable: true,
    get() {
      return this[GENERATOR].level;
    },
    set(level) {
      this[GENERATOR].level = level;
    }
  }
});
var createStyler = (open, close, parent) => {
  let openAll;
  let closeAll;
  if (parent === undefined) {
    openAll = open;
    closeAll = close;
  } else {
    openAll = parent.openAll + open;
    closeAll = close + parent.closeAll;
  }
  return {
    open,
    close,
    openAll,
    closeAll,
    parent
  };
};
var createBuilder = (self, _styler, _isEmpty) => {
  const builder = (...arguments_) => applyStyle(builder, arguments_.length === 1 ? "" + arguments_[0] : arguments_.join(" "));
  Object.setPrototypeOf(builder, proto);
  builder[GENERATOR] = self;
  builder[STYLER] = _styler;
  builder[IS_EMPTY] = _isEmpty;
  return builder;
};
var applyStyle = (self, string) => {
  if (self.level <= 0 || !string) {
    return self[IS_EMPTY] ? "" : string;
  }
  let styler = self[STYLER];
  if (styler === undefined) {
    return string;
  }
  const { openAll, closeAll } = styler;
  if (string.includes("\x1B")) {
    while (styler !== undefined) {
      string = stringReplaceAll(string, styler.close, styler.open);
      styler = styler.parent;
    }
  }
  const lfIndex = string.indexOf(`
`);
  if (lfIndex !== -1) {
    string = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex);
  }
  return openAll + string + closeAll;
};
Object.defineProperties(createChalk.prototype, styles2);
var chalk = createChalk();
var chalkStderr = createChalk({ level: stderrColor ? stderrColor.level : 0 });
var source_default = chalk;

// src/index.ts
var import_prompts7 = __toESM(require_prompts3(), 1);

// src/commands/init.ts
var import_prompts6 = __toESM(require_prompts3(), 1);

// src/commands/init/typescript.ts
var import_prompts = __toESM(require_prompts3(), 1);
import { writeFile, exists, mkdir } from "fs/promises";
import path from "path";
import { join } from "path";

// src/templates/readme/typescript.ts
var generateTypeScriptReadme = (projectName, framework, database, useSrcDir, mongoDriver) => {
  const mongoDriverInfo = database === "mongodb" && mongoDriver ? `

### MongoDB Driver: ${mongoDriver === "mongoose" ? "Mongoose \uD83D\uDC00" : "MongoDB Native \uD83C\uDF43"}` : "";
  const schemaInfo = database === "mongodb" && mongoDriver === "mongoose" ? `${useSrcDir ? "\u2502   " : ""}\u2502       \u251C\u2500\u2500 [name].schema.ts    # Mongoose schema/model` : `${useSrcDir ? "\u2502   " : ""}\u2502       \u251C\u2500\u2500 [name].schema.ts    # Data schema/model`;
  const repoInfo = database === "mongodb" && mongoDriver === "mongoose" ? "" : `${useSrcDir ? "\u2502   " : ""}\u2502       \u251C\u2500\u2500 [name].repository.ts # Data access layer
`;
  return `# ${projectName}

## \uD83D\uDE80 Project Structure

\`\`\`
${projectName}/
${useSrcDir ? "\u251C\u2500\u2500 src/" : ""}
${useSrcDir ? "\u2502   " : ""}\u251C\u2500\u2500 config/             # Database configuration
${useSrcDir ? "\u2502   " : ""}\u2502   \u251C\u2500\u2500 db.json         # Database credentials
${useSrcDir ? "\u2502   " : ""}\u2502   \u2514\u2500\u2500 index.ts        # Config loader
${useSrcDir ? "\u2502   " : ""}\u251C\u2500\u2500 modules/            # Business modules
${useSrcDir ? "\u2502   " : ""}\u2502   \u2514\u2500\u2500 [module]/       # Specific module
${schemaInfo}
${repoInfo}${useSrcDir ? "\u2502   " : ""}\u2502       \u251C\u2500\u2500 [name].service.ts   # Business logic
${useSrcDir ? "\u2502   " : ""}\u2502       \u251C\u2500\u2500 [name].migrate.ts   # Database migrations
${useSrcDir ? "\u2502   " : ""}\u2502       \u251C\u2500\u2500 [name].seed.ts      # Data seeder
${useSrcDir ? "\u2502   " : ""}\u2502       \u2514\u2500\u2500 index.ts            # Controller/routes
${useSrcDir ? "\u2502   " : ""}\u251C\u2500\u2500 router.ts           # API routes configuration
${useSrcDir ? "\u2502   " : ""}\u251C\u2500\u2500 error.ts            # Error handling
${useSrcDir ? "\u2502   " : ""}\u2514\u2500\u2500 index.ts            # Application entry point
\u251C\u2500\u2500 data/                  # Sample data for seeding
\u2502   \u2514\u2500\u2500 [resources].json   # JSON data for each resource
\u251C\u2500\u2500 henotic.config.json    # Henotic configuration
\u2514\u2500\u2500 package.json           # Project dependencies
\`\`\`${mongoDriverInfo}

## \uD83D\uDEE0\uFE0F Commands

### Generate CRUD

Generate a new CRUD module:

\`\`\`bash
henotic generate Product name:string price:number description:string
\`\`\`

### Run the application

# Development mode
\`\`\`bash
henotic dev
\`\`\`

# Production mode
\`\`\`bash
henotic start
\`\`\`

### Build the application

\`\`\`bash
henotic build
\`\`\`

### Seed the database

\`\`\`bash
# Seed a specific module
henotic seed Product
\`\`\`

or

\`\`\`bash
# Seed all modules
henotic seed --all
\`\`\`

### Unseed the database

\`\`\`bash
# Remove seed data for a specific module
henotic unseed Product
\`\`\`

or

\`\`\`bash
# Remove seed data for all modules
henotic unseed --all
\`\`\`

### Database migrations

\`\`\`bash
# Run migrations for a specific module
henotic migrate Product
\`\`\`

or

\`\`\`bash
# Run migrations for all modules
henotic migrate --all
\`\`\`

### Drop tables

\`\`\`bash
# Drop tables for a specific module
henotic drop Product
\`\`\`

or

\`\`\`bash
# Drop tables for all modules
henotic drop --all
\`\`\`

## \uD83D\uDCDA API Endpoints

After generating a module, the following endpoints will be available:

- **GET** \`/api/[resources]\`: Get all resources
- **GET** \`/api/[resources]/:id\`: Get a resource by ID
- **POST** \`/api/[resources]\`: Create a new resource
- **PUT** \`/api/[resources]/:id\`: Update a resource
- **DELETE** \`/api/[resources]/:id\`: Delete a resource

## \uD83D\uDD27 Configuration

Edit the \`config/db.json\` file to configure your database connection and other settings.

${framework === "next" ? `## Next.js Specific

This project uses Next.js App Router. API routes are located in \`app/api/[resource]/route.ts\`.` : ""}
`;
};

// src/commands/init/typescript.ts
var promptsConfig = {
  onCancel: () => {
    console.log(source_default.yellow(`
\uD83D\uDED1 Operasi dibatalkan oleh pengguna`));
    process.exit(0);
  }
};
async function initTypeScript(projectName) {
  const frameworkChoices = [
    { title: "Express.js \uD83D\uDE80", value: "express" },
    { title: "Elysia (Bun) \uD83D\uDC30", value: "elysia", disabled: true },
    { title: "Hono \uD83D\uDD25", value: "hono" },
    { title: "Next.js \u23ED\uFE0F", value: "next" }
  ];
  let framework;
  if (frameworkChoices.length > 1) {
    const response = await import_prompts.default({
      type: "select",
      name: "framework",
      message: "Pilih framework:",
      choices: frameworkChoices
    }, promptsConfig);
    if (!response.framework) {
      console.log(source_default.yellow(`
\uD83D\uDED1 Operasi dibatalkan oleh pengguna`));
      process.exit(0);
    }
    framework = response.framework;
  } else {
    framework = frameworkChoices[0]?.value ?? "native";
    console.log(`Framework otomatis: ${framework}`);
  }
  let dbChoices = [
    { title: "PostgreSQL \uD83D\uDC18", value: "postgresql" },
    { title: "MariaDB \uD83D\uDC2C", value: "mariadb", disabled: true },
    { title: "SQLite \uD83D\uDCC1", value: "sqlite" },
    { title: "MongoDB \uD83C\uDF43", value: "mongodb" }
  ];
  if (framework === "next") {
    dbChoices = dbChoices.map((choice) => ({
      ...choice,
      disabled: choice.value !== "mongodb"
    }));
  }
  const dbResponse = await import_prompts.default({
    type: "select",
    name: "database",
    message: "Pilih database:",
    choices: dbChoices
  }, promptsConfig);
  if (!dbResponse.database) {
    console.log(source_default.yellow(`
\uD83D\uDED1 Operasi dibatalkan oleh pengguna`));
    process.exit(0);
  }
  const database = dbResponse.database;
  let mongoDriver;
  if (database === "mongodb") {
    const driverResponse = await import_prompts.default({
      type: "select",
      name: "driver",
      message: "Pilih MongoDB driver:",
      choices: [
        { title: "Mongoose \uD83D\uDC00 (ODM dengan schema)", value: "mongoose" },
        { title: "MongoDB Native \uD83C\uDF43 (driver resmi)", value: "mongodb" }
      ]
    }, promptsConfig);
    if (!driverResponse.driver) {
      console.log(source_default.yellow(`
\uD83D\uDED1 Operasi dibatalkan oleh pengguna`));
      process.exit(0);
    }
    mongoDriver = driverResponse.driver;
  }
  let useSrcDir = true;
  if (framework !== "next") {
    const dirResponse = await import_prompts.default({
      type: "confirm",
      name: "useSrcDir",
      message: "Gunakan folder src/ sebagai project directory?",
      initial: true
    }, promptsConfig);
    if (dirResponse.useSrcDir === undefined) {
      console.log(source_default.yellow(`
\uD83D\uDED1 Operasi dibatalkan oleh pengguna`));
      process.exit(0);
    }
    useSrcDir = dirResponse.useSrcDir;
  }
  if (projectName !== ".") {
    const dirExists = await exists(projectName);
    if (!dirExists) {
      await mkdir(projectName, { recursive: true });
    }
    process.chdir(projectName);
  }
  if (framework !== "next") {
    console.log(source_default.cyan(`
\uD83D\uDE80 Initializing TypeScript project...`));
    const initProcess = Bun.spawn(["bun", "init", "-y"], {
      stdio: ["ignore", "ignore", "ignore"]
    });
    await initProcess.exited;
    if (initProcess.exitCode !== 0) {
      throw new Error("Gagal menjalankan bun init -y");
    }
  }
  const config = {
    language: "typescript",
    framework,
    database,
    projectDir: useSrcDir ? "src" : ""
  };
  if (mongoDriver) {
    config.mongoDriver = mongoDriver;
  }
  if (framework === "next") {
    console.log(source_default.cyan(`
\uD83D\uDE80 Initializing Next.js project...`));
    const createProcess = Bun.spawn([
      "bun",
      "create",
      "next-app",
      ".",
      "--ts",
      "--eslint",
      "--tailwind",
      "--src-dir",
      "--app",
      "--turbopack",
      "--import-alias",
      "@/*",
      "--use-bun"
    ], {
      stdio: ["inherit", "inherit", "inherit"]
    });
    await createProcess.exited;
    if (createProcess.exitCode !== 0) {
      throw new Error("Gagal membuat Next.js project");
    }
    console.log(source_default.green("\u2705 Next.js project initialized!"));
  }
  console.log(source_default.cyan(`
\uD83D\uDCE6 Installing dependencies...`));
  const frameworkDeps = {
    express: {
      prod: ["express", "cors"],
      dev: ["@types/express", "@types/cors"]
    },
    elysia: {
      prod: ["elysia", "@elysiajs/cors", "@elysiajs/swagger"],
      dev: []
    },
    hono: {
      prod: ["hono", "@hono/zod-validator"],
      dev: []
    },
    next: {
      prod: [],
      dev: []
    }
  };
  const dbDeps = {
    postgresql: {
      prod: [],
      dev: []
    },
    mongodb: {
      prod: ["mongodb"],
      dev: []
    },
    mariadb: {
      prod: ["mariadb"],
      dev: []
    },
    sqlite: {
      prod: [],
      dev: []
    }
  };
  if (mongoDriver === "mongoose") {
    dbDeps.mongodb.prod.push("mongoose");
  }
  const prodDeps = [
    ...frameworkDeps[framework].prod,
    ...dbDeps[database].prod,
    "zod",
    "dotenv"
  ];
  const devDeps = [
    ...frameworkDeps[framework].dev,
    ...dbDeps[database].dev
  ];
  if (prodDeps.length > 0) {
    await Bun.spawn(["bun", "add", ...prodDeps], {
      stdio: ["inherit", "inherit", "inherit"]
    }).exited;
  }
  if (devDeps.length > 0) {
    await Bun.spawn(["bun", "add", "-d", ...devDeps], {
      stdio: ["inherit", "inherit", "inherit"]
    }).exited;
  }
  if (prodDeps.length > 0 || devDeps.length > 0) {
    console.log(source_default.green("\u2705 Dependencies terinstall!"));
  }
  const readmeContent = generateTypeScriptReadme(projectName === "." ? path.basename(process.cwd()) : projectName, framework, database, useSrcDir, mongoDriver);
  await writeFile(join(process.cwd(), "README.md"), readmeContent);
  await writeFile(join(process.cwd(), "henotic.config.json"), JSON.stringify(config, null, 2));
}

// src/commands/init/golang.ts
var import_prompts2 = __toESM(require_prompts3(), 1);
import { writeFile as writeFile2, exists as exists2, mkdir as mkdir2 } from "fs/promises";
import path2 from "path";
import { join as join2 } from "path";

// src/templates/readme/go.ts
var generateGoReadme = (projectName) => `# ${projectName}

## \uD83D\uDE80 Project Structure

\`\`\`
${projectName}/
\u251C\u2500\u2500 cmd/                  # Command-line applications
\u2502   \u251C\u2500\u2500 main/             # Main application
\u2502   \u2502   \u2514\u2500\u2500 main.go       # Entry point
\u2502   \u2514\u2500\u2500 seed/             # Database seeder
\u2502       \u2514\u2500\u2500 main.go       # Seeder entry point
\u251C\u2500\u2500 data/                 # Sample data for seeding
\u251C\u2500\u2500 internal/             # Private application code
\u2502   \u251C\u2500\u2500 module/           # Business modules
\u2502   \u2502   \u2514\u2500\u2500 [module]/     # Specific module
\u2502   \u2502       \u251C\u2500\u2500 entity/   # Domain models
\u2502   \u2502       \u251C\u2500\u2500 handler/  # HTTP handlers
\u2502   \u2502       \u2514\u2500\u2500 service/  # Business logic
\u2502   \u2502       
\u2502   \u2514\u2500\u2500 seed/             # Seed implementations
\u251C\u2500\u2500 pkg/                  # Public libraries
\u2502   \u251C\u2500\u2500 config/           # Configuration
\u2502   \u251C\u2500\u2500 database/         # Database connection
\u2502   \u251C\u2500\u2500 middleware/       # HTTP middleware
\u2502   \u2514\u2500\u2500 utils/            # Utility functions
\u251C\u2500\u2500 .env                  # Environment variables
\u251C\u2500\u2500 .gitignore            # Git ignore file
\u251C\u2500\u2500 go.mod                # Go modules
\u2514\u2500\u2500 go.sum                # Go dependencies checksum
\`\`\`

## \uD83D\uDEE0\uFE0F Commands

### Generate CRUD

Generate a new CRUD module:

\`\`\`bash
henotic generate Product name:string price:number description:text
\`\`\`

### Run the application

Before running the application, you need to install the dependencies:

\`\`\`bash
go mod tidy
\`\`\`

Then, you can run the application:

\`\`\`bash
go run cmd/main/main.go
\`\`\`

or

\`\`\`bash
henotic start
\`\`\`

### Run the application in development mode

\`\`\`bash
henotic dev
\`\`\`

### Seed the database

\`\`\`bash
go run cmd/seed/main.go
\`\`\`

or

\`\`\`bash
henotic seed
\`\`\`

## \uD83D\uDCDA API Endpoints

After generating a module, the following endpoints will be available:

- **GET** \`/api/[resources]\`: Get all resources
- **GET** \`/api/[resources]/:id\`: Get a resource by ID
- **POST** \`/api/[resources]\`: Create a new resource
- **PUT** \`/api/[resources]/:id\`: Update a resource
- **DELETE** \`/api/[resources]/:id\`: Delete a resource

## \uD83D\uDD27 Configuration

Edit the \`.env\` file to configure your database connection and other settings.
`;

// src/commands/init/golang.ts
var promptsConfig2 = {
  onCancel: () => {
    console.log(source_default.yellow(`
\uD83D\uDED1 Operasi dibatalkan oleh pengguna`));
    process.exit(0);
  }
};
async function initGolang(projectName) {
  const { database } = await import_prompts2.default({
    type: "select",
    name: "database",
    message: "Pilih database:",
    choices: [
      { title: "PostgreSQL \uD83D\uDC18", value: "postgresql" },
      { title: "MariaDB \uD83D\uDC2C", value: "mariadb" },
      { title: "SQLite \uD83D\uDCC1", value: "sqlite" },
      { title: "MongoDB \uD83C\uDF43", value: "mongodb", disabled: true }
    ]
  }, promptsConfig2);
  if (!database) {
    console.log(source_default.yellow(`
\uD83D\uDED1 Operasi dibatalkan oleh pengguna`));
    process.exit(0);
  }
  const config = {
    language: "golang",
    framework: "gin",
    database,
    projectDir: ""
  };
  console.log(source_default.cyan(`
\uD83D\uDE80 Initializing Go project...`));
  if (projectName !== ".") {
    const dirExists = await exists2(projectName);
    if (!dirExists) {
      await mkdir2(projectName, { recursive: true });
    }
    process.chdir(projectName);
  }
  const goModName = projectName === "." ? path2.basename(process.cwd()) : projectName;
  const goInitProcess = Bun.spawn(["go", "mod", "init", goModName], {
    stdio: ["inherit", "inherit", "inherit"]
  });
  await goInitProcess.exited;
  console.log(source_default.green("\u2705 Go module initialized!"));
  console.log(source_default.cyan(`
\uD83D\uDCE6 Installing Go dependencies...`));
  const baseDeps = [
    "github.com/gin-gonic/gin",
    "github.com/go-playground/validator/v10",
    "github.com/joho/godotenv"
  ];
  const dbDeps = {
    postgresql: [
      "gorm.io/gorm",
      "gorm.io/driver/postgres"
    ],
    mongodb: [
      "go.mongodb.org/mongo-driver"
    ],
    mariadb: [
      "gorm.io/gorm",
      "gorm.io/driver/mysql"
    ],
    sqlite: [
      "gorm.io/gorm",
      "gorm.io/driver/sqlite"
    ]
  };
  const goDeps = [...baseDeps, ...dbDeps[database] || []];
  for (const dep of goDeps) {
    console.log(source_default.cyan(`\uD83D\uDCE6 Installing ${dep}...`));
    const goGetProcess = Bun.spawn(["go", "get", dep], {
      stdio: ["inherit", "inherit", "inherit"]
    });
    await goGetProcess.exited;
    if (goGetProcess.exitCode !== 0) {
      console.log(source_default.yellow(`\u26A0\uFE0F Gagal menginstall ${dep}`));
    }
  }
  console.log(source_default.cyan("\uD83E\uDDF9 Cleaning up dependencies..."));
  await Bun.spawn(["go", "mod", "tidy"], {
    stdio: ["inherit", "inherit", "inherit"]
  }).exited;
  console.log(source_default.green("\u2705 Go dependencies terinstall!"));
  await mkdir2(join2(process.cwd(), "cmd", "main"), { recursive: true });
  await mkdir2(join2(process.cwd(), "cmd", "seed"), { recursive: true });
  await mkdir2(join2(process.cwd(), "internal", "module"), { recursive: true });
  await mkdir2(join2(process.cwd(), "internal", "seed"), { recursive: true });
  await mkdir2(join2(process.cwd(), "pkg", "config"), { recursive: true });
  await mkdir2(join2(process.cwd(), "pkg", "database"), { recursive: true });
  await mkdir2(join2(process.cwd(), "pkg", "middleware"), { recursive: true });
  await mkdir2(join2(process.cwd(), "pkg", "utils"), { recursive: true });
  await mkdir2(join2(process.cwd(), "data"), { recursive: true });
  const readmeContent = generateGoReadme(goModName);
  await writeFile2(join2(process.cwd(), "README.md"), readmeContent);
  const gitignoreContent = `# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, built with 'go test -c'
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# Dependency directories (remove the comment below to include it)
# vendor/

# Go workspace file
go.work

# Environment variables
.env

# Database files
*.db
`;
  await writeFile2(join2(process.cwd(), ".gitignore"), gitignoreContent);
  await writeFile2(join2(process.cwd(), "henotic.config.json"), JSON.stringify(config, null, 2));
}

// src/commands/init/java.ts
var import_prompts3 = __toESM(require_prompts3(), 1);
import { writeFile as writeFile3 } from "fs/promises";
import { join as join3 } from "path";
async function initJava(projectName) {
  const { database } = await import_prompts3.default({
    type: "select",
    name: "database",
    message: "Pilih database:",
    choices: [
      { title: "PostgreSQL \uD83D\uDC18", value: "postgresql" },
      { title: "MongoDB \uD83C\uDF43", value: "mongodb" },
      { title: "MariaDB \uD83D\uDC2C", value: "mariadb" },
      { title: "MySQL \uD83D\uDC2C", value: "mysql" },
      { title: "SQLite \uD83D\uDCC1", value: "sqlite" }
    ]
  });
  console.log(source_default.yellow("\u26A0\uFE0F Java initialization belum diimplementasikan"));
  const config = {
    language: "java",
    framework: "springboot",
    database,
    projectDir: ""
  };
  await writeFile3(join3(process.cwd(), "henotic.config.json"), JSON.stringify(config, null, 2));
}

// src/commands/init/php.ts
var import_prompts4 = __toESM(require_prompts3(), 1);
import { writeFile as writeFile4 } from "fs/promises";
import { join as join4 } from "path";
async function initPHP(projectName) {
  const { database } = await import_prompts4.default({
    type: "select",
    name: "database",
    message: "Pilih database:",
    choices: [
      { title: "PostgreSQL \uD83D\uDC18", value: "postgresql" },
      { title: "MongoDB \uD83C\uDF43", value: "mongodb" },
      { title: "MariaDB \uD83D\uDC2C", value: "mariadb" },
      { title: "MySQL \uD83D\uDC2C", value: "mysql" },
      { title: "SQLite \uD83D\uDCC1", value: "sqlite" }
    ]
  });
  console.log(source_default.yellow("\u26A0\uFE0F PHP initialization belum diimplementasikan"));
  const config = {
    language: "php",
    framework: "laravel",
    database,
    projectDir: ""
  };
  await writeFile4(join4(process.cwd(), "henotic.config.json"), JSON.stringify(config, null, 2));
}

// src/commands/init/rust.ts
var import_prompts5 = __toESM(require_prompts3(), 1);
import { writeFile as writeFile5, exists as exists3, mkdir as mkdir3 } from "fs/promises";
import { join as join5 } from "path";
import path3 from "path";

// src/templates/readme/rust.ts
function generateRustReadme(projectName, framework, database) {
  return `# ${projectName}

Aplikasi Rust menggunakan ${framework} dan ${database}.

## Struktur Folder

\`\`\`
.
\u251C\u2500\u2500 src/
\u2502   \u251C\u2500\u2500 api/           # API layer (router, middleware)
\u2502   \u251C\u2500\u2500 core/          # Core functionality (database, config)
\u2502   \u251C\u2500\u2500 modules/       # Business modules
\u2502   \u2502   \u2514\u2500\u2500 product/   # Product module
\u2502   \u2514\u2500\u2500 bin/           # Binary executables
\u251C\u2500\u2500 migrations/        # Database migrations
\u2514\u2500\u2500 data/              # Seed data
\`\`\`

## Menjalankan Aplikasi

### Setup Database

1. Pastikan ${database} sudah terinstall dan berjalan
2. Jalankan migrasi database:

\`\`\`bash
sqlx migrate run
\`\`\`

### Menjalankan Aplikasi

\`\`\`bash
cargo run
\`\`\`

### Menjalankan Seeder

\`\`\`bash
cargo run --bin seed
\`\`\`

## Pengembangan

### Membuat Migrasi Baru

\`\`\`bash
sqlx migrate add <nama_migrasi>
\`\`\`

### Build untuk Production

\`\`\`bash
cargo build --release
\`\`\`

## Dibuat dengan Henotic CLI \uD83D\uDE80
`;
}

// src/commands/init/rust.ts
var promptsConfig3 = {
  onCancel: () => {
    console.log(source_default.yellow(`
\uD83D\uDED1 Operasi dibatalkan oleh pengguna`));
    process.exit(0);
  }
};
async function initRust(projectName) {
  const { database } = await import_prompts5.default({
    type: "select",
    name: "database",
    message: "Pilih database:",
    choices: [
      { title: "PostgreSQL \uD83D\uDC18", value: "postgresql" },
      { title: "MariaDB \uD83D\uDC2C", value: "mariadb" },
      { title: "SQLite \uD83D\uDCC1", value: "sqlite" },
      { title: "MongoDB \uD83C\uDF43", value: "mongodb", disabled: true }
    ]
  }, promptsConfig3);
  if (!database) {
    console.log(source_default.yellow(`
\uD83D\uDED1 Operasi dibatalkan oleh pengguna`));
    process.exit(0);
  }
  const framework = "axum";
  console.log(source_default.cyan(`Framework: ${framework} \uD83D\uDD04`));
  console.log(source_default.cyan(`
\uD83D\uDE80 Initializing Rust project...`));
  if (projectName !== ".") {
    const dirExists = await exists3(projectName);
    if (!dirExists) {
      await mkdir3(projectName, { recursive: true });
    }
    process.chdir(projectName);
  }
  const cargoName = projectName === "." ? path3.basename(process.cwd()) : projectName;
  console.log(source_default.cyan(`\uD83D\uDCE6 Creating new Rust project: ${cargoName}...`));
  const cargoInitProcess = Bun.spawn(["cargo", "init", "--bin"], {
    stdio: ["inherit", "inherit", "inherit"]
  });
  await cargoInitProcess.exited;
  if (cargoInitProcess.exitCode !== 0) {
    console.log(source_default.red("\u274C Cargo init gagal. Pastikan Rust terinstall dengan benar."));
    process.exit(1);
  }
  console.log(source_default.green("\u2705 Rust project initialized!"));
  console.log(source_default.cyan("\uD83D\uDCE6 Installing SQLx CLI..."));
  const sqlxInstallProcess = Bun.spawn(["cargo", "install", "sqlx-cli"], {
    stdio: ["inherit", "inherit", "inherit"]
  });
  await sqlxInstallProcess.exited;
  if (sqlxInstallProcess.exitCode !== 0) {
    console.log(source_default.yellow("\u26A0\uFE0F SQLx CLI installation failed, you may need to install it manually"));
  } else {
    console.log(source_default.green("\u2705 SQLx CLI installed!"));
  }
  console.log(source_default.cyan("\uD83D\uDCE6 Adding dependencies to Cargo.toml..."));
  const baseDeps = [
    ["axum", "--features", "tokio"],
    ["tokio", "--features", "full"],
    ["serde", "--features", "derive"],
    ["serde_json"],
    ["chrono", "--features", "serde"],
    ["uuid", "--features", "v4,v7,serde"],
    ["dotenv"],
    ["anyhow"],
    ["thiserror"],
    ["async-trait"],
    ["validator", "--features", "derive"],
    ["hyper", "--features", "full"],
    ["include_dir"]
  ];
  const dbFeatures = {
    postgresql: "postgres,runtime-tokio-rustls,chrono,uuid,time",
    mariadb: "mysql,runtime-tokio-rustls,chrono",
    sqlite: "sqlite,migrate,runtime-tokio-rustls,uuid,chrono",
    mongodb: "mongodb"
  };
  for (const dep of baseDeps) {
    console.log(source_default.cyan(`\uD83D\uDCE6 Adding ${dep[0]}...`));
    const addProcess = Bun.spawn(["cargo", "add", ...dep], {
      stdio: ["inherit", "inherit", "inherit"]
    });
    await addProcess.exited;
    if (addProcess.exitCode !== 0) {
      console.log(source_default.yellow(`\u26A0\uFE0F Failed to add ${dep[0]}`));
    }
  }
  if (database !== "mongodb") {
    console.log(source_default.cyan(`\uD83D\uDCE6 Adding SQLx with ${database} features...`));
    const sqlxAddProcess = Bun.spawn(["cargo", "add", "sqlx", "--features", dbFeatures[database]], {
      stdio: ["inherit", "inherit", "inherit"]
    });
    await sqlxAddProcess.exited;
    if (sqlxAddProcess.exitCode !== 0) {
      console.log(source_default.yellow("\u26A0\uFE0F Failed to add SQLx"));
    }
  }
  console.log(source_default.green("\u2705 Dependencies added!"));
  console.log(source_default.cyan("\uD83D\uDCC1 Creating basic folder structure..."));
  await mkdir3(join5(process.cwd(), "src", "api"), { recursive: true });
  await mkdir3(join5(process.cwd(), "src", "core"), { recursive: true });
  await mkdir3(join5(process.cwd(), "src", "modules"), { recursive: true });
  await mkdir3(join5(process.cwd(), "src", "bin"), { recursive: true });
  await mkdir3(join5(process.cwd(), "migrations"), { recursive: true });
  await mkdir3(join5(process.cwd(), "data"), { recursive: true });
  const files = [
    {
      path: "src/api/mod.rs",
      content: "pub mod router;"
    },
    {
      path: "src/api/router.rs",
      content: ""
    },
    {
      path: "src/bin/seed.rs",
      content: ""
    },
    {
      path: "src/core/mod.rs",
      content: "pub mod db;"
    },
    {
      path: "src/core/db.rs",
      content: ""
    },
    {
      path: "src/modules/mod.rs",
      content: "// Modules will be added here"
    },
    {
      path: "src/lib.rs",
      content: `pub mod core;
pub mod api;
pub mod modules;
pub mod seed;`
    },
    {
      path: "src/seed.rs",
      content: ""
    }
  ];
  for (const file of files) {
    await writeFile5(join5(process.cwd(), file.path), file.content);
  }
  let envContent = "";
  if (database === "postgresql") {
    envContent = `DATABASE_URL=postgres://postgres:postgres@localhost:5432/${cargoName}
SERVER_HOST=0.0.0.0:3000
`;
  } else if (database === "mariadb") {
    envContent = `DATABASE_URL=mysql://root:root@localhost:3306/${cargoName}
SERVER_HOST=0.0.0.0:3000
`;
  } else if (database === "sqlite") {
    envContent = `DATABASE_URL=sqlite:${cargoName}.db
SERVER_HOST=0.0.0.0:3000
`;
  }
  await writeFile5(join5(process.cwd(), ".env"), envContent);
  let envexample = "";
  if (database === "postgresql") {
    envexample = `DATABASE_URL=postgres://postgres:postgres@localhost:5432/${cargoName}
SERVER_HOST=0.0.0.0:3000
`;
  } else if (database === "mariadb") {
    envexample = `DATABASE_URL=mysql://root:root@localhost:3306/${cargoName}
SERVER_HOST=0.0.0.0:3000
`;
  } else if (database === "sqlite") {
    envexample = `DATABASE_URL=sqlite:${cargoName}.db
SERVER_HOST=0.0.0.0:3000
`;
  }
  await writeFile5(join5(process.cwd(), ".env.example"), envexample);
  const gitignoreContent = `# Generated by Cargo
/target/

# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock

# These are backup files generated by rustfmt
**/*.rs.bk

# MSVC Windows builds of rustc generate these, which store debugging information
*.pdb

# Environment variables
.env

# Database files
*.db
`;
  await writeFile5(join5(process.cwd(), ".gitignore"), gitignoreContent);
  const readmeContent = generateRustReadme(cargoName, framework, database);
  await writeFile5(join5(process.cwd(), "README.md"), readmeContent);
  console.log(source_default.green("\u2705 Project structure created!"));
  const config = {
    language: "rust",
    framework,
    database,
    projectDir: "src"
  };
  await writeFile5(join5(process.cwd(), "henotic.config.json"), JSON.stringify(config, null, 2));
  const rimrafProcess = Bun.spawn(["rm", "-rf", ".git", ".github"], {
    stdio: ["inherit", "inherit", "inherit"]
  });
  await rimrafProcess.exited;
  console.log(source_default.green(`
\u2728 Rust project initialized successfully!`));
  console.log(source_default.cyan(`
\uD83D\uDCA1 Tip: Run the following commands to get started:`));
  console.log(source_default.yellow("1. sqlx migrate add create_products_table"));
  console.log(source_default.yellow("2. sqlx migrate run"));
  console.log(source_default.yellow("3. cargo run"));
}

// src/commands/init.ts
var promptsConfig4 = {
  onCancel: () => {
    console.log(source_default.yellow(`
\uD83D\uDED1 Operasi dibatalkan oleh pengguna`));
    process.exit(0);
  }
};
async function init(projectName) {
  const { language } = await import_prompts6.default({
    type: "select",
    name: "language",
    message: "Pilih bahasa pemrograman:",
    choices: [
      { title: "TypeScript \uD83D\uDC99", value: "typescript" },
      { title: "Golang \uD83E\uDDAB", value: "golang" },
      { title: "Java \u2615 (soon)", value: "java", disabled: true },
      { title: "PHP \uD83D\uDC18 (soon)", value: "php", disabled: true },
      { title: "Rust \uD83E\uDD80 (development)", value: "rust" }
    ]
  }, promptsConfig4);
  if (!language) {
    console.log(source_default.yellow(`
\uD83D\uDED1 Operasi dibatalkan oleh pengguna`));
    process.exit(0);
  }
  try {
    if (language === "typescript") {
      await initTypeScript(projectName);
    } else if (language === "golang") {
      await initGolang(projectName);
    } else if (language === "java") {
      await initJava(projectName);
    } else if (language === "php") {
      await initPHP(projectName);
    } else if (language === "rust") {
      await initRust(projectName);
    }
    console.log(source_default.green(`
\u2728 Project siap!`));
    console.log("Langkah selanjutnya:");
    if (language === "golang") {
      if (projectName !== ".") {
        console.log(`1. cd ${projectName}`);
        console.log("2. henotic generate <model>");
        console.log(source_default.cyan(`
\uD83D\uDCA1 Jangan lupa jalankan `) + source_default.yellow("go mod tidy") + source_default.cyan(" setelah generate model!"));
      } else {
        console.log("1. henotic generate <model>");
        console.log(source_default.cyan(`
\uD83D\uDCA1 Jangan lupa jalankan `) + source_default.yellow("go mod tidy") + source_default.cyan(" setelah generate model!"));
      }
    } else {
      if (projectName !== ".") {
        console.log(`1. cd ${projectName}`);
        console.log("2. henotic generate <model>");
      } else {
        console.log("1. henotic generate <model>");
      }
    }
  } catch (error) {
    const errorMessage = error instanceof Error ? error.message : String(error);
    console.error(source_default.red(`
\u274C Error: ${errorMessage}`));
    process.exit(1);
  }
}

// src/generators/utils/config.ts
import { join as join6 } from "path";
async function readConfig() {
  try {
    const configPath = join6(process.cwd(), "henotic.config.json");
    const configFile = await Bun.file(configPath).json();
    if (!configFile.language || !configFile.framework || !configFile.database) {
      throw new Error("Config harus ada language, framework, dan database! \uD83D\uDEA8");
    }
    const config = {
      language: configFile.language.toLowerCase(),
      framework: configFile.framework.toLowerCase(),
      database: configFile.database.toLowerCase(),
      projectDir: configFile.projectDir || ""
    };
    if (config.database === "mongodb") {
      return {
        ...config,
        mongoDriver: configFile.mongoDriver || "mongoose"
      };
    }
    return config;
  } catch (error) {
    throw new Error(`Gagal baca henotic.config.json: ${source_default.red(error.message)}`);
  }
}

// src/generators/utils/plural.ts
function pluralize(word) {
  const irregulars = {
    Category: "Categories",
    Property: "Properties",
    City: "Cities",
    Story: "Stories",
    Baby: "Babies",
    Person: "People",
    Man: "Men",
    Woman: "Women",
    Child: "Children",
    Tooth: "Teeth",
    Foot: "Feet",
    Mouse: "Mice",
    Belief: "Beliefs"
  };
  if (irregulars[word]) {
    return irregulars[word];
  }
  if (word.match(/[sxz]$/)) {
    return word + "es";
  }
  if (word.match(/[^aeiou]y$/)) {
    return word.replace(/y$/, "ies");
  }
  if (word.match(/o$/)) {
    return word + "es";
  }
  return word + "s";
}

// src/generators/utils/parser.ts
function parseFields(fields = []) {
  return fields.map((field) => {
    const [name, type] = field.split(":");
    if (!name || !type) {
      throw new Error(`Format field tidak valid: ${field}`);
    }
    const validTypes = ["string", "number", "boolean", "date", "text", "json", "enum"];
    if (!validTypes.includes(type)) {
      throw new Error(`Tipe data ${source_default.red(type)} tidak valid! Pilih dari: ${validTypes.join(", ")}`);
    }
    return { name, type };
  });
}

// src/generators/languages/typescript/constants/index.ts
var exports_constants = {};
__export(exports_constants, {
  nextStructure: () => nextStructure,
  kontasStructure: () => kontasStructure,
  honoStructure: () => honoStructure,
  expressStructure: () => expressStructure,
  elysiaStructure: () => elysiaStructure
});

// src/generators/languages/typescript/constants/structures/express.ts
var expressStructure = {
  getModulesPath: (projectDir) => `${projectDir}/modules`.replace(/\/+/g, "/"),
  getRoutersPath: (projectDir) => `${projectDir}/routers`.replace(/\/+/g, "/")
};
// src/generators/languages/typescript/constants/structures/elysia.ts
var elysiaStructure = {
  getModulesPath: (projectDir) => `${projectDir}/modules`.replace(/\/+/g, "/"),
  getRoutersPath: (projectDir) => `${projectDir}/routers`.replace(/\/+/g, "/")
};
// src/generators/languages/typescript/constants/structures/hono.ts
var honoStructure = {
  getModulesPath: (projectDir) => `${projectDir}/modules`.replace(/\/+/g, "/"),
  getRoutersPath: (projectDir) => `${projectDir}/routers`.replace(/\/+/g, "/")
};
// src/generators/languages/typescript/constants/structures/next.ts
var nextStructure = {
  getModulesPath: (projectDir) => `${projectDir}/modules`.replace(/\/+/g, "/"),
  getRoutersPath: (projectDir) => `${projectDir}/app/api`.replace(/\/+/g, "/")
};
// src/generators/languages/typescript/constants/structures/kontas.ts
var kontasStructure = {
  getModulesPath: (projectDir) => `${projectDir}/modules`.replace(/\/+/g, "/")
};
// src/generators/utils/json.template.ts
var generateJSONData = (name, fields, count = 10) => {
  const generateRandomValue = (type) => {
    switch (type) {
      case "string":
        const words = ["Henotic Labs", "Koding Fantasi", "Television", "Pemanasan Kaki"];
        return words[Math.floor(Math.random() * words.length)];
      case "number":
        return Math.floor(Math.random() * 1000);
      case "boolean":
        return Math.random() > 0.5;
      case "date":
        const start = new Date(2020, 1, 1);
        const end = new Date;
        return new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime())).toISOString();
      default:
        return null;
    }
  };
  const sampleData = Array.from({ length: count }, () => {
    const item = {
      ...Object.fromEntries(fields.map((field) => [
        field.name,
        generateRandomValue(field.type)
      ]))
    };
    return item;
  });
  return JSON.stringify(sampleData, null, 4);
};

// src/generators/languages/typescript/templates/framework/express/router.ts
var generateRouter = (name, pluralName) => `import { Router } from "express"
import { ${pluralName.toLowerCase()} } from "./modules/${pluralName.toLowerCase()}"

const router = Router()
    .use('/${pluralName.toLowerCase()}', ${pluralName.toLowerCase()})

export { router }`;

// src/generators/languages/typescript/templates/framework/elysia/router.ts
var generateRouter2 = (name, pluralName) => `import { Elysia } from 'elysia'
import { ${name} } from './modules/${pluralName.toLowerCase()}'

export const router = (app: Elysia) => {
    return app
        .group('/api', app => app
            .use(${name})
        )
}`;

// src/generators/languages/typescript/templates/framework/hono/router.ts
var generateRouter3 = (name, pluralName) => `import { Hono } from "hono"
import { ${pluralName.toLowerCase()} } from "./modules/${pluralName.toLowerCase()}"

const router = new Hono()
    .route('/${pluralName.toLowerCase()}', ${pluralName.toLowerCase()})

export { router }`;

// src/generators/languages/typescript/src/router.ts
async function updateRouter(name, framework, projectDir = "") {
  if (framework === "next") {
    console.log(source_default.yellow("\u26A0\uFE0F Skip generate router.ts (Next.js menggunakan App Router)"));
    return;
  }
  const cwd = process.cwd();
  const routerPath = `${cwd}/${projectDir ? projectDir + "/" : ""}router.ts`;
  const pluralName = pluralize(name);
  let content = "";
  try {
    content = await Bun.file(routerPath).text();
  } catch (error) {
    const generators = {
      express: generateRouter,
      elysia: generateRouter2,
      hono: generateRouter3
    };
    content = generators[framework](name, pluralName);
    await Bun.write(routerPath, content);
    return;
  }
  const imports = content.split(`

`)[0];
  let newImport = "";
  if (framework === "elysia") {
    newImport = `import { ${name} } from './modules/${pluralName.toLowerCase()}'`;
  } else {
    newImport = `import { ${pluralName.toLowerCase()} } from "./modules/${pluralName.toLowerCase()}"`;
  }
  const lines = content.split(`
`);
  const routes = lines.filter((line) => {
    if (framework === "elysia") {
      return line.includes(`.use(${name})`);
    } else if (framework === "express") {
      return line.includes(`.use('/${pluralName.toLowerCase()}', ${pluralName.toLowerCase()})`);
    } else {
      return line.includes(`.route('/${pluralName.toLowerCase()}', ${pluralName.toLowerCase()})`);
    }
  });
  if (routes.length > 0) {
    console.log(source_default.yellow(`\u26A0\uFE0F Route untuk ${name} sudah ada, skip update router...`));
    return;
  }
  if (!imports.includes(newImport)) {
    content = content.replace(imports, `${imports}
${newImport}`);
  }
  const routePatterns = {
    express: {
      search: "const router = Router()",
      replace: (name2, plural) => `const router = Router()
    .use('/${plural.toLowerCase()}', ${plural.toLowerCase()})`
    },
    elysia: {
      search: "app => app",
      replace: (name2) => `app => app
            .use(${name2})`
    },
    hono: {
      search: "const router = new Hono()",
      replace: (name2, plural) => `const router = new Hono()
    .route('/${plural.toLowerCase()}', ${plural.toLowerCase()})`
    }
  };
  const pattern = routePatterns[framework];
  const hasExistingRoutes = framework === "elysia" ? content.includes(".use(") : content.includes(framework === "express" ? ".use(" : ".route(");
  if (hasExistingRoutes) {
    const lastChainIndex = content.lastIndexOf(framework === "express" ? ".use(" : framework === "elysia" ? ".use(" : ".route(");
    const beforeChain = content.slice(0, lastChainIndex);
    const afterChain = content.slice(lastChainIndex);
    if (framework === "elysia") {
      content = `${beforeChain}
            .use(${name})${afterChain}`;
    } else {
      content = `${beforeChain}
    .${framework === "express" ? "use" : "route"}('/${pluralName.toLowerCase()}', ${pluralName.toLowerCase()})${afterChain}`;
    }
  } else {
    content = content.replace(pattern.search, pattern.replace(name, pluralName));
  }
  await Bun.write(routerPath, content);
}

// src/generators/languages/typescript/templates/framework/express/repository/mariadb.ts
var generateMariadbRepository = (name, pluralName) => `import { db } from "../../config";
import type { Create${name}, Update${name}, ${pluralName}, ${name}Id } from "./${name.toLowerCase()}.schema";
import { ${name} } from "./${name.toLowerCase()}.schema";

export type Result<T> = {
    success: boolean;
    message?: string;
    data: T | null;
    error?: unknown;
};

export class ${name}Repository {
    private readonly table = "${pluralName.toLowerCase()}";
    
    create = async (data: Create${name}): Promise<Result<${pluralName}>> => {
        try {
            const fields = Object.keys(data);
            const values = Object.values(data);
            const placeholders = values.map(() => '?').join(', ');
            
            const result = await db.query(\`
                INSERT INTO \${this.table} 
                (\${fields.join(', ')}, createdAt, updatedAt)
                VALUES (\${placeholders}, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
            \`, values);
            
            const newItem = await db.query(\`
                SELECT *
                FROM \${this.table} 
                WHERE id = ?
            \`, [result.insertId]);
            
            if (!newItem?.[0]) {
                throw new Error("Failed to create ${name.toLowerCase()}");
            }
            
            return {
                success: true,
                message: "${name} created successfully",
                data: new ${name}(newItem[0]) as ${pluralName}
            };
        } catch (error) {
            console.error('Error in create:', error);
            throw new Error(error instanceof Error ? error.message : "Failed to create ${name.toLowerCase()}");
        }
    };
    
    findAll = async (): Promise<Result<${pluralName}[]>> => {
        try {
            const rows = await db.query(\`
                SELECT * 
                FROM \${this.table}
            \`);
            
            return {
                success: true,
                data: rows.map((row: ${pluralName}) => new ${name}(row) as ${pluralName})
            };
        } catch (error) {
            console.error('Error in findAll:', error);
            throw new Error("Failed to fetch ${pluralName.toLowerCase()}");
        }
    };
    
    findById = async ({ id }: ${name}Id): Promise<Result<${pluralName}>> => {
        try {
            const row = await db.query(\`
                SELECT * 
                FROM \${this.table} 
                WHERE id = ?
            \`, [id]);
            
            if (!row?.[0]) {
                throw new Error("${name} not found");
            }
            
            return {
                success: true,
                data: new ${name}(row[0]) as ${pluralName}
            };
        } catch (error) {
            console.error('Error in findById:', error);
            throw new Error(error instanceof Error ? error.message : "Failed to find ${name.toLowerCase()}");
        }
    };
    
    update = async ({ id }: ${name}Id, data: Update${name}): Promise<Result<${pluralName}>> => {
        try {
            const fields = Object.keys(data);
            const values = Object.values(data);
            const setClause = fields
                .map(field => \`\${field} = ?\`)
                .join(', ');
            
            await db.query(\`
                UPDATE \${this.table}
                SET \${setClause}, updatedAt = CURRENT_TIMESTAMP
                WHERE id = ?
            \`, [...values, id]);
            
            const row = await db.query(\`
                SELECT * 
                FROM \${this.table} 
                WHERE id = ?
            \`, [id]);
            
            if (!row?.[0]) {
                throw new Error("${name} not found");
            }
            
            return {
                success: true,
                message: "${name} updated successfully",
                data: new ${name}(row[0]) as ${pluralName}
            };
        } catch (error) {
            console.error('Error in update:', error);
            throw new Error(error instanceof Error ? error.message : "Failed to update ${name.toLowerCase()}");
        }
    };
    
    delete = async ({ id }: ${name}Id): Promise<Result<${pluralName}>> => {
        try {
            const row = await db.query(\`
                SELECT * 
                FROM \${this.table} 
                WHERE id = ?
            \`, [id]);
            
            if (!row?.[0]) {
                throw new Error("${name} not found");
            }
            
            await db.query(\`
                DELETE FROM \${this.table} 
                WHERE id = ?
            \`, [id]);
            
            return {
                success: true,
                message: "${name} deleted successfully",
                data: new ${name}(row[0]) as ${pluralName}
            };
        } catch (error) {
            console.error('Error in delete:', error);
            throw new Error(error instanceof Error ? error.message : "Failed to delete ${name.toLowerCase()}");
        }
    };
}

// ! -- CUSTOM METHODS --
// You can add custom methods or business logic below this line
// For example: 
// export class Custom${name}Repository extends ${name}Repository {
//     customMethod = async () => {
//         // Your custom logic here
//     }
// }

export const Repository = new ${name}Repository()`;
// src/generators/languages/typescript/templates/framework/express/repository/postgresql.ts
var generatePostgresRepository = (name, pluralName) => `import { sql } from "../../config";
import type { Create${name}, Update${name}, ${pluralName}, ${name}Id } from "./${name.toLowerCase()}.schema";
import { ${name} } from "./${name.toLowerCase()}.schema";

export class ${name}Repository {
    private readonly table = "${pluralName.toLowerCase()}";
    
    create = async (data: Create${name}) => {
        try {
            const [result] = await sql\`
                INSERT INTO \${sql(this.table)} \${sql(data)}
                RETURNING *
            \`;
            return { 
                success: true, 
                message: "${name} created successfully",
                data: new ${name}(result) as ${pluralName} 
            };
        } catch (error) {
            console.error("Error creating ${name.toLowerCase()}:", error);
            throw error;
        }
    };
    
    findAll = async () => {
        try {
            const result = await sql\`SELECT * FROM \${sql(this.table)}\`;
            return { 
                success: true, 
                data: result.map((row: ${pluralName}) => new ${name}(row) as ${pluralName}) 
            };
        } catch (error) {
            console.error("Error finding all ${pluralName.toLowerCase()}:", error);
            throw error;
        }
    };
    
    findById = async ({ id }: ${name}Id) => {
        try {
            const [result] = await sql\`SELECT * FROM \${sql(this.table)} WHERE "id" = \${id}\`;
            if (!result) {
                throw new Error(\`${name} with id \${id} not found\`);
            }
            return { 
                success: true, 
                data: new ${name}(result) as ${pluralName} 
            };
        } catch (error) {
            console.error("Error finding ${name.toLowerCase()} by id:", error);
            throw error;
        }
    };
    
    update = async ({ id }: ${name}Id, data: Update${name}) => {
        try {
            const [result] = await sql\`
                UPDATE \${sql(this.table)}
                SET \${sql(data)}, "updatedAt" = NOW()
                WHERE "id" = \${id}
                RETURNING *
            \`;
            if (!result) {
                throw new Error(\`${name} with id \${id} not found\`);
            }
            return { 
                success: true, 
                message: "${name} updated successfully",
                data: new ${name}(result) as ${pluralName} 
            };
        } catch (error) {
            console.error("Error updating ${name.toLowerCase()}:", error);
            throw error;
        }
    };
    
    delete = async ({ id }: ${name}Id) => {
        try {
            return await sql.begin(async (tx) => {
                const [${name.toLowerCase()}] = await tx\`SELECT * FROM \${sql(this.table)} WHERE "id" = \${id}\`;
                if (!${name.toLowerCase()}) {
                    throw new Error(\`${name} with id \${id} not found\`);
                }
                await tx\`DELETE FROM \${sql(this.table)} WHERE "id" = \${id}\`;
                return { 
                    success: true, 
                    message: "${name} deleted successfully",
                    data: new ${name}(${name.toLowerCase()}) as ${pluralName} 
                };
            });
        } catch (error) {
            console.error("Error deleting ${name.toLowerCase()}:", error);
            throw error;
        }
    };
}

export const Repository = new ${name}Repository();`;
// src/generators/languages/typescript/templates/framework/express/repository/sqlite.ts
var generateSqliteRepository = (name, pluralName) => `import { db } from "../../config";
import type { Create${name}, Update${name}, ${pluralName}, ${name}Id } from "./${name.toLowerCase()}.schema";
import { ${name} } from "./${name.toLowerCase()}.schema";

// Tipe untuk data dari SQLite (timestamps sebagai string)
type SQLite${name} = Omit<${pluralName}, 'createdAt' | 'updatedAt'> & {
    createdAt: string;
    updatedAt: string;
};

export class ${name}Repository {
    private readonly table = "${pluralName.toLowerCase()}";
    
    private convertDates(${name.toLowerCase()}: SQLite${name}): ${pluralName} {
        return new ${name}({
            ...${name.toLowerCase()},
            createdAt: new Date(${name.toLowerCase()}.createdAt),
            updatedAt: new Date(${name.toLowerCase()}.updatedAt)
        }) as ${pluralName};
    }

    create = async (data: Create${name}) => {
        try {
            const fields = Object.keys(data);
            const columns = fields.join(', ');
            const placeholders = fields.map(f => \`$\${f}\`).join(', ');
            const params = Object.fromEntries(fields.map(f => [\`$\${f}\`, data[f as keyof Create${name}]]));
            
            const newItem = db.query(\`
                INSERT INTO \${this.table} 
                (\${columns}, createdAt, updatedAt)
                VALUES (\${placeholders}, datetime('now'), datetime('now'))
                RETURNING *;
            \`).get(params) as SQLite${name};
            
            if (!newItem) throw new Error("Failed to create ${name.toLowerCase()}");
            
            return {
                success: true,
                message: "${name} created successfully",
                data: this.convertDates(newItem)
            };
        } catch (error) {
            console.error("Error creating ${name.toLowerCase()}:", error);
            throw error;
        }
    };
    
    findAll = async () => {
        try {
            const query = db.query(\`SELECT * FROM \${this.table}\`);
            const rows = query.all() as SQLite${name}[];
            
            return {
                success: true,
                data: rows.map(this.convertDates)
            };
        } catch (error) {
            console.error("Error finding all ${pluralName.toLowerCase()}:", error);
            throw error;
        }
    };
    
    findById = async ({ id }: ${name}Id) => {
        try {
            const query = db.query(\`
                SELECT *
                FROM \${this.table} 
                WHERE id = $id
            \`);
            
            const row = query.get({ $id: id }) as SQLite${name} | undefined;
            
            if (!row) {
                throw new Error(\`${name} with id \${id} not found\`);
            }
            
            return {
                success: true,
                data: this.convertDates(row)
            };
        } catch (error) {
            console.error("Error finding ${name.toLowerCase()} by id:", error);
            throw error;
        }
    };
    
    update = async ({ id }: ${name}Id, data: Update${name}) => {
        try {
            const fields = Object.keys(data);
            const setClause = fields.map(f => \`\${f} = $\${f}\`).join(', ');
            const params = { $id: id, ...Object.fromEntries(fields.map(f => [\`$\${f}\`, data[f as keyof Update${name}]])) };
            
            db.query(\`
                UPDATE \${this.table}
                SET \${setClause}, updatedAt = datetime('now')
                WHERE id = $id
            \`).run(params);
            
            const row = db.query(\`SELECT * FROM \${this.table} WHERE id = $id\`)
                .get({ $id: id }) as SQLite${name};
            
            if (!row) throw new Error(\`${name} with id \${id} not found\`);
            
            return {
                success: true,
                message: "${name} updated successfully",
                data: this.convertDates(row)
            };
        } catch (error) {
            console.error("Error updating ${name.toLowerCase()}:", error);
            throw error;
        }
    };
    
    delete = async ({ id }: ${name}Id) => {
        try {
            const findQuery = db.query(\`
                SELECT *
                FROM \${this.table} 
                WHERE id = $id
            \`);
            
            const row = findQuery.get({ $id: id }) as SQLite${name} | undefined;
            
            if (!row) {
                throw new Error(\`${name} with id \${id} not found\`);
            }
            
            const deleteQuery = db.query(\`DELETE FROM \${this.table} WHERE id = $id\`);
            deleteQuery.run({ $id: id });
            
            return {
                success: true,
                message: "${name} deleted successfully",
                data: this.convertDates(row)
            };
        } catch (error) {
            console.error("Error deleting ${name.toLowerCase()}:", error);
            throw error;
        }
    };
}

// ! -- CUSTOM METHODS --
// You can add custom methods or business logic below this line
// For example: 
// export class Custom${name}Repository extends ${name}Repository {
//     customMethod = async () => {
//         // Your custom logic here
//     }
// }

export const Repository = new ${name}Repository()`;
// src/generators/languages/typescript/templates/framework/express/repository/mongodb.ts
var generateMongoRepository = (name, pluralName) => `import { ObjectId } from "mongodb";
import { db } from "../../config";
import type { Create${name}, Update${name}, ${pluralName}, ${name}Id } from "./${name.toLowerCase()}.schema";
import { ${name} } from "./${name.toLowerCase()}.schema";

export class ${name}Repository {
    private readonly collection = "${pluralName.toLowerCase()}";
    
    private getCollection = async () => {
        return db.collection(this.collection);
    };
    
    create = async (data: Create${name}) => {
        try {
            const doc = {
                ...data,
                createdAt: new Date(),
                updatedAt: new Date()
            };
            
            const collection = await this.getCollection();
            const result = await collection.insertOne(doc);
            
            if (!result.acknowledged) {
                throw new Error("Failed to create ${name.toLowerCase()}");
            }
            
            return {
                success: true,
                message: "${name} created successfully",
                data: new ${name}({ ...doc, _id: result.insertedId }) as ${pluralName}
            };
        } catch (error) {
            console.error("Error creating ${name.toLowerCase()}:", error);
            throw error;
        }
    };

    findAll = async () => {
        try {
            const collection = await this.getCollection();
            const docs = await collection
                .find({})
                .sort({ _id: -1 })
                .toArray() as ${pluralName}[];
                
            return {
                success: true,
                data: docs.map(doc => new ${name}(doc) as ${pluralName})
            };
        } catch (error) {
            console.error("Error finding all ${pluralName.toLowerCase()}:", error);
            throw error;
        }
    };

    findById = async ({ id }: ${name}Id) => {
        try {
            const collection = await this.getCollection();
            const doc = await collection
                .findOne({ _id: new ObjectId(id) }) as ${pluralName} | null;
                
            if (!doc) {
                throw new Error(\`${name} with id \${id} not found\`);
            }
            
            return {
                success: true,
                data: new ${name}(doc) as ${pluralName}
            };
        } catch (error) {
            console.error("Error finding ${name.toLowerCase()} by id:", error);
            throw error;
        }
    };

    update = async ({ id }: ${name}Id, data: Update${name}) => {
        try {
            const collection = await this.getCollection();
            const result = await collection
                .findOneAndUpdate(
                    { _id: new ObjectId(id) },
                    { 
                        $set: {
                            ...data,
                            updatedAt: new Date()
                        }
                    },
                    { returnDocument: 'after' }
                );
            
            if (!result) {
                throw new Error(\`${name} with id \${id} not found\`);
            }
            
            return {
                success: true,
                message: "${name} updated successfully",
                data: new ${name}(result) as ${pluralName}
            };
        } catch (error) {
            console.error("Error updating ${name.toLowerCase()}:", error);
            throw error;
        }
    };

    delete = async ({ id }: ${name}Id) => {
        try {
            const collection = await this.getCollection();
            const doc = await collection
                .findOne({ _id: new ObjectId(id) });
                
            if (!doc) {
                throw new Error(\`${name} with id \${id} not found\`);
            }

            await collection.deleteOne({ _id: new ObjectId(id) });
            
            return {
                success: true,
                message: "${name} deleted successfully",
                data: new ${name}(doc) as ${pluralName}
            };
        } catch (error) {
            console.error("Error deleting ${name.toLowerCase()}:", error);
            throw error;
        }
    };
}

// ! -- CUSTOM METHODS --
// You can add custom methods or business logic below this line
// For example: 
// export class Custom${name}Repository extends ${name}Repository {
//     customMethod = async () => {
//         // Your custom logic here
//     }
// }

export const Repository = new ${name}Repository();`;
// src/generators/languages/typescript/templates/framework/express/schema/mongoose.ts
var generateMongooseSchema = (name, fields) => {
  const mapTypeToMongoose = (zodType) => {
    const typeMap = {
      string: "String",
      number: "Number",
      boolean: "Boolean",
      date: "Date",
      array: "Array",
      object: "Object"
    };
    return typeMap[zodType] || "String";
  };
  return `import { z } from "zod";
import mongoose from "mongoose";

// Definisi schema mongoose
const ${name.toLowerCase()}Schema = new mongoose.Schema({
    ${fields.map((f) => `${f.name}: {
        type: ${mapTypeToMongoose(f.type)},
        required: true
    }`).join(`,
    `)}
}, {
    timestamps: true
});

// Model mongoose
export const ${name} = mongoose.model('${name}', ${name.toLowerCase()}Schema);

// Zod schema untuk validasi
const ${name}Schema = z.object({
    ${fields.map((f) => `${f.name}: z.${f.type}()`).join(`,
    `)}
})

const TimestampSchema = z.object({
    createdAt: z.date(),
    updatedAt: z.date()
})

export const ${name}IdValidate = z.object({
    id: z.string().refine((val) => mongoose.Types.ObjectId.isValid(val), {
        message: "ID harus berupa ObjectId yang valid"
    })
})

export const Create${name}Validate = ${name}Schema

export const ${pluralize(name)}Validate = ${name}Schema
    .merge(z.object({
        _id: z.instanceof(mongoose.Types.ObjectId).or(z.string())
    }))
    .merge(TimestampSchema)

export const Update${name}Validate = ${name}Schema.partial()

export type Create${name} = z.infer<typeof Create${name}Validate>
export type ${pluralize(name)} = z.infer<typeof ${pluralize(name)}Validate>
export type Update${name} = z.infer<typeof Update${name}Validate>
export type ${name}Id = z.infer<typeof ${name}IdValidate>
`;
};
// src/generators/languages/typescript/templates/framework/express/schema/mongodb.ts
var generateMongodbSchema = (name, fields) => `import { z } from "zod"
import { ObjectId } from "mongodb"

export class ${name} {
    constructor(data: Partial<${pluralize(name)}>) {
        Object.assign(this, data)
    }
}

const ${name}Schema = z.object({
    ${fields.map((f) => `${f.name}: z.${f.type}()`).join(`,
    `)}
})

const WithIdSchema = z.object({
    _id: z.instanceof(ObjectId)
})

const TimestampSchema = z.object({
    createdAt: z.date(),
    updatedAt: z.date()
})

export const ${name}IdValidate = z.object({
    id: z.string().regex(/^[0-9a-fA-F]{24}$/, "Invalid ObjectId format")
})

export const Create${name}Validate = ${name}Schema

export const ${pluralize(name)}Validate = ${name}Schema
    .merge(WithIdSchema)
    .merge(TimestampSchema)

export const Update${name}Validate = ${name}Schema.partial()

export type Create${name} = z.infer<typeof Create${name}Validate>
export type ${pluralize(name)} = z.infer<typeof ${pluralize(name)}Validate>
export type Update${name} = z.infer<typeof Update${name}Validate>
export type ${name}Id = z.infer<typeof ${name}IdValidate>
`;
// src/generators/languages/typescript/templates/framework/express/schema/sql.ts
var generateSqlSchema = (name, fields) => `import { z } from "zod"

export class ${name} {
    constructor(data: Partial<${pluralize(name)}>) {
        Object.assign(this, data)
    }
}

const ${name}Schema = z.object({
    ${fields.map((f) => `${f.name}: z.${f.type}()`).join(`,
    `)}
})

const WithIdSchema = z.object({
    id: z.number()
})

const TimestampSchema = z.object({
    createdAt: z.date(),
    updatedAt: z.date()
})

export const ${name}IdValidate = z.object({
    id: z.coerce.number().positive("ID harus positif")
})

export const Create${name}Validate = ${name}Schema

export const ${pluralize(name)}Validate = ${name}Schema
    .merge(WithIdSchema)
    .merge(TimestampSchema)

export const Update${name}Validate = ${name}Schema.partial()

export type Create${name} = z.infer<typeof Create${name}Validate>
export type ${pluralize(name)} = z.infer<typeof ${pluralize(name)}Validate>
export type Update${name} = z.infer<typeof Update${name}Validate>
export type ${name}Id = z.infer<typeof ${name}IdValidate>
`;
// src/generators/languages/typescript/templates/framework/express/service/mongoose.ts
var generateMongooseService = (name, pluralName) => `import { db } from '../../config';
import type { Create${name}, Update${name}, ${pluralName} } from './${name.toLowerCase()}.schema';
import { ${name}, Create${name}Validate, Update${name}Validate } from './${name.toLowerCase()}.schema';

export type Result<T> = {
    success: boolean;
    message?: string;
    data: T | null;
};

export class ${name}Service {
    create = async (data: Create${name}): Promise<Result<${pluralName}>> => {
        try {
            const validatedData = Create${name}Validate.parse(data);
            
            const ${name.toLowerCase()} = new ${name}(validatedData);
            const saved${name} = await ${name.toLowerCase()}.save();
            
            return {
                success: true,
                message: "${name} created successfully",
                data: saved${name}
            };
        } catch (error) {
            console.error("Error creating ${name.toLowerCase()}:", error);
            throw error;
        }
    };

    getAll = async (): Promise<Result<${pluralName}[]>> => {
        try {
            const ${pluralName.toLowerCase()} = await ${name}.find();
                
            return {
                success: true,
                data: ${pluralName.toLowerCase()}
            };
        } catch (error) {
            console.error("Error getting all ${pluralName.toLowerCase()}:", error);
            throw error;
        }
    };

    getById = async (id: string): Promise<Result<${pluralName}>> => {
        try {
            if (!db.Types.ObjectId.isValid(id)) {
                throw new Error("Invalid ${name.toLowerCase()} ID");
            }
            
            const ${name.toLowerCase()} = await ${name}.findById(id);
                
            if (!${name.toLowerCase()}) {
                throw new Error("${name} not found");
            }
            
            return {
                success: true,
                data: ${name.toLowerCase()}
            };
        } catch (error) {
            console.error(\`Error getting ${name.toLowerCase()} with ID \${id}:\`, error);
            throw error;
        }
    };

    update = async (id: string, data: Update${name}): Promise<Result<${pluralName}>> => {
        try {
            if (!db.Types.ObjectId.isValid(id)) {
                throw new Error("Invalid ${name.toLowerCase()} ID");
            }
            
            // Validasi data dengan Zod
            const validatedData = Update${name}Validate.parse(data);
            
            const updated${name} = await ${name}.findByIdAndUpdate(
                id,
                { ...validatedData },
                { new: true }
            );
            
            if (!updated${name}) {
                throw new Error("${name} not found");
            }
            
            return {
                success: true,
                message: "${name} updated successfully",
                data: updated${name}
            };
        } catch (error) {
            console.error(\`Error updating ${name.toLowerCase()} with ID \${id}:\`, error);
            throw error;
        }
    };

    delete = async (id: string): Promise<Result<${pluralName}>> => {
        try {
            if (!db.Types.ObjectId.isValid(id)) {
                throw new Error("Invalid ${name.toLowerCase()} ID");
            }
            
            const deleted${name} = await ${name}.findByIdAndDelete(id);
                
            if (!deleted${name}) {
                throw new Error("${name} not found");
            }
            
            return {
                success: true,
                message: "${name} deleted successfully",
                data: deleted${name}
            };
        } catch (error) {
            console.error(\`Error deleting ${name.toLowerCase()} with ID \${id}:\`, error);
            throw error;
        }
    };
}

export const Service = new ${name}Service();
`;
// src/generators/languages/typescript/templates/framework/express/service/mongodb.ts
var generateMongodbService = (name, pluralName) => `import { Repository as ${name} } from "./${name.toLowerCase()}.repository";
import type { Create${name}, Update${name} } from "./${name.toLowerCase()}.schema";
import { 
    Create${name}Validate, 
    Update${name}Validate,
    ${name}IdValidate
} from "./${name.toLowerCase()}.schema";

export const Service = {
    create: async (data: Create${name}) => {
        try {
            const validated = Create${name}Validate.parse(data);
            return await ${name}.create(validated);
        } catch (error) {
            console.error("Service error creating ${name.toLowerCase()}:", error);
            throw error;
        }
    },
    
    getAll: async () => {
        try {
            return await ${name}.findAll();
        } catch (error) {
            console.error("Service error getting all ${pluralName.toLowerCase()}:", error);
            throw error;
        }
    },
    
    getById: async (id: string) => {
        try {
            const { id: validId } = ${name}IdValidate.parse({ id });
            return await ${name}.findById({ id: validId });
        } catch (error) {
            console.error("Service error getting ${name.toLowerCase()} by id:", error);
            throw error;
        }
    },
    
    update: async (id: string, data: Update${name}) => {
        try {
            const { id: validId } = ${name}IdValidate.parse({ id });
            const validated = Update${name}Validate.parse(data);
            return await ${name}.update({ id: validId }, validated);
        } catch (error) {
            console.error("Service error updating ${name.toLowerCase()}:", error);
            throw error;
        }
    },
    
    delete: async (id: string) => {
        try {
            const { id: validId } = ${name}IdValidate.parse({ id });
            return await ${name}.delete({ id: validId });
        } catch (error) {
            console.error("Service error deleting ${name.toLowerCase()}:", error);
            throw error;
        }
    }
};`;
// src/generators/languages/typescript/templates/framework/express/service/sql.ts
var generateSqlService = (name, pluralName) => `import { Repository as ${name} } from "./${name.toLowerCase()}.repository";
import type { Create${name}, Update${name} } from "./${name.toLowerCase()}.schema";
import { 
    Create${name}Validate, 
    Update${name}Validate,
    ${name}IdValidate
} from "./${name.toLowerCase()}.schema";

export const Service = {
    create: async (data: Create${name}) => {
        try {
            const validated = Create${name}Validate.parse(data);
            return await ${name}.create(validated);
        } catch (error) {
            console.error("Service error creating ${name.toLowerCase()}:", error);
            throw error;
        }
    },
    
    getAll: async () => {
        try {
            return await ${name}.findAll();
        } catch (error) {
            console.error("Service error getting all ${pluralName.toLowerCase()}:", error);
            throw error;
        }
    },
    
    getById: async (id: string) => {
        try {
            const { id: validId } = ${name}IdValidate.parse({ id: Number(id) });
            return await ${name}.findById({ id: validId });
        } catch (error) {
            console.error("Service error getting ${name.toLowerCase()} by id:", error);
            throw error;
        }
    },
    
    update: async (id: string, data: Update${name}) => {
        try {
            const { id: validId } = ${name}IdValidate.parse({ id: Number(id) });
            const validated = Update${name}Validate.parse(data);
            return await ${name}.update({ id: validId }, validated);
        } catch (error) {
            console.error("Service error updating ${name.toLowerCase()}:", error);
            throw error;
        }
    },
    
    delete: async (id: string) => {
        try {
            const { id: validId } = ${name}IdValidate.parse({ id: Number(id) });
            return await ${name}.delete({ id: validId });
        } catch (error) {
            console.error("Service error deleting ${name.toLowerCase()}:", error);
            throw error;
        }
    }
};`;
// src/generators/languages/typescript/templates/framework/express/controller.ts
var generateController = (name, pluralName) => `import { Router } from "express";
import { Service as ${name} } from "./${name.toLowerCase()}.service";

export const ${pluralName.toLowerCase()} = Router()   
    .post("/", async (req, res, next) => {
        try {
            const result = await ${name}.create(req.body);
            res.status(201).json(result);
        } catch (error) {
            next(error);
        }
    })
    .get("/", async (_req, res, next) => {
        try {
            const result = await ${name}.getAll();
            res.status(200).json(result);
        } catch (error) {
            next(error);
        }
    })
    .get("/:id", async (req, res, next) => {
        try {
            const { id } = req.params;
            const result = await ${name}.getById(id);
            res.status(200).json(result);
        } catch (error) {
            next(error);
        }
    })
    .put("/:id", async (req, res, next) => {
        try {
            const { id } = req.params;
            const result = await ${name}.update(id, req.body);
            res.status(200).json(result);
        } catch (error) {
            next(error);
        }
    })
    .delete("/:id", async (req, res, next) => {
        try {
            const { id } = req.params;
            const result = await ${name}.delete(id);
            res.status(200).json(result);
        } catch (error) {
            next(error);
        }
    });`;
// src/generators/languages/typescript/templates/framework/express/server.ts
var generateServer = () => `import express from "express";
import cors from "cors";
import { router } from "./router";
import { errorHandler } from "./error";

const app = express();

app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cors());

app.use('/api', router);
app.use(errorHandler);

app.listen(3000, () => {
    console.log("Server is running on port 3000 \uD83D\uDE80");
});

export default app;`;
// src/generators/languages/typescript/templates/framework/express/error.ts
var generateError = () => `import type { Request, Response, NextFunction, ErrorRequestHandler } from "express";
import { ZodError } from "zod";

type ErrorResult = {
    success: boolean;
    message?: string;
    data: null;
    errors?: {
        field: string;
        message: string;
    }[];
};

type HttpStatus = 
    | 400 // Bad Request
    | 401 // Unauthorized
    | 403 // Forbidden
    | 404 // Not Found
    | 405 // Method Not Allowed
    | 408 // Request Timeout
    | 409 // Conflict
    | 422 // Unprocessable Entity
    | 429 // Too Many Requests
    | 500 // Internal Server Error
    | 502 // Bad Gateway
    | 503 // Service Unavailable
    | 504 // Gateway Timeout

export const errorHandler: ErrorRequestHandler = (
    error: Error | ZodError,
    _req: Request,
    res: Response,
    _next: NextFunction
): void => {
    console.error("Error:", error);
    
    let status: HttpStatus = 500;
    let response: ErrorResult = {
        success: false,
        message: "Terjadi kesalahan internal server",
        data: null
    };
    
    // Handle specific errors (400, 404, etc)
    if (error instanceof ZodError) {
        status = 400;
        response = {
            success: false,
            message: "Data tidak valid",
            data: null,
            errors: error.errors.map(e => ({
                field: e.path.join('.'),
                message: e.message
            }))
        };
    } else if (error.message.toLowerCase().includes('not found')) {
        status = 404;
        response = {
            success: false,
            message: error.message,
            data: null
        };
    } else if (error.message.toLowerCase().includes('invalid') || error.message.toLowerCase().includes('failed')) {
        status = 400;
        response = {
            success: false,
            message: error.message,
            data: null
        };
    } else if (error.message.toLowerCase().includes('unauthorized')) {
        status = 401;
        response = {
            success: false,
            message: error.message,
            data: null
        };
    } else if (error.message.toLowerCase().includes('forbidden')) {
        status = 403;
        response = {
            success: false,
            message: error.message,
            data: null
        };
    }
    
    res.status(status).json(response);
}
`;
// src/generators/languages/typescript/templates/framework/elysia/repository/mariadb.ts
var generateMariadbRepository2 = (name, pluralName) => `import { db } from "../../config";
import type { Create${name}, Update${name}, ${pluralName}, ${name}Id } from "./${name.toLowerCase()}.schema";

export type Result<T> = {
    success: boolean;
    message?: string;
    data: T | null;
    error?: unknown;
};

export class ${name}Repository {
    private readonly table = "${pluralName.toLowerCase()}";
    
    create = async (data: Create${name}): Promise<Result<${pluralName}>> => {
        try {
            const fields = Object.keys(data);
            const values = Object.values(data);
            const placeholders = values.map(() => '?').join(', ');
            
            const result = await db.query(\`
                INSERT INTO \${this.table} 
                (\${fields.join(', ')}, createdAt, updatedAt)
                VALUES (\${placeholders}, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
            \`, values);
            
            const newItem = await db.query(\`
                SELECT *
                FROM \${this.table} 
                WHERE id = ?
            \`, [result.insertId]);
            
            if (!newItem?.[0]) {
                throw new Error("Failed to create ${name.toLowerCase()}");
            }
            
            return {
                success: true,
                message: "${name} created successfully",
                data: newItem[0]
            };
        } catch (error) {
            console.error('Error in create:', error);
            throw new Error(error instanceof Error ? error.message : "Failed to create ${name.toLowerCase()}");
        }
    };
    
    findAll = async (): Promise<Result<${pluralName}[]>> => {
        try {
            const rows = await db.query(\`
                SELECT * 
                FROM \${this.table}
            \`);
            
            return {
                success: true,
                data: rows
            };
        } catch (error) {
            console.error('Error in findAll:', error);
            throw new Error("Failed to fetch ${pluralName.toLowerCase()}");
        }
    };
    
    findById = async ({ id }: ${name}Id): Promise<Result<${pluralName}>> => {
        try {
            const row = await db.query(\`
                SELECT * 
                FROM \${this.table} 
                WHERE id = ?
            \`, [id]);
            
            if (!row?.[0]) {
                throw new Error("${name} not found");
            }
            
            return {
                success: true,
                data: row[0]
            };
        } catch (error) {
            console.error('Error in findById:', error);
            throw new Error(error instanceof Error ? error.message : "Failed to find ${name.toLowerCase()}");
        }
    };
    
    update = async ({ id }: ${name}Id, data: Update${name}): Promise<Result<${pluralName}>> => {
        try {
            const fields = Object.keys(data);
            const values = Object.values(data);
            const setClause = fields
                .map(field => \`\${field} = ?\`)
                .join(', ');
            
            await db.query(\`
                UPDATE \${this.table}
                SET \${setClause}, updatedAt = CURRENT_TIMESTAMP
                WHERE id = ?
            \`, [...values, id]);
            
            const row = await db.query(\`
                SELECT * 
                FROM \${this.table} 
                WHERE id = ?
            \`, [id]);
            
            if (!row?.[0]) {
                throw new Error("${name} not found");
            }
            
            return {
                success: true,
                message: "${name} updated successfully",
                data: row[0]
            };
        } catch (error) {
            console.error('Error in update:', error);
            throw new Error(error instanceof Error ? error.message : "Failed to update ${name.toLowerCase()}");
        }
    };
    
    delete = async ({ id }: ${name}Id): Promise<Result<${pluralName}>> => {
        try {
            const row = await db.query(\`
                SELECT * 
                FROM \${this.table} 
                WHERE id = ?
            \`, [id]);
            
            if (!row?.[0]) {
                throw new Error("${name} not found");
            }
            
            await db.query(\`
                DELETE FROM \${this.table} 
                WHERE id = ?
            \`, [id]);
            
            return {
                success: true,
                message: "${name} deleted successfully",
                data: row[0]
            };
        } catch (error) {
            console.error('Error in delete:', error);
            throw new Error(error instanceof Error ? error.message : "Failed to delete ${name.toLowerCase()}");
        }
    };
}

// ! -- CUSTOM METHODS --
// You can add custom methods or business logic below this line
// For example: 
// export class Custom${name}Repository extends ${name}Repository {
//     customMethod = async () => {
//         // Your custom logic here
//     }
// }

export const Repository = new ${name}Repository();`;
// src/generators/languages/typescript/templates/framework/elysia/repository/postgresql.ts
var generatePostgresRepository2 = (name, pluralName) => `import { sql } from "../../config";
import type { Create${name}, Update${name}, ${pluralName}, ${name}Id } from "./${name.toLowerCase()}.schema";
import { NotFoundError, DatabaseError } from "../../error";

export class ${name}Repository {
    private readonly table = "${pluralName.toLowerCase()}";
    
    create = async (data: Create${name}) => {
        try {
            const [result] = await sql\`
                INSERT INTO \${sql(this.table)} \${sql(data)}
                RETURNING *
            \`;
            return { 
                success: true, 
                message: "${name} created successfully",
                data: result as ${pluralName} 
            };
        } catch (error) {
            console.error("Error creating ${name.toLowerCase()}:", error);
            throw new DatabaseError("Gagal membuat ${name.toLowerCase()} baru");
        }
    };
    
    findAll = async () => {
        try {
            const result = await sql\`SELECT * FROM \${sql(this.table)}\`;
            return { 
                success: true, 
                data: result as ${pluralName}[] 
            };
        } catch (error) {
            console.error("Error finding all ${pluralName.toLowerCase()}:", error);
            throw new DatabaseError("Gagal mengambil daftar ${pluralName.toLowerCase()}");
        }
    };
    
    findById = async ({ id }: ${name}Id) => {
        try {
            const [result] = await sql\`SELECT * FROM \${sql(this.table)} WHERE "id" = \${id}\`;
            if (!result) {
                throw new NotFoundError("${name}", id);
            }
            return { 
                success: true, 
                data: result as ${pluralName} 
            };
        } catch (error) {
            if (error instanceof NotFoundError) {
                throw error;
            }
            console.error("Error finding ${name.toLowerCase()} by id:", error);
            throw new DatabaseError("Gagal mencari ${name.toLowerCase()}");
        }
    };
    
    update = async ({ id }: ${name}Id, data: Update${name}) => {
        try {
            const [result] = await sql\`
                UPDATE \${sql(this.table)}
                SET \${sql(data)}, "updatedAt" = NOW()
                WHERE "id" = \${id}
                RETURNING *
            \`;
            if (!result) {
                throw new NotFoundError("${name}", id);
            }
            return { 
                success: true, 
                message: "${name} updated successfully",
                data: result as ${pluralName} 
            };
        } catch (error) {
            if (error instanceof NotFoundError) {
                throw error;
            }
            console.error("Error updating ${name.toLowerCase()}:", error);
            throw new DatabaseError("Gagal memperbarui ${name.toLowerCase()}");
        }
    };
    
    delete = async ({ id }: ${name}Id) => {
        try {
            return await sql.begin(async (tx) => {
                const [${name.toLowerCase()}] = await tx\`SELECT * FROM \${sql(this.table)} WHERE "id" = \${id}\`;
                if (!${name.toLowerCase()}) {
                    throw new NotFoundError("${name}", id);
                }
                await tx\`DELETE FROM \${sql(this.table)} WHERE "id" = \${id}\`;
                return { 
                    success: true, 
                    message: "${name} deleted successfully",
                    data: ${name.toLowerCase()} as ${pluralName} 
                };
            });
        } catch (error) {
            if (error instanceof NotFoundError) {
                throw error;
            }
            console.error("Error deleting ${name.toLowerCase()}:", error);
            throw new DatabaseError("Gagal menghapus ${name.toLowerCase()}");
        }
    };
}

// ! -- CUSTOM METHODS --
// You can add custom methods or business logic below this line
// For example: 
// export class Custom${name}Repository extends ${name}Repository {
//     customMethod = async () => {
//         // Your custom logic here
//    }
// }

export const Repository = new ${name}Repository();`;
// src/generators/languages/typescript/templates/framework/elysia/repository/sqlite.ts
var generateSqliteRepository2 = (name, pluralName) => `import { db } from "../../config";
import type { Create${name}, Update${name}, ${pluralName}, ${name}Id } from "./${name.toLowerCase()}.schema";

export type Result<T> = {
    success: boolean;
    message?: string;
    data: T | null;
    error?: unknown;
};

// Tipe untuk data dari SQLite (timestamps sebagai string)
type SQLite${name} = Omit<${pluralName}, 'createdAt' | 'updatedAt'> & {
    createdAt: string;
    updatedAt: string;
};

export class ${name}Repository {
    private readonly table = "${pluralName.toLowerCase()}";
    
    create = async (data: Create${name}): Promise<Result<${pluralName}>> => {
        try {
            const fields = Object.keys(data);
            const placeholders = fields.map(field => \`$\${field}\`).join(', ');
            
            const query = db.query(\`
                INSERT INTO \${this.table} 
                (\${fields.join(', ')}, createdAt, updatedAt)
                VALUES (\${placeholders}, datetime('now'), datetime('now'))
                RETURNING *;
            \`);
            
            const newItem = query.get(data) as SQLite${name};
            
            if (!newItem) {
                throw new Error("Failed to create ${name.toLowerCase()}");
            }
            
            return {
                success: true,
                message: "${name} created successfully",
                data: {
                    ...newItem,
                    createdAt: new Date(newItem.createdAt),
                    updatedAt: new Date(newItem.updatedAt)
                } as ${pluralName}
            };
        } catch (error) {
            console.error("Error creating ${name.toLowerCase()}:", error);
            return { 
                success: false, 
                data: null,
                error: error instanceof Error ? error.message : "Failed to create ${name.toLowerCase()}" 
            };
        }
    };
    
    findAll = async (): Promise<Result<${pluralName}[]>> => {
        try {
            const query = db.query(\`
                SELECT *
                FROM \${this.table}
            \`);
            
            const rows = query.all() as SQLite${name}[];
            
            return {
                success: true,
                data: rows.map(row => ({
                    ...row,
                    createdAt: new Date(row.createdAt),
                    updatedAt: new Date(row.updatedAt)
                })) as ${pluralName}[]
            };
        } catch (error) {
            console.error("Error finding all ${pluralName.toLowerCase()}:", error);
            return { 
                success: false, 
                data: null,
                error: error instanceof Error ? error.message : "Failed to fetch ${pluralName.toLowerCase()}" 
            };
        }
    };
    
    findById = async ({ id }: ${name}Id): Promise<Result<${pluralName}>> => {
        try {
            const query = db.query(\`
                SELECT *
                FROM \${this.table} 
                WHERE id = $id
            \`);
            
            const row = query.get({ $id: id }) as SQLite${name} | undefined;
            
            if (!row) {
                throw new Error("${name} not found");
            }
            
            return {
                success: true,
                data: {
                    ...row,
                    createdAt: new Date(row.createdAt),
                    updatedAt: new Date(row.updatedAt)
                } as ${pluralName}
            };
        } catch (error) {
            console.error("Error finding ${name.toLowerCase()} by id:", error);
            return { 
                success: false, 
                data: null,
                error: error instanceof Error ? error.message : "Failed to find ${name.toLowerCase()}" 
            };
        }
    };
    
    update = async ({ id }: ${name}Id, data: Update${name}): Promise<Result<${pluralName}>> => {
        try {
            const fields = Object.keys(data);
            const setClause = fields
                .map(field => \`\${field} = $\${field}\`)
                .join(', ');
            
            const updateQuery = db.query(\`
                UPDATE \${this.table}
                SET \${setClause}, updatedAt = datetime('now')
                WHERE id = $id
            \`);
            
            updateQuery.run({ ...data, $id: id });
            
            const findQuery = db.query(\`
                SELECT *
                FROM \${this.table} 
                WHERE id = $id
            \`);
            
            const row = findQuery.get({ $id: id }) as SQLite${name} | undefined;
            
            if (!row) {
                throw new Error("${name} not found");
            }
            
            return {
                success: true,
                message: "${name} updated successfully",
                data: {
                    ...row,
                    createdAt: new Date(row.createdAt),
                    updatedAt: new Date(row.updatedAt)
                } as ${pluralName}
            };
        } catch (error) {
            console.error("Error updating ${name.toLowerCase()}:", error);
            return { 
                success: false, 
                data: null,
                error: error instanceof Error ? error.message : "Failed to update ${name.toLowerCase()}" 
            };
        }
    };
    
    delete = async ({ id }: ${name}Id): Promise<Result<${pluralName}>> => {
        try {
            const findQuery = db.query(\`
                SELECT *
                FROM \${this.table} 
                WHERE id = $id
            \`);
            
            const row = findQuery.get({ $id: id }) as SQLite${name} | undefined;
            
            if (!row) {
                throw new Error("${name} not found");
            }
            
            const deleteQuery = db.query(\`DELETE FROM \${this.table} WHERE id = $id\`);
            deleteQuery.run({ $id: id });
            
            return {
                success: true,
                message: "${name} deleted successfully",
                data: {
                    ...row,
                    createdAt: new Date(row.createdAt),
                    updatedAt: new Date(row.updatedAt)
                } as ${pluralName}
            };
        } catch (error) {
            console.error("Error deleting ${name.toLowerCase()}:", error);
            return { 
                success: false, 
                data: null,
                error: error instanceof Error ? error.message : "Failed to delete ${name.toLowerCase()}" 
            };
        }
    };
}

// ! -- CUSTOM METHODS --
// You can add custom methods or business logic below this line
// For example: 
// export class Custom${name}Repository extends ${name}Repository {
//     customMethod = async () => {
//         // Your custom logic here
//    }
// }

export const Repository = new ${name}Repository();`;
// src/generators/languages/typescript/templates/framework/elysia/repository/mongodb.ts
var generateMongoRepository2 = (name, pluralName) => `import { ObjectId } from "mongodb";
import { db } from "../../config";
import type { Create${name}, Update${name}, ${pluralName}, ${name}Id } from "./${name.toLowerCase()}.schema";

export type Result<T> = {
    success: boolean;
    message?: string;
    data: T | null;
};

export class ${name}Repository {
    private readonly collection = "${pluralName.toLowerCase()}";
    
    private getCollection = async () => {
        return db.collection(this.collection);
    };
    
    create = async (data: Create${name}): Promise<Result<${pluralName}>> => {
        try {
            const doc = {
                ...data,
                createdAt: new Date(),
                updatedAt: new Date()
            } as const;
            
            const collection = await this.getCollection();
            const result = await collection.insertOne(doc);
            
            if (!result.acknowledged) {
                return {
                    success: false,
                    message: "Failed to create ${name.toLowerCase()}",
                    data: null
                };
            }
            
            return {
                success: true,
                message: "${name} created successfully",
                data: { ...doc, _id: result.insertedId } as ${pluralName}
            };
        } catch (error) {
            return {
                success: false,
                message: error instanceof Error ? error.message : "Failed to create ${name.toLowerCase()}",
                data: null
            };
        }
    };

    findAll = async (): Promise<Result<${pluralName}[]>> => {
        try {
            const collection = await this.getCollection();
            const docs = await collection
                .find({})
                .sort({ _id: -1 })
                .toArray() as ${pluralName}[];
                
            return {
                success: true,
                data: docs as ${pluralName}[]
            };
        } catch (error) {
            return {
                success: false,
                message: error instanceof Error ? error.message : "Failed to fetch ${pluralName.toLowerCase()}",
                data: null
            };
        }
    };

    findById = async ({ id }: ${name}Id): Promise<Result<${pluralName}>> => {
        try {
            const collection = await this.getCollection();
            const doc = await collection
                .findOne({ _id: new ObjectId(id) }) as ${pluralName} | null;
                
            if (!doc) {
                return {
                    success: false,
                    message: "${name} not found",
                    data: null
                };
            }
            
            return {
                success: true,
                data: doc as ${pluralName}
            };
        } catch (error) {
            return {
                success: false,
                message: error instanceof Error ? error.message : "Failed to find ${name.toLowerCase()}",
                data: null
            };
        }
    };

    update = async ({ id }: ${name}Id, data: Update${name}): Promise<Result<${pluralName}>> => {
        try {
            const collection = await this.getCollection();
            const result = await collection
                .findOneAndUpdate(
                    { _id: new ObjectId(id) },
                    { 
                        $set: {
                            ...data,
                            updatedAt: new Date()
                        }
                    },
                    { returnDocument: 'after' }
                );
            
            if (!result) {
                return {
                    success: false,
                    message: "${name} not found",
                    data: null
                };
            }
            
            return {
                success: true,
                message: "${name} updated successfully",
                data: result as ${pluralName}
            };
        } catch (error) {
            return {
                success: false,
                message: error instanceof Error ? error.message : "Failed to update ${name.toLowerCase()}",
                data: null
            };
        }
    };

    delete = async ({ id }: ${name}Id): Promise<Result<${pluralName}>> => {
        try {
            const collection = await this.getCollection();
            const doc = await collection
                .findOne({ _id: new ObjectId(id) });
                
            if (!doc) {
                return {
                    success: false,
                    message: "${name} not found",
                    data: null
                };
            }

            await collection.deleteOne({ _id: new ObjectId(id) });
            
            return {
                success: true,
                message: "${name} deleted successfully",
                data: doc as ${pluralName}
            };
        } catch (error) {
            return {
                success: false,
                message: error instanceof Error ? error.message : "Failed to delete ${name.toLowerCase()}",
                data: null
            };
        }
    };
}

// ! -- CUSTOM METHODS --
// You can add custom methods or business logic below this line
// For example: 
// export class Custom${name}Repository extends ${name}Repository {
//     customMethod = async () => {
//         // Your custom logic here
//    }
// }

export const Repository = new ${name}Repository();`;
// src/generators/languages/typescript/templates/framework/elysia/schema/mongoose.ts
var generateMongooseSchema2 = (name, fields) => {
  const mapTypeToMongoose = (zodType) => {
    const typeMap = {
      string: "String",
      number: "Number",
      boolean: "Boolean",
      date: "Date",
      array: "Array",
      object: "Object"
    };
    return typeMap[zodType] || "String";
  };
  return `import { Elysia, t } from 'elysia'
import { db } from '../../config';
import { Document, Schema } from 'mongoose';

// Definisi interface untuk tipe data
export interface Create${name} {
    ${fields.map((f) => `${f.name}: ${f.type === "number" ? "number" : f.type === "boolean" ? "boolean" : "string"};`).join(`
    `)}
}

export type Update${name} = Partial<Create${name}>;

export interface ${pluralize(name)} extends Document, Create${name} {
    _id: typeof db.Types.ObjectId;
    createdAt: Date;
    updatedAt: Date;
}

// Mongoose schema
const ${name.toLowerCase()}Schema = new Schema<${pluralize(name)}>(
    {
        ${fields.map((f) => `${f.name}: { type: ${mapTypeToMongoose(f.type)}, required: true }`).join(`,
        `)}
    },
    { 
        timestamps: true,
        versionKey: false
    }
);

// Mongoose model
export const ${name} = db.model<${pluralize(name)}>('${name}', ${name.toLowerCase()}Schema);

// Elysia validation models untuk API routes
export const ${name}Model = {
    create: t.Object({
        ${fields.map((f) => `${f.name}: t.${f.type.charAt(0).toUpperCase() + f.type.slice(1)}()`).join(`,
        `)}
    }),
    
    update: t.Object({
        ${fields.map((f) => `${f.name}: t.${f.type.charAt(0).toUpperCase() + f.type.slice(1)}({ optional: true })`).join(`,
        `)}
    }),
    
    id: t.Object({
        id: t.String({
            pattern: '^[0-9a-fA-F]{24}$',
            error: 'Invalid ObjectId format'
        })
    })
}

// Plugin Elysia untuk model
export const ${name}Schema = new Elysia()
    .model({
        create: ${name}Model.create,
        update: ${name}Model.update,
        id: ${name}Model.id
    })`;
};
// src/generators/languages/typescript/templates/framework/elysia/schema/mongodb.ts
var generateMongodbSchema2 = (name, fields) => `import { Elysia, t } from 'elysia'
import { ObjectId } from 'mongodb'

// Define models
const models = {
    create: t.Object({
        ${fields.map((f) => `${f.name}: t.${f.type.charAt(0).toUpperCase() + f.type.slice(1)}()`).join(`,
        `)}
    }),
    
    update: t.Object({
        ${fields.map((f) => `${f.name}: t.${f.type.charAt(0).toUpperCase() + f.type.slice(1)}({ optional: true })`).join(`,
        `)}
    }),
    
    id: t.Object({
        id: t.String({
            pattern: '^[0-9a-fA-F]{24}$',
            error: 'Invalid ObjectId format'
        })
    })
}

// Create plugin with models
export const ${name}Schema = new Elysia()
    .model(models)

// Types from model
export type Create${name} = typeof models.create.static
export type Update${name} = typeof models.update.static
export type ${name}Id = typeof models.id.static
export type ${pluralize(name)} = Create${name} & {
    _id: ObjectId
    createdAt: Date
    updatedAt: Date
}

// Export models for routes usage
export const ${name}Model = models`;
// src/generators/languages/typescript/templates/framework/elysia/schema/sql.ts
var generateSqlSchema2 = (name, fields) => `import { Elysia, t } from 'elysia'

// Define models
const models = {
    create: t.Object({
        ${fields.map((f) => `${f.name}: t.${f.type.charAt(0).toUpperCase() + f.type.slice(1)}()`).join(`,
        `)}
    }),
    
    update: t.Object({
        ${fields.map((f) => `${f.name}: t.${f.type.charAt(0).toUpperCase() + f.type.slice(1)}({ optional: true })`).join(`,
        `)}
    }),
    
    id: t.Object({
        id: t.Numeric()
    })
}

// Create plugin with models
export const ${name}Schema = new Elysia()
    .model(models)

// Types from model
export type Create${name} = typeof models.create.static
export type Update${name} = typeof models.update.static
export type ${name}Id = typeof models.id.static
export type ${pluralize(name)} = Create${name} & ${name}Id & {
    createdAt: Date
    updatedAt: Date
}

// Export models for routes usage
export const ${name}Model = models`;
// src/generators/languages/typescript/templates/framework/elysia/service/mongoose.ts
var generateMongooseService2 = (name, pluralName) => `import { Elysia } from 'elysia'
import { ${name} } from './${name.toLowerCase()}.schema'
import type { Create${name}, Update${name}, ${pluralName} } from './${name.toLowerCase()}.schema'

export type Result<T> = {
    success: boolean;
    message?: string;
    data: T | null;
    error?: unknown;
};

// Define service methods
const ${name.toLowerCase()}Methods = {
    create: async(data: Create${name}): Promise<Result<${pluralName}>> => {
        try {
            const ${name.toLowerCase()} = new ${name}(data);
            const saved${name} = await ${name.toLowerCase()}.save();
            
            return {
                success: true,
                message: "${name} created successfully",
                data: saved${name}
            };
        } catch (error) {
            throw error;
        }
    },
    
    getAll: async(): Promise<Result<${pluralName}[]>> => {
        try {
            const ${pluralName.toLowerCase()} = await ${name}.find();
            
            return {
                success: true,
                data: ${pluralName.toLowerCase()}
            };
        } catch (error) {
            throw error;
        }
    },
    
    getById: async(id: string): Promise<Result<${pluralName}>> => {
        try {
            const ${name.toLowerCase()} = await ${name}.findById(id);
            
            if (!${name.toLowerCase()}) {
                throw new Error("${name} not found");
            }
            
            return {
                success: true,
                data: ${name.toLowerCase()}
            };
        } catch (error) {
            throw error;
        }
    },
    
    update: async(id: string, data: Update${name}): Promise<Result<${pluralName}>> => {
        try {
            const ${name.toLowerCase()} = await ${name}.findByIdAndUpdate(
                id,
                { ...data },
                { new: true }
            );
            
            if (!${name.toLowerCase()}) {
                throw new Error("${name} not found");
            }
            
            return {
                success: true,
                message: "${name} updated successfully",
                data: ${name.toLowerCase()}
            };
        } catch (error) {
            throw error;
        }
    },
    
    delete: async(id: string): Promise<Result<${pluralName}>> => {
        try {
            const ${name.toLowerCase()} = await ${name}.findByIdAndDelete(id);
            
            if (!${name.toLowerCase()}) {
                throw new Error("${name} not found");
            }
            
            return {
                success: true,
                message: "${name} deleted successfully",
                data: ${name.toLowerCase()}
            };
        } catch (error) {
            throw error;
        }
    }
}

// Create service
export const Service = new Elysia({ name: 'Service.${name}' })
    .state('${pluralName.toLowerCase()}', ${name.toLowerCase()}Methods)`;
// src/generators/languages/typescript/templates/framework/elysia/service/mongodb.ts
var generateMongodbService2 = (name, pluralName) => `import { Elysia } from 'elysia'
import { Repository as ${name} } from './${name.toLowerCase()}.repository'
import type { Create${name}, Update${name}, ${pluralName} } from './${name.toLowerCase()}.schema'
import type { Result } from './${name.toLowerCase()}.repository'

// Define service methods
const ${name.toLowerCase()}Methods = {
    create: async (data: Create${name}): Promise<Result<${pluralName}>> => {
        try {
            return await ${name}.create(data)
        } catch (error) {
            console.error("Service error creating ${name.toLowerCase()}:", error)
            return {
                success: false,
                message: error instanceof Error ? error.message : "Failed to create ${name.toLowerCase()}",
                data: null
            }
        }
    },
    
    getAll: async (): Promise<Result<${pluralName}[]>> => {
        try {
            return await ${name}.findAll()
        } catch (error) {
            console.error("Service error getting all ${pluralName.toLowerCase()}:", error)
            return {
                success: false,
                message: error instanceof Error ? error.message : "Failed to get all ${pluralName.toLowerCase()}",
                data: null
            }
        }
    },
    
    getById: async (id: string): Promise<Result<${pluralName}>> => {
        try {
            return await ${name}.findById({ id })
        } catch (error) {
            console.error("Service error getting ${name.toLowerCase()} by id:", error)
            return {
                success: false,
                message: error instanceof Error ? error.message : "Failed to get ${name.toLowerCase()} by id",
                data: null
            }
        }
    },
    
    update: async (id: string, data: Update${name}): Promise<Result<${pluralName}>> => {
        try {
            return await ${name}.update({ id }, data)
        } catch (error) {
            console.error("Service error updating ${name.toLowerCase()}:", error)
            return {
                success: false,
                message: error instanceof Error ? error.message : "Failed to update ${name.toLowerCase()}",
                data: null
            }
        }
    },
    
    delete: async (id: string): Promise<Result<${pluralName}>> => {
        try {
            return await ${name}.delete({ id })
        } catch (error) {
            console.error("Service error deleting ${name.toLowerCase()}:", error)
            return {
                success: false,
                message: error instanceof Error ? error.message : "Failed to delete ${name.toLowerCase()}",
                data: null
            }
        }
    }
}

// Create service
export const Service = new Elysia({ name: 'Service.${name}' })
    .state('${pluralName.toLowerCase()}', ${name.toLowerCase()}Methods)`;
// src/generators/languages/typescript/templates/framework/elysia/service/sql.ts
var generateSqlService2 = (name, pluralName) => `import { Elysia } from 'elysia'
import { Repository } from './${name.toLowerCase()}.repository'
import type { Create${name}, Update${name} } from './${name.toLowerCase()}.schema'

// Define service methods
const ${name.toLowerCase()}Methods = {
    create: async (data: Create${name}) => {
        try {
            return await Repository.create(data);
        } catch (error) {
            console.error("Service error creating ${name.toLowerCase()}:", error);
            throw error;
        }
    },
    
    getAll: async () => {
        try {
            return await Repository.findAll();
        } catch (error) {
            console.error("Service error getting all ${pluralName.toLowerCase()}:", error);
            throw error;
        }
    },
    
    getById: async (id: number) => {
        try {
            return await Repository.findById({ id });
        } catch (error) {
            console.error("Service error getting ${name.toLowerCase()} by id:", error);
            throw error;
        }
    },
    
    update: async (id: number, data: Update${name}) => {
        try {
            return await Repository.update({ id }, data);
        } catch (error) {
            console.error("Service error updating ${name.toLowerCase()}:", error);
            throw error;
        }
    },
    
    delete: async (id: number) => {
        try {
            return await Repository.delete({ id });
        } catch (error) {
            console.error("Service error deleting ${name.toLowerCase()}:", error);
            throw error;
        }
    }
}

// Create service
export const Service = new Elysia({ name: 'Service.${name}' })
    .state('${pluralName.toLowerCase()}', ${name.toLowerCase()}Methods)`;
// src/generators/languages/typescript/templates/framework/elysia/controller.ts
var generateController2 = (name, pluralName) => `import { Elysia } from 'elysia'
import { Service } from './${name.toLowerCase()}.service'
import { ${name}Model } from './${name.toLowerCase()}.schema'

export const ${name} = new Elysia()
    .use(Service)
    .group('/${pluralName.toLowerCase()}', app => app
        .get('/', 
            async ({ store: { ${pluralName.toLowerCase()} } }) => {
                const result = await ${pluralName.toLowerCase()}.getAll()
                return result
            }
        )
        .get('/:id', 
            async ({ params: { id }, store: { ${pluralName.toLowerCase()} } }) => {
                const result = await ${pluralName.toLowerCase()}.getById(id)
                return result
            },
            { params: ${name}Model.id }
        )
        .post('/', 
            async ({ body, store: { ${pluralName.toLowerCase()} } }) => {
                const result = await ${pluralName.toLowerCase()}.create(body)
                return result
            },
            { body: ${name}Model.create }
        )
        .put('/:id',
            async ({ params: { id }, body, store: { ${pluralName.toLowerCase()} } }) => {
                const result = await ${pluralName.toLowerCase()}.update(id, body)
                return result
            },
            {
                params: ${name}Model.id,
                body: ${name}Model.update
            }
        )
        .delete('/:id',
            async ({ params: { id }, store: { ${pluralName.toLowerCase()} } }) => {
                const result = await ${pluralName.toLowerCase()}.delete(id)
                return result
            },
            { params: ${name}Model.id }
        )
    )`;
// src/generators/languages/typescript/templates/framework/elysia/server.ts
var generateServer2 = () => `import { Elysia } from 'elysia'
import { cors } from '@elysiajs/cors'
import { swagger } from '@elysiajs/swagger'
import { NotFoundError, DatabaseError, ValidationError, handleError } from './error'
import { router } from './router'

const app = new Elysia()
    // Register custom errors
    .error({
        NotFoundError,
        DatabaseError,
        ValidationError
    })
    // Global error handler
    .onError(({ code, error, set }) => {
        console.error(\`[Error] \${code}:\`, error);
        
        const { status, body } = handleError(code, error);
        set.status = status;
        
        return body;
    })
    // Other plugins
    .use(swagger({
        documentation: {
            info: {
                title: 'API Documentation',
                version: '1.0.0'
            }
        }
    }))
    .use(cors())
    // Routes
    .get('/', () => ({ 
        success: true, 
        message: 'API is running',
        data: { 
            timestamp: new Date().toISOString() 
        }
    }))
    .use(router)
    .listen(3000)

console.log('\uD83E\uDD8A Server running at', app.server?.hostname, 'on port', app.server?.port)

export type App = typeof app`;
// src/generators/languages/typescript/templates/framework/elysia/error.ts
var generateError2 = () => `// Custom error types
export class NotFoundError extends Error {
    constructor(resource: string = 'Resource', id?: string | number) {
        super(id 
            ? \`\${resource} dengan ID \${id} tidak ditemukan\` 
            : \`\${resource} tidak ditemukan\`);
        this.name = 'NotFoundError';
    }
}

export class DatabaseError extends Error {
    constructor(message: string = 'Terjadi kesalahan database') {
        super(message);
        this.name = 'DatabaseError';
    }
}

export class ValidationError extends Error {
    constructor(message: string = 'Data tidak valid') {
        super(message);
        this.name = 'ValidationError';
    }
}

// Simplified error mapping
export const ERROR_MAP = {
    // Custom errors
    NotFoundError: { status: 404, code: 'NOT_FOUND' },
    DatabaseError: { status: 500, code: 'DATABASE_ERROR' },
    ValidationError: { status: 400, code: 'VALIDATION_ERROR' },
    
    // Elysia built-in errors
    NOT_FOUND: { status: 404, code: 'ROUTE_NOT_FOUND', message: 'Route tidak ditemukan' },
    VALIDATION: { status: 400, code: 'VALIDATION_ERROR' },
    PARSE: { status: 400, code: 'PARSE_ERROR', message: 'Format data tidak valid' },
    INTERNAL_SERVER_ERROR: { status: 500, code: 'INTERNAL_SERVER_ERROR' },
    INVALID_COOKIE_SIGNATURE: { status: 400, code: 'INVALID_COOKIE' },
    UNKNOWN: { status: 500, code: 'UNKNOWN_ERROR' }
} as const;

// Simplified error handler
export const handleError = (code: string | number, error: unknown) => {
    const errorKey = typeof code === 'string' ? code : 'UNKNOWN';
    const errorConfig = ERROR_MAP[errorKey as keyof typeof ERROR_MAP] || ERROR_MAP.UNKNOWN;
    
    let message = 'Terjadi kesalahan internal server';
    
    if (error instanceof Error) {
        message = error.message;
    } else if (typeof error === 'string') {
        message = error;
    }
    
    // Use predefined message if available
    if ('message' in errorConfig && typeof errorConfig.message === 'string') {
        message = errorConfig.message;
    }
    
    return {
        status: errorConfig.status,
        body: {
            success: false,
            error: {
                code: errorConfig.code,
                message
            },
            data: null
        }
    };
};`;
// src/generators/languages/typescript/templates/framework/hono/repository/mariadb.ts
var generateMariadbRepository3 = (name, pluralName) => `import { db } from "../../config";
import type { Create${name}, Update${name}, ${pluralName}, ${name}Id } from "./${name.toLowerCase()}.schema";
import { ${name} } from "./${name.toLowerCase()}.schema";

export type Result<T> = {
    success: boolean;
    message?: string;
    data: T | null;
    error?: unknown;
};

export class ${name}Repository {
    private readonly table = "${pluralName.toLowerCase()}";
    
    create = async (data: Create${name}): Promise<Result<${pluralName}>> => {
        try {
            const fields = Object.keys(data);
            const values = Object.values(data);
            const placeholders = values.map(() => '?').join(', ');
            
            const result = await db.query(\`
                INSERT INTO \${this.table} 
                (\${fields.join(', ')}, createdAt, updatedAt)
                VALUES (\${placeholders}, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
            \`, values);
            
            const newItem = await db.query(\`
                SELECT *
                FROM \${this.table} 
                WHERE id = ?
            \`, [result.insertId]);
            
            if (!newItem?.[0]) {
                throw new Error("Failed to create ${name.toLowerCase()}");
            }
            
            return {
                success: true,
                message: "${name} created successfully",
                data: new ${name}(newItem[0]) as ${pluralName}
            };
        } catch (error) {
            console.error('Error in create:', error);
            throw new Error(error instanceof Error ? error.message : "Failed to create ${name.toLowerCase()}");
        }
    };
    
    findAll = async (): Promise<Result<${pluralName}[]>> => {
        try {
            const rows = await db.query(\`
                SELECT * 
                FROM \${this.table}
                ORDER BY id DESC
            \`);
            
            return {
                success: true,
                data: rows.map((row: ${name}) => new ${name}(row) as ${pluralName})
            };
        } catch (error) {
            console.error('Error in findAll:', error);
            throw new Error("Failed to fetch ${pluralName.toLowerCase()}");
        }
    };
    
    findById = async ({ id }: ${name}Id): Promise<Result<${pluralName}>> => {
        try {
            const row = await db.query(\`
                SELECT * 
                FROM \${this.table} 
                WHERE id = ?
            \`, [id]);
            
            if (!row?.[0]) {
                throw new Error("${name} not found");
            }
            
            return {
                success: true,
                data: new ${name}(row[0]) as ${pluralName}
            };
        } catch (error) {
            console.error('Error in findById:', error);
            throw new Error(error instanceof Error ? error.message : "Failed to find ${name.toLowerCase()}");
        }
    };
    
    update = async ({ id }: ${name}Id, data: Update${name}): Promise<Result<${pluralName}>> => {
        try {
            const fields = Object.keys(data);
            const values = Object.values(data);
            const setClause = fields
                .map(field => \`\${field} = ?\`)
                .join(', ');
            
            await db.query(\`
                UPDATE \${this.table}
                SET \${setClause}, updatedAt = CURRENT_TIMESTAMP
                WHERE id = ?
            \`, [...values, id]);
            
            const row = await db.query(\`
                SELECT * 
                FROM \${this.table} 
                WHERE id = ?
            \`, [id]);
            
            if (!row?.[0]) {
                throw new Error("${name} not found");
            }
            
            return {
                success: true,
                message: "${name} updated successfully",
                data: new ${name}(row[0]) as ${pluralName}
            };
        } catch (error) {
            console.error('Error in update:', error);
            throw new Error(error instanceof Error ? error.message : "Failed to update ${name.toLowerCase()}");
        }
    };
    
    delete = async ({ id }: ${name}Id): Promise<Result<${pluralName}>> => {
        try {
            const row = await db.query(\`
                SELECT * 
                FROM \${this.table} 
                WHERE id = ?
            \`, [id]);
            
            if (!row?.[0]) {
                throw new Error("${name} not found");
            }
            
            await db.query(\`
                DELETE FROM \${this.table} 
                WHERE id = ?
            \`, [id]);
            
            return {
                success: true,
                message: "${name} deleted successfully",
                data: new ${name}(row[0]) as ${pluralName}
            };
        } catch (error) {
            console.error('Error in delete:', error);
            throw new Error(error instanceof Error ? error.message : "Failed to delete ${name.toLowerCase()}");
        }
    };
}

// ! -- CUSTOM METHODS --
// You can add custom methods or business logic below this line
// For example: 
// export class Custom${name}Repository extends ${name}Repository {
//     customMethod = async () => {
//         // Your custom logic here
//     }
// }

export const Repository = new ${name}Repository();`;
// src/generators/languages/typescript/templates/framework/hono/repository/mongodb.ts
var generateMongoRepository3 = (name, pluralName) => `import { ObjectId } from "mongodb";
import { db } from "../../config";
import type { Create${name}, Update${name}, ${pluralName}, ${name}Id } from "./${name.toLowerCase()}.schema";
import { ${name} } from "./${name.toLowerCase()}.schema";
import { HTTPException } from "hono/http-exception";

export class ${name}Repository {
    private readonly collection = "${pluralName.toLowerCase()}";
    
    private getCollection = async () => {
        return db.collection(this.collection);
    };
    
    create = async (data: Create${name}) => {
        try {
            const doc = {
                ...data,
                createdAt: new Date(),
                updatedAt: new Date()
            } as const;
            
            const collection = await this.getCollection();
            const result = await collection.insertOne(doc);
            
            if (!result.acknowledged) {
                throw new HTTPException(500, { message: "Failed to create ${name.toLowerCase()}" });
            }
            
            return {
                success: true,
                message: "${name} created successfully",
                data: new ${name}({ ...doc, _id: result.insertedId }) as ${pluralName}
            };
        } catch (error) {
            console.error("Repository error creating ${name.toLowerCase()}:", error);
            throw error;
        }
    };

    findAll = async () => {
        try {
            const collection = await this.getCollection();
            const docs = await collection
                .find({})
                .sort({ _id: -1 })
                .toArray() as ${pluralName}[];
                
            return {
                success: true,
                data: docs.map(doc => new ${name}(doc) as ${pluralName})
            };
        } catch (error) {
            console.error("Repository error fetching ${pluralName.toLowerCase()}:", error);
            throw error;
        }
    };

    findById = async ({ id }: ${name}Id) => {
        try {
            const collection = await this.getCollection();
            const doc = await collection
                .findOne({ _id: new ObjectId(id) }) as ${pluralName} | null;
                
            if (!doc) {
                throw new HTTPException(404, { message: \`${name} with id \${id} not found\` });
            }
            
            return {
                success: true,
                data: new ${name}(doc) as ${pluralName}
            };
        } catch (error) {
            console.error("Repository error finding ${name.toLowerCase()}:", error);
            throw error;
        }
    };

    update = async ({ id }: ${name}Id, data: Update${name}) => {
        try {
            const collection = await this.getCollection();
            const result = await collection
                .findOneAndUpdate(
                    { _id: new ObjectId(id) },
                    { 
                        $set: {
                            ...data,
                            updatedAt: new Date()
                        }
                    },
                    { returnDocument: 'after' }
                );
            
            if (!result) {
                throw new HTTPException(404, { message: \`${name} with id \${id} not found\` });
            }
            
            return {
                success: true,
                message: "${name} updated successfully",
                data: new ${name}(result) as ${pluralName}
            };
        } catch (error) {
            console.error("Repository error updating ${name.toLowerCase()}:", error);
            throw error;
        }
    };

    delete = async ({ id }: ${name}Id) => {
        try {
            const collection = await this.getCollection();
            const doc = await collection
                .findOne({ _id: new ObjectId(id) });
                
            if (!doc) {
                throw new HTTPException(404, { message: \`${name} with id \${id} not found\` });
            }

            await collection.deleteOne({ _id: new ObjectId(id) });
            
            return {
                success: true,
                message: "${name} deleted successfully",
                data: new ${name}(doc) as ${pluralName}
            };
        } catch (error) {
            console.error("Repository error deleting ${name.toLowerCase()}:", error);
            throw error;
        }
    };
}

// ! -- CUSTOM METHODS --
// You can add custom methods or business logic below this line
// For example: 
// export class Custom${name}Repository extends ${name}Repository {
//     customMethod = async () => {
//         // Your custom logic here
//    }
// }

export const Repository = new ${name}Repository();`;
// src/generators/languages/typescript/templates/framework/hono/repository/postgresql.ts
var generatePostgresRepository3 = (name, pluralName) => `import { sql } from "../../config";
import type { Create${name}, Update${name}, ${pluralName}, ${name}Id } from "./${name.toLowerCase()}.schema";
import { ${name} } from "./${name.toLowerCase()}.schema";
import { HTTPException } from "hono/http-exception";

export class ${name}Repository {
    private readonly table = "${pluralName.toLowerCase()}";
    
    create = async (data: Create${name}) => {
        try {
            const [result] = await sql\`
                INSERT INTO \${sql(this.table)} \${sql(data)}
                RETURNING *
            \`;
            return { 
                success: true, 
                message: "${name} created successfully",
                data: new ${name}(result) as ${pluralName} 
            };
        } catch (error) {
            console.error("Error creating ${name.toLowerCase()}:", error);
            throw error;
        }
    };
    
    findAll = async () => {
        try {
            const result = await sql\`SELECT * FROM \${sql(this.table)}\`;
            return { 
                success: true, 
                data: result.map((row: ${pluralName}) => new ${name}(row) as ${pluralName}) 
            };
        } catch (error) {
            console.error("Error finding all ${pluralName.toLowerCase()}:", error);
            throw error;
        }
    };
    
    findById = async ({ id }: ${name}Id) => {
        try {
            const [result] = await sql\`SELECT * FROM \${sql(this.table)} WHERE "id" = \${id}\`;
            if (!result) {
                throw new HTTPException(404, { message: "${name} not found" });
            }
            return { 
                success: true, 
                data: new ${name}(result) as ${pluralName} 
            };
        } catch (error) {
            console.error("Error finding ${name.toLowerCase()} by id:", error);
            throw error;
        }
    };
    
    update = async ({ id }: ${name}Id, data: Update${name}) => {
        try {
            const [result] = await sql\`
                UPDATE \${sql(this.table)}
                SET \${sql(data)}, "updatedAt" = NOW()
                WHERE "id" = \${id}
                RETURNING *
            \`;
            if (!result) {
                throw new HTTPException(404, { message: "${name} not found" });
            }
            return { 
                success: true, 
                message: "${name} updated successfully",
                data: new ${name}(result) as ${pluralName} 
            };
        } catch (error) {
            console.error("Error updating ${name.toLowerCase()}:", error);
            throw error;
        }
    };
    
    delete = async ({ id }: ${name}Id) => {
        try {
            return await sql.begin(async (tx) => {
                const [${name.toLowerCase()}] = await tx\`SELECT * FROM \${sql(this.table)} WHERE "id" = \${id}\`;
                if (!${name.toLowerCase()}) {
                    throw new HTTPException(404, { message: "${name} not found" });
                }
                await tx\`DELETE FROM \${sql(this.table)} WHERE "id" = \${id}\`;
                return { 
                    success: true, 
                    message: "${name} deleted successfully",
                    data: new ${name}(${name.toLowerCase()}) as ${pluralName} 
                };
            });
        } catch (error) {
            console.error("Error deleting ${name.toLowerCase()}:", error);
            throw error;
        }
    };
}

// ! -- CUSTOM METHODS --
// You can add custom methods or business logic below this line
// For example: 
// export class Custom${name}Repository extends ${name}Repository {
//     customMethod = async () => {
//         // Your custom logic here
//    }
// }

export const Repository = new ${name}Repository();`;
// src/generators/languages/typescript/templates/framework/hono/repository/sqlite.ts
var generateSqliteRepository3 = (name, pluralName) => `import { db } from "../../config";
import type { Create${name}, Update${name}, ${pluralName}, ${name}Id } from "./${name.toLowerCase()}.schema";
import { ${name} } from "./${name.toLowerCase()}.schema";
import { HTTPException } from "hono/http-exception";

// Tipe untuk data dari SQLite (timestamps sebagai string)
type SQLite${name} = Omit<${pluralName}, 'createdAt' | 'updatedAt'> & {
    createdAt: string;
    updatedAt: string;
};

export class ${name}Repository {
    private readonly table = "${pluralName.toLowerCase()}";
    
    private convertDates(${name.toLowerCase()}: SQLite${name}): ${pluralName} {
        return new ${name}({
            ...${name.toLowerCase()},
            createdAt: new Date(${name.toLowerCase()}.createdAt),
            updatedAt: new Date(${name.toLowerCase()}.updatedAt)
        }) as ${pluralName};
    }

    create = async (data: Create${name}) => {
        try {
            const fields = Object.keys(data);
            const columns = fields.join(', ');
            const placeholders = fields.map(f => \`$\${f}\`).join(', ');
            const params = Object.fromEntries(fields.map(f => [\`$\${f}\`, data[f as keyof Create${name}]]));
            
            const newItem = db.query(\`
                INSERT INTO \${this.table} 
                (\${columns}, createdAt, updatedAt)
                VALUES (\${placeholders}, datetime('now'), datetime('now'))
                RETURNING *;
            \`).get(params) as SQLite${name};
            
            if (!newItem) throw new HTTPException(400, { message: "Failed to create ${name.toLowerCase()}" });
            
            return {
                success: true,
                message: "${name} created successfully",
                data: this.convertDates(newItem)
            };
        } catch (error) {
            console.error("Error creating ${name.toLowerCase()}:", error);
            throw error;
        }
    };
    
    findAll = async () => {
        try {
            const query = db.query(\`SELECT * FROM \${this.table}\`);
            const rows = query.all() as SQLite${name}[];
            
            return {
                success: true,
                data: rows.map(this.convertDates)
            };
        } catch (error) {
            console.error("Error finding all ${pluralName.toLowerCase()}:", error);
            throw error;
        }
    };
    
    findById = async ({ id }: ${name}Id) => {
        try {
            const query = db.query(\`
                SELECT *
                FROM \${this.table} 
                WHERE id = $id
            \`);
            
            const row = query.get({ $id: id }) as SQLite${name} | undefined;
            
            if (!row) {
                throw new HTTPException(404, { message: "${name} not found" });
            }
            
            return {
                success: true,
                data: this.convertDates(row)
            };
        } catch (error) {
            console.error("Error finding ${name.toLowerCase()} by id:", error);
            throw error;
        }
    };
    
    update = async ({ id }: ${name}Id, data: Update${name}) => {
        try {
            const fields = Object.keys(data);
            const setClause = fields.map(f => \`\${f} = $\${f}\`).join(', ');
            const params = { $id: id, ...Object.fromEntries(fields.map(f => [\`$\${f}\`, data[f as keyof Update${name}]])) };
            
            db.query(\`
                UPDATE \${this.table}
                SET \${setClause}, updatedAt = datetime('now')
                WHERE id = $id
            \`).run(params);
            
            const row = db.query(\`SELECT * FROM \${this.table} WHERE id = $id\`)
                .get({ $id: id }) as SQLite${name};
            
            if (!row) throw new HTTPException(404, { message: "${name} not found" });
            
            return {
                success: true,
                message: "${name} updated successfully",
                data: this.convertDates(row)
            };
        } catch (error) {
            console.error("Error updating ${name.toLowerCase()}:", error);
            throw error;
        }
    };
    
    delete = async ({ id }: ${name}Id) => {
        try {
            const findQuery = db.query(\`
                SELECT *
                FROM \${this.table} 
                WHERE id = $id
            \`);
            
            const row = findQuery.get({ $id: id }) as SQLite${name} | undefined;
            
            if (!row) {
                throw new HTTPException(404, { message: "${name} not found" });
            }
            
            const deleteQuery = db.query(\`DELETE FROM \${this.table} WHERE id = $id\`);
            deleteQuery.run({ $id: id });
            
            return {
                success: true,
                message: "${name} deleted successfully",
                data: this.convertDates(row)
            };
        } catch (error) {
            console.error("Error deleting ${name.toLowerCase()}:", error);
            throw error;
        }
    };
}

// ! -- CUSTOM METHODS --
// You can add custom methods or business logic below this line
// For example: 
// export class Custom${name}Repository extends ${name}Repository {
//     customMethod = async () => {
//         // Your custom logic here
//    }
// }

export const Repository = new ${name}Repository();`;
// src/generators/languages/typescript/templates/framework/hono/schema/sql.ts
var generateSqlSchema3 = (name, fields) => `import { z } from "zod"

export class ${name} {
    constructor(data: Partial<${pluralize(name)}>) {
        Object.assign(this, data)
    }
}

const ${name}Schema = z.object({
    ${fields.map((f) => `${f.name}: z.${f.type}()`).join(`,
    `)}
})

const WithIdSchema = z.object({
    id: z.number()
})

const TimestampSchema = z.object({
    createdAt: z.date(),
    updatedAt: z.date()
})

export const ${name}IdValidate = z.object({
    id: z.coerce.number().positive("ID harus positif")
})

export const Create${name}Validate = ${name}Schema

export const ${pluralize(name)}Validate = ${name}Schema
    .merge(WithIdSchema)
    .merge(TimestampSchema)

export const Update${name}Validate = ${name}Schema.partial()

export type Create${name} = z.infer<typeof Create${name}Validate>
export type ${pluralize(name)} = z.infer<typeof ${pluralize(name)}Validate>
export type Update${name} = z.infer<typeof Update${name}Validate>
export type ${name}Id = z.infer<typeof ${name}IdValidate>
`;
// src/generators/languages/typescript/templates/framework/hono/schema/mongodb.ts
var generateMongodbSchema3 = (name, fields) => `import { z } from "zod"
import { ObjectId } from "mongodb"

export class ${name} {
    constructor(data: Partial<${pluralize(name)}>) {
        Object.assign(this, data)
    }
}

const ${name}Schema = z.object({
    ${fields.map((f) => `${f.name}: z.${f.type}()`).join(`,
    `)}
})

const WithIdSchema = z.object({
    _id: z.instanceof(ObjectId)
})

const TimestampSchema = z.object({
    createdAt: z.date(),
    updatedAt: z.date()
})

export const ${name}IdValidate = z.object({
    id: z.string().regex(/^[0-9a-fA-F]{24}$/, "Invalid ObjectId format")
})

export const Create${name}Validate = ${name}Schema

export const ${pluralize(name)}Validate = ${name}Schema
    .merge(WithIdSchema)
    .merge(TimestampSchema)

export const Update${name}Validate = ${name}Schema.partial()

export type Create${name} = z.infer<typeof Create${name}Validate>
export type ${pluralize(name)} = z.infer<typeof ${pluralize(name)}Validate>
export type Update${name} = z.infer<typeof Update${name}Validate>
export type ${name}Id = z.infer<typeof ${name}IdValidate>
`;
// src/generators/languages/typescript/templates/framework/hono/schema/mongoose.ts
var generateMongooseSchema3 = (name, fields) => {
  const mapTypeToMongoose = (zodType) => {
    const typeMap = {
      string: "String",
      number: "Number",
      boolean: "Boolean",
      date: "Date",
      array: "Array",
      object: "Object"
    };
    return typeMap[zodType] || "String";
  };
  const mapTypeToZod = (type) => {
    const typeMap = {
      string: "z.string()",
      number: "z.number()",
      boolean: "z.boolean()",
      date: "z.date()",
      array: "z.array(z.any())",
      object: "z.object({})"
    };
    return typeMap[type] || "z.string()";
  };
  return `import { z } from "zod";
import mongoose from "mongoose";

// Definisi schema mongoose
const ${name.toLowerCase()}Schema = new mongoose.Schema({
    ${fields.map((f) => `${f.name}: {
        type: ${mapTypeToMongoose(f.type)},
        required: true
    }`).join(`,
    `)}
}, {
    timestamps: true
});

// Model mongoose
export const ${name} = mongoose.model('${name}', ${name.toLowerCase()}Schema);

// Zod schema untuk validasi
const ${name}Schema = z.object({
    ${fields.map((f) => `${f.name}: ${mapTypeToZod(f.type)}`).join(`,
    `)}
})

const TimestampSchema = z.object({
    createdAt: z.date(),
    updatedAt: z.date()
})

export const ${name}IdValidate = z.object({
    id: z.string().refine((val) => mongoose.Types.ObjectId.isValid(val), {
        message: "ID harus berupa ObjectId yang valid"
    })
})

export const Create${name}Validate = ${name}Schema

export const ${pluralize(name)}Validate = ${name}Schema
    .merge(z.object({
        _id: z.instanceof(mongoose.Types.ObjectId).or(z.string())
    }))
    .merge(TimestampSchema)

export const Update${name}Validate = ${name}Schema.partial()

export type Create${name} = z.infer<typeof Create${name}Validate>
export type ${pluralize(name)} = z.infer<typeof ${pluralize(name)}Validate>
export type Update${name} = z.infer<typeof Update${name}Validate>
export type ${name}Id = z.infer<typeof ${name}IdValidate>
`;
};
// src/generators/languages/typescript/templates/framework/hono/service/mongodb.ts
var generateMongodbService3 = (name, pluralName) => `import { Repository as ${name} } from "./${name.toLowerCase()}.repository";
import type { Create${name}, Update${name} } from "./${name.toLowerCase()}.schema";

export const Service = {
    create: async (data: Create${name}) => {
        try {
            return await ${name}.create(data);
        } catch (error) {
            console.error("Service error creating ${name.toLowerCase()}:", error);
            throw error;
        }
    },
    
    getAll: async () => {
        try {
            return await ${name}.findAll();
        } catch (error) {
            console.error("Service error getting all ${pluralName.toLowerCase()}:", error);
            throw error;
        }
    },
    
    getById: async (id: string) => {
        try {
            return await ${name}.findById({ id });
        } catch (error) {
            console.error("Service error getting ${name.toLowerCase()} by id:", error);
            throw error;
        }
    },
    
    update: async (id: string, data: Update${name}) => {
        try {
            return await ${name}.update({ id }, data);
        } catch (error) {
            console.error("Service error updating ${name.toLowerCase()}:", error);
            throw error;
        }
    },
    
    delete: async (id: string) => {
        try {
            return await ${name}.delete({ id });
        } catch (error) {
            console.error("Service error deleting ${name.toLowerCase()}:", error);
            throw error;
        }
    }
};`;
// src/generators/languages/typescript/templates/framework/hono/service/mongoose.ts
var generateMongooseService3 = (name, pluralName) => `import { db } from '../../config';
import type { Create${name}, Update${name} } from './${name.toLowerCase()}.schema';
import { ${name} } from './${name.toLowerCase()}.schema';
import { HTTPException } from 'hono/http-exception';

export class ${name}Service {
    create = async (data: Create${name}) => {
        try {
            const ${name.toLowerCase()} = new ${name}(data);
            const saved${name} = await ${name.toLowerCase()}.save();
            
            return {
                success: true,
                message: "${name} created successfully",
                data: saved${name}
            };
        } catch (error) {
            console.error("Error creating ${name.toLowerCase()}:", error);
            throw error;
        }
    };

    getAll = async () => {
        try {
            const ${pluralName.toLowerCase()} = await ${name}.find();
                
            return {
                success: true,
                data: ${pluralName.toLowerCase()}
            };
        } catch (error) {
            console.error("Error fetching ${pluralName.toLowerCase()}:", error);
            throw error;
        }
    };

    getById = async (id: string) => {
        try {
            if (!db.Types.ObjectId.isValid(id)) {
                throw new HTTPException(400, { message: "Invalid ${name.toLowerCase()} ID" });
            }
            
            const ${name.toLowerCase()} = await ${name}.findById(id);
                
            if (!${name.toLowerCase()}) {
                throw new HTTPException(404, { message: "${name} not found" });
            }
            
            return {
                success: true,
                data: ${name.toLowerCase()}
            };
        } catch (error) {
            console.error("Error finding ${name.toLowerCase()}:", error);
            throw error;
        }
    };

    update = async (id: string, data: Update${name}) => {
        try {
            if (!db.Types.ObjectId.isValid(id)) {
                throw new HTTPException(400, { message: "Invalid ${name.toLowerCase()} ID" });
            }
            
            const updated${name} = await ${name}.findByIdAndUpdate(
                id,
                { ...data },
                { new: true }
            );
            
            if (!updated${name}) {
                throw new HTTPException(404, { message: "${name} not found" });
            }
            
            return {
                success: true,
                message: "${name} updated successfully",
                data: updated${name}
            };
        } catch (error) {
            console.error("Error updating ${name.toLowerCase()}:", error);
            throw error;
        }
    };

    delete = async (id: string) => {
        try {
            if (!db.Types.ObjectId.isValid(id)) {
                throw new HTTPException(400, { message: "Invalid ${name.toLowerCase()} ID" });
            }
            
            const deleted${name} = await ${name}.findByIdAndDelete(id);
                
            if (!deleted${name}) {
                throw new HTTPException(404, { message: "${name} not found" });
            }
            
            return {
                success: true,
                message: "${name} deleted successfully",
                data: deleted${name}
            };
        } catch (error) {
            console.error("Error deleting ${name.toLowerCase()}:", error);
            throw error;
        }
    };
}

export const Service = new ${name}Service();
`;
// src/generators/languages/typescript/templates/framework/hono/service/sql.ts
var generateSqlService3 = (name, pluralName) => `import { Repository as ${name} } from "./${name.toLowerCase()}.repository";
import type { Create${name}, Update${name} } from "./${name.toLowerCase()}.schema";

export const Service = {
    create: async (data: Create${name}) => {
        try {
            return await ${name}.create(data);
        } catch (error) {
            console.error("Service error creating ${name.toLowerCase()}:", error);
            throw error;
        }
    },
    
    getAll: async () => {
        try {
            return await ${name}.findAll();
        } catch (error) {
            console.error("Service error getting all ${pluralName.toLowerCase()}:", error);
            throw error;
        }
    },
    
    getById: async (id: string) => {
        try {
            return await ${name}.findById({ id: Number(id) });
        } catch (error) {
            console.error("Service error getting ${name.toLowerCase()} by id:", error);
            throw error;
        }
    },
    
    update: async (id: string, data: Update${name}) => {
        try {
            return await ${name}.update({ id: Number(id) }, data);
        } catch (error) {
            console.error("Service error updating ${name.toLowerCase()}:", error);
            throw error;
        }
    },
    
    delete: async (id: string) => {
        try {
            return await ${name}.delete({ id: Number(id) });
        } catch (error) {
            console.error("Service error deleting ${name.toLowerCase()}:", error);
            throw error;
        }
    }
};`;
// src/generators/languages/typescript/templates/framework/hono/controller.ts
var generateController3 = (name, pluralName) => `import { Hono } from "hono"
import { zValidator } from "@hono/zod-validator"
import { Create${name}Validate, Update${name}Validate } from "./${name.toLowerCase()}.schema"
import { Service as ${name} } from "./${name.toLowerCase()}.service"

export const ${pluralName.toLowerCase()} = new Hono()
    .post('/',
        zValidator('json', Create${name}Validate),
        async (c) => {
            const body = c.req.valid('json')
            const result = await ${name}.create(body)
            return c.json(result, 201)
        }
    )
    .get('/',
        async (c) => {
            const result = await ${name}.getAll()
            return c.json(result)
        }
    )
    .get('/:id',
        async (c) => {
            const { id } = c.req.param()
            const result = await ${name}.getById(id)
            return c.json(result)
        }
    )
    .put('/:id',
        zValidator('json', Update${name}Validate),
        async (c) => {
            const { id } = c.req.param()
            const body = c.req.valid('json')
            const result = await ${name}.update(id, body)
            return c.json(result)
        }
    )
    .delete('/:id',
        async (c) => {
            const { id } = c.req.param()
            const result = await ${name}.delete(id)
            return c.json(result)
        }
    )`;
// src/generators/languages/typescript/templates/framework/hono/server.ts
var generateServer3 = () => `import { Hono } from "hono"
import { cors } from "hono/cors"
import { logger } from "hono/logger"
import { router } from "./router"
import { errorHandler } from "./error"

const app = new Hono()

// Middleware
app.use("*", logger())
app.use("*", cors())

// Routes
app.route("/api", router)

// Error Handler 
app.onError(errorHandler)

export default app`;
// src/generators/languages/typescript/templates/framework/hono/error.ts
var generateError3 = () => `import type { Context } from 'hono'
import { HTTPException } from 'hono/http-exception'
import { ZodError } from 'zod'

export const errorHandler = (err: Error, c: Context) => {
    // Log error utk debugging
    console.error("Error:", err)
    
    // Handle Zod validation errors
    if (err instanceof ZodError) {
        return c.json({
            success: false,
            message: "Validasi gagal",
            errors: err.errors.map(e => ({
                field: e.path.join('.'),
                message: e.message
            })),
            data: null
        }, 400)
    }
    
    // Handle HTTP exceptions
    if (err instanceof HTTPException) {
        return c.json({
            success: false,
            message: err.message,
            data: null
        }, err.status)
    }
    
    // Handle other errors
    return c.json({
        success: false,
        message: err instanceof Error ? err.message : "Terjadi kesalahan internal server",
        data: null
    }, 500)
}`;
// src/generators/languages/typescript/templates/framework/next/repository/postgresql.ts
var generatePostgresRepository4 = (name, pluralName) => `import { db } from "../../config";
import type { Create${name}, Update${name}, ${pluralName}, ${name}Id } from "./${name.toLowerCase()}.schema";
import { ${name} } from "./${name.toLowerCase()}.schema";

export type Result<T> = {
    success: boolean;
    message?: string;
    data: T | null;
    error?: unknown;
};

export class ${name}Repository {
    private readonly table = "${pluralName.toLowerCase()}";
    
    create = async (data: Create${name}): Promise<Result<${pluralName}>> => {
        try {
            const fields = Object.keys(data).map(key => \`"\${key}"\`);
            const values = Object.values(data);
            const placeholders = values.map((_, i) => \`$\${i + 1}\`).join(', ');
            
            const query = \`
                INSERT INTO \${this.table} 
                (\${fields.join(', ')}, "createdAt", "updatedAt")
                VALUES (\${placeholders}, NOW(), NOW())
                RETURNING *
            \`;
            
            const result = await db.query(query, values);
            
            if (!result.rows[0]) {
                throw new Error("Failed to create ${name.toLowerCase()}");
            }
            
            return {
                success: true,
                message: "${name} created successfully",
                data: new ${name}(result.rows[0]) as ${pluralName}
            };
        } catch (error) {
            throw new Error(error instanceof Error ? error.message : "Failed to create ${name.toLowerCase()}");
        }
    };
    
    findAll = async (): Promise<Result<${pluralName}[]>> => {
        try {
            const result = await db.query<${pluralName}>(\`
                SELECT * FROM \${this.table}
            \`);
            
            return {
                success: true,
                data: result.rows.map(row => new ${name}(row) as ${pluralName})
            };
        } catch (error) {
            console.log(error)
            throw new Error("Failed to fetch ${pluralName.toLowerCase()}");
        }
    };
    
    findById = async ({ id }: ${name}Id): Promise<Result<${pluralName}>> => {
        try {
            const result = await db.query(\`
                SELECT *
                FROM \${this.table} 
                WHERE "id" = $1
            \`, [id]);
            
            if (!result.rows[0]) {
                throw new Error("${name} not found");
            }
            
            return {
                success: true,
                data: new ${name}(result.rows[0]) as ${pluralName}
            };
        } catch (error) {
            throw new Error(error instanceof Error ? error.message : "Failed to find ${name.toLowerCase()}");
        }
    };
    
    update = async ({ id }: ${name}Id, data: Update${name}): Promise<Result<${pluralName}>> => {
        try {
            const fields = Object.keys(data);
            const values = Object.values(data);
            const setClause = fields
                .map((field, i) => \`"\${field}" = $\${i + 1}\`)
                .join(', ');
            
            const query = \`
                UPDATE \${this.table}
                SET \${setClause}, "updatedAt" = NOW()
                WHERE "id" = $\${values.length + 1}
                RETURNING *
            \`;
            
            const result = await db.query(query, [...values, id]);
            
            if (!result.rows[0]) {
                throw new Error("${name} not found");
            }
            
            return {
                success: true,
                message: "${name} updated successfully",
                data: new ${name}(result.rows[0]) as ${pluralName}
            };
        } catch (error) {
            throw new Error(error instanceof Error ? error.message : "Failed to update ${name.toLowerCase()}");
        }
    };
    
    delete = async ({ id }: ${name}Id): Promise<Result<${pluralName}>> => {
        try {
            const findResult = await db.query(\`
                SELECT *
                FROM \${this.table} 
                WHERE "id" = $1
            \`, [id]);
            
            if (!findResult.rows[0]) {
                throw new Error("${name} not found");
            }
            
            await db.query(\`
                DELETE FROM \${this.table} 
                WHERE "id" = $1
            \`, [id]);
            
            return {
                success: true,
                message: "${name} deleted successfully",
                data: new ${name}(findResult.rows[0]) as ${pluralName}
            };
        } catch (error) {
            throw new Error(error instanceof Error ? error.message : "Failed to delete ${name.toLowerCase()}");
        }
    };
}

// ! -- CUSTOM METHODS --
// You can add custom methods or business logic below this line
// For example: 
// export class Custom${name}Repository extends ${name}Repository {
//     customMethod = async () => {
//         // Your custom logic here
//    }
// }

export const Repository = new ${name}Repository();`;
// src/generators/languages/typescript/templates/framework/next/repository/sqlite.ts
var generateSqliteRepository4 = (name, pluralName) => `import { db } from "../../config";
import type { Create${name}, Update${name}, ${pluralName}, ${name}Id } from "./${name.toLowerCase()}.schema";
import { ${name} } from "./${name.toLowerCase()}.schema";

export type Result<T> = {
    success: boolean;
    message?: string;
    data: T | null;
    error?: unknown;
};

export class ${name}Repository {
    private readonly table = "${pluralName.toLowerCase()}";
    
    create = async (data: Create${name}): Promise<Result<${pluralName}>> => {
        try {
            const fields = Object.keys(data);
            const values = Object.values(data);
            const placeholders = values.map(() => '?').join(', ');
            
            const query = \`
                INSERT INTO \${this.table} 
                (\${fields.join(', ')}, createdAt, updatedAt)
                VALUES (\${placeholders}, datetime('now'), datetime('now'))
                RETURNING *;
            \`;
            
            const [newItem] = await db.query(query, values);
            
            if (!newItem) {
                throw new Error("Failed to create ${name.toLowerCase()}");
            }
            
            return {
                success: true,
                message: "${name} created successfully",
                data: new ${name}(newItem) as ${pluralName}
            };
        } catch (error) {
            throw new Error(error instanceof Error ? error.message : "Failed to create ${name.toLowerCase()}");
        }
    };
    
    findAll = async (): Promise<Result<${pluralName}[]>> => {
        try {
            const rows = await db.query(\`
                SELECT *
                FROM \${this.table}
            \`);
            
            return {
                success: true,
                data: rows.map((row: ${pluralName}) => new ${name}(row) as ${pluralName})
            };
        } catch (error) {
            console.log(error)
            throw new Error("Failed to fetch ${pluralName.toLowerCase()}");
        }
    };
    
    findById = async ({ id }: ${name}Id): Promise<Result<${pluralName}>> => {
        try {
            const [row] = await db.query(\`
                SELECT *
                FROM \${this.table} 
                WHERE id = ?
            \`, [id]);
            
            if (!row) {
                throw new Error("${name} not found");
            }
            
            return {
                success: true,
                data: new ${name}(row) as ${pluralName}
            };
        } catch (error) {
            throw new Error(error instanceof Error ? error.message : "Failed to find ${name.toLowerCase()}");
        }
    };
    
    update = async ({ id }: ${name}Id, data: Update${name}): Promise<Result<${pluralName}>> => {
        try {
            const fields = Object.keys(data);
            const values = Object.values(data);
            const setClause = fields
                .map(field => \`\${field} = ?\`)
                .join(', ');
            
            const query = \`
                UPDATE \${this.table}
                SET \${setClause}, updatedAt = datetime('now')
                WHERE id = ?
            \`;
            
            await db.query(query, [...values, id]);
            const [row] = await db.query(\`
                SELECT * 
                FROM \${this.table} 
                WHERE id = ?
            \`, [id]);
            
            if (!row) {
                throw new Error("${name} not found");
            }
            
            return {
                success: true,
                message: "${name} updated successfully",
                data: new ${name}(row) as ${pluralName}
            };
        } catch (error) {
            throw new Error(error instanceof Error ? error.message : "Failed to update ${name.toLowerCase()}");
        }
    };
    
    delete = async ({ id }: ${name}Id): Promise<Result<${pluralName}>> => {
        try {
            const [row] = await db.query(\`
                SELECT * 
                FROM \${this.table} 
                WHERE id = ?
            \`, [id]);
            
            if (!row) {
                throw new Error("${name} not found");
            }
            
            await db.query(\`
                DELETE FROM \${this.table} 
                WHERE id = ?
            \`, [id]);
            
            return {
                success: true,
                message: "${name} deleted successfully",
                data: new ${name}(row) as ${pluralName}
            };
        } catch (error) {
            throw new Error(error instanceof Error ? error.message : "Failed to delete ${name.toLowerCase()}");
        }
    };
}

// ! -- CUSTOM METHODS --
// You can add custom methods or business logic below this line
// For example: 
// export class Custom${name}Repository extends ${name}Repository {
//     customMethod = async () => {
//         // Your custom logic here
//     }
// }

export const Repository = new ${name}Repository()`;
// src/generators/languages/typescript/templates/framework/next/repository/mariadb.ts
var generateMariadbRepository4 = (name, pluralName) => `import { db } from "../../config";
import type { Create${name}, Update${name}, ${pluralName}, ${name}Id } from "./${name.toLowerCase()}.schema";
import { ${name} } from "./${name.toLowerCase()}.schema";

export type Result<T> = {
    success: boolean;
    message?: string;
    data: T | null;
    error?: unknown;
};

export class ${name}Repository {
    private readonly table = "${pluralName.toLowerCase()}";
    
    create = async (data: Create${name}): Promise<Result<${pluralName}>> => {
        try {
            const fields = Object.keys(data);
            const values = Object.values(data);
            const placeholders = values.map(() => '?').join(', ');
            
            const result = await db.query(\`
                INSERT INTO \${this.table} 
                (\${fields.join(', ')}, createdAt, updatedAt)
                VALUES (\${placeholders}, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
            \`, values);
            
            const newItem = await db.query(\`
                SELECT *
                FROM \${this.table} 
                WHERE id = ?
            \`, [result.insertId]);
            
            if (!newItem?.[0]) {
                throw new Error("Failed to create ${name.toLowerCase()}");
            }
            
            return {
                success: true,
                message: "${name} created successfully",
                data: new ${name}(newItem[0]) as ${pluralName}
            };
        } catch (error) {
            console.error('Error in create:', error);
            throw new Error(error instanceof Error ? error.message : "Failed to create ${name.toLowerCase()}");
        }
    };
    
    findAll = async (): Promise<Result<${pluralName}[]>> => {
        try {
            const rows = await db.query(\`
                SELECT * 
                FROM \${this.table}
                ORDER BY id DESC
            \`);
            
            return {
                success: true,
                data: rows.map((row: ${pluralName}) => new ${name}(row) as ${pluralName})
            };
        } catch (error) {
            console.error('Error in findAll:', error);
            throw new Error("Failed to fetch ${pluralName.toLowerCase()}");
        }
    };
    
    findById = async ({ id }: ${name}Id): Promise<Result<${pluralName}>> => {
        try {
            const row = await db.query(\`
                SELECT * 
                FROM \${this.table} 
                WHERE id = ?
            \`, [id]);
            
            if (!row?.[0]) {
                throw new Error("${name} not found");
            }
            
            return {
                success: true,
                data: new ${name}(row[0]) as ${pluralName}
            };
        } catch (error) {
            console.error('Error in findById:', error);
            throw new Error(error instanceof Error ? error.message : "Failed to find ${name.toLowerCase()}");
        }
    };
    
    update = async ({ id }: ${name}Id, data: Update${name}): Promise<Result<${pluralName}>> => {
        try {
            const fields = Object.keys(data);
            const values = Object.values(data);
            const setClause = fields
                .map(field => \`\${field} = ?\`)
                .join(', ');
            
            await db.query(\`
                UPDATE \${this.table}
                SET \${setClause}, updatedAt = CURRENT_TIMESTAMP
                WHERE id = ?
            \`, [...values, id]);
            
            const row = await db.query(\`
                SELECT * 
                FROM \${this.table} 
                WHERE id = ?
            \`, [id]);
            
            if (!row?.[0]) {
                throw new Error("${name} not found");
            }
            
            return {
                success: true,
                message: "${name} updated successfully",
                data: new ${name}(row[0]) as ${pluralName}
            };
        } catch (error) {
            console.error('Error in update:', error);
            throw new Error(error instanceof Error ? error.message : "Failed to update ${name.toLowerCase()}");
        }
    };
    
    delete = async ({ id }: ${name}Id): Promise<Result<${pluralName}>> => {
        try {
            const row = await db.query(\`
                SELECT * 
                FROM \${this.table} 
                WHERE id = ?
            \`, [id]);
            
            if (!row?.[0]) {
                throw new Error("${name} not found");
            }
            
            await db.query(\`
                DELETE FROM \${this.table} 
                WHERE id = ?
            \`, [id]);
            
            return {
                success: true,
                message: "${name} deleted successfully",
                data: new ${name}(row[0]) as ${pluralName}
            };
        } catch (error) {
            console.error('Error in delete:', error);
            throw new Error(error instanceof Error ? error.message : "Failed to delete ${name.toLowerCase()}");
        }
    };
}

// ! -- CUSTOM METHODS --
// You can add custom methods or business logic below this line
// For example: 
// export class Custom${name}Repository extends ${name}Repository {
//     customMethod = async () => {
//         // Your custom logic here
//     }
// }

export const Repository = new ${name}Repository()`;
// src/generators/languages/typescript/templates/framework/next/repository/mongodb.ts
var generateMongoRepository4 = (name, pluralName) => `import { ObjectId } from "mongodb";
import { db } from "../../config";
import type { Create${name}, Update${name}, ${pluralName}, ${name}Id } from "./${name.toLowerCase()}.schema";
import { ${name} } from "./${name.toLowerCase()}.schema";
import { NotFoundError, BadRequestError } from "../../error";

export class ${name}Repository {
    private readonly collection = "${pluralName.toLowerCase()}";
    
    private getCollection = async () => {
        return db.collection(this.collection);
    };
    
    create = async (data: Create${name}) => {
        try {
            const doc = {
                ...data,
                createdAt: new Date(),
                updatedAt: new Date()
            };
            
            const collection = await this.getCollection();
            const result = await collection.insertOne(doc);
            
            if (!result.acknowledged) {
                throw new BadRequestError("Failed to create ${name.toLowerCase()}");
            }
            
            return {
                success: true,
                message: "${name} created successfully",
                data: new ${name}({ ...doc, _id: result.insertedId }) as ${pluralName}
            };
        } catch (error) {
            console.error("Error creating ${name.toLowerCase()}:", error);
            throw error;
        }
    };

    findAll = async () => {
        try {
            const collection = await this.getCollection();
            const docs = await collection
                .find({})
                .sort({ _id: -1 })
                .toArray() as ${pluralName}[];
                
            return {
                success: true,
                data: docs.map(doc => new ${name}(doc) as ${pluralName})
            };
        } catch (error) {
            console.error("Error finding all ${pluralName.toLowerCase()}:", error);
            throw error;
        }
    };

    findById = async ({ id }: ${name}Id) => {
        try {
            const collection = await this.getCollection();
            const doc = await collection
                .findOne({ _id: new ObjectId(id) }) as ${pluralName} | null;
                
            if (!doc) {
                throw new NotFoundError(\`${name} with id \${id} not found\`);
            }
            
            return {
                success: true,
                data: new ${name}(doc) as ${pluralName}
            };
        } catch (error) {
            console.error("Error finding ${name.toLowerCase()} by id:", error);
            throw error;
        }
    };

    update = async ({ id }: ${name}Id, data: Update${name}) => {
        try {
            const collection = await this.getCollection();
            const result = await collection
                .findOneAndUpdate(
                    { _id: new ObjectId(id) },
                    { 
                        $set: {
                            ...data,
                            updatedAt: new Date()
                        }
                    },
                    { returnDocument: 'after' }
                );
            
            if (!result) {
                throw new NotFoundError(\`${name} with id \${id} not found\`);
            }
            
            return {
                success: true,
                message: "${name} updated successfully",
                data: new ${name}(result) as ${pluralName}
            };
        } catch (error) {
            console.error("Error updating ${name.toLowerCase()}:", error);
            throw error;
        }
    };

    delete = async ({ id }: ${name}Id) => {
        try {
            const collection = await this.getCollection();
            const doc = await collection
                .findOne({ _id: new ObjectId(id) });
                
            if (!doc) {
                throw new NotFoundError(\`${name} with id \${id} not found\`);
            }

            await collection.deleteOne({ _id: new ObjectId(id) });
            
            return {
                success: true,
                message: "${name} deleted successfully",
                data: new ${name}(doc) as ${pluralName}
            };
        } catch (error) {
            console.error("Error deleting ${name.toLowerCase()}:", error);
            throw error;
        }
    };
}

// ! -- CUSTOM METHODS --
// You can add custom methods or business logic below this line
// For example: 
// export class Custom${name}Repository extends ${name}Repository {
//     customMethod = async () => {
//         // Your custom logic here
//     }
// }

export const Repository = new ${name}Repository();`;
// src/generators/languages/typescript/templates/framework/next/schema/mongoose.ts
var generateMongooseSchema4 = (name, fields) => {
  const mapTypeToMongoose = (zodType) => {
    const typeMap = {
      string: "String",
      number: "Number",
      boolean: "Boolean",
      date: "Date",
      array: "Array",
      object: "Object"
    };
    return typeMap[zodType] || "String";
  };
  const mapTypeToZod = (type) => {
    const typeMap = {
      string: "z.string()",
      number: "z.number()",
      boolean: "z.boolean()",
      date: "z.date()",
      array: "z.array(z.any())",
      object: "z.object({})"
    };
    return typeMap[type] || "z.string()";
  };
  return `import { z } from "zod";
import mongoose from "mongoose";

// Definisi schema mongoose
const ${name.toLowerCase()}Schema = new mongoose.Schema({
    ${fields.map((f) => `${f.name}: {
        type: ${mapTypeToMongoose(f.type)},
        required: true
    }`).join(`,
    `)}
}, {
    timestamps: true
});

// Model mongoose
export const ${name} = mongoose.models.${name} || mongoose.model('${name}', ${name.toLowerCase()}Schema);

// Zod schema untuk validasi
const ${name}Schema = z.object({
    ${fields.map((f) => `${f.name}: ${mapTypeToZod(f.type)}`).join(`,
    `)}
})

const TimestampSchema = z.object({
    createdAt: z.date(),
    updatedAt: z.date()
})

export const ${name}IdValidate = z.object({
    id: z.string().refine((val) => mongoose.Types.ObjectId.isValid(val), {
        message: "ID harus berupa ObjectId yang valid"
    })
})

export const Create${name}Validate = ${name}Schema

export const ${pluralize(name)}Validate = ${name}Schema
    .merge(z.object({
        _id: z.instanceof(mongoose.Types.ObjectId).or(z.string())
    }))
    .merge(TimestampSchema)

export const Update${name}Validate = ${name}Schema.partial()

export type Create${name} = z.infer<typeof Create${name}Validate>
export type ${pluralize(name)} = z.infer<typeof ${pluralize(name)}Validate>
export type Update${name} = z.infer<typeof Update${name}Validate>
export type ${name}Id = z.infer<typeof ${name}IdValidate>
`;
};
// src/generators/languages/typescript/templates/framework/next/schema/mongodb.ts
var generateMongodbSchema4 = (name, fields) => `import { z } from "zod"
import { ObjectId } from "mongodb"

export class ${name} {
    constructor(data: Partial<${pluralize(name)}>) {
        Object.assign(this, data)
    }
}

const ${name}Schema = z.object({
    ${fields.map((f) => `${f.name}: z.${f.type}()`).join(`,
    `)}
})

const WithIdSchema = z.object({
    _id: z.instanceof(ObjectId)
})

const TimestampSchema = z.object({
    createdAt: z.date(),
    updatedAt: z.date()
})

export const ${name}IdValidate = z.object({
    id: z.string().regex(/^[0-9a-fA-F]{24}$/, "Invalid ObjectId format")
})

export const Create${name}Validate = ${name}Schema

export const ${pluralize(name)}Validate = ${name}Schema
    .merge(WithIdSchema)
    .merge(TimestampSchema)

export const Update${name}Validate = ${name}Schema.partial()

export type Create${name} = z.infer<typeof Create${name}Validate>
export type ${pluralize(name)} = z.infer<typeof ${pluralize(name)}Validate>
export type Update${name} = z.infer<typeof Update${name}Validate>
export type ${name}Id = z.infer<typeof ${name}IdValidate>
`;
// src/generators/languages/typescript/templates/framework/next/schema/sql.ts
var generateSqlSchema4 = (name, fields) => `import { z } from "zod"

export class ${name} {
    constructor(data: Partial<${pluralize(name)}>) {
        Object.assign(this, data)
    }
}

const ${name}Schema = z.object({
    ${fields.map((f) => `${f.name}: z.${f.type}()`).join(`,
    `)}
})

const WithIdSchema = z.object({
    id: z.number()
})

const TimestampSchema = z.object({
    createdAt: z.date(),
    updatedAt: z.date()
})

export const ${name}IdValidate = z.object({
    id: z.coerce.number().positive("ID harus positif")
})

export const Create${name}Validate = ${name}Schema

export const ${pluralize(name)}Validate = ${name}Schema
    .merge(WithIdSchema)
    .merge(TimestampSchema)

export const Update${name}Validate = ${name}Schema.partial()

export type Create${name} = z.infer<typeof Create${name}Validate>
export type ${pluralize(name)} = z.infer<typeof ${pluralize(name)}Validate>
export type Update${name} = z.infer<typeof Update${name}Validate>
export type ${name}Id = z.infer<typeof ${name}IdValidate>
`;
// src/generators/languages/typescript/templates/framework/next/service/mongoose.ts
var generateMongooseService4 = (name, pluralName) => `import { db } from '../../config';
import type { Create${name}, Update${name} } from './${name.toLowerCase()}.schema';
import { ${name}, Create${name}Validate, Update${name}Validate } from './${name.toLowerCase()}.schema';
import { NotFoundError, BadRequestError } from '../../error';

export class ${name}Service {
    create = async (data: Create${name}) => {
        try {
            const validatedData = Create${name}Validate.parse(data);
            
            const ${name.toLowerCase()} = new ${name}(validatedData);
            const saved${name} = await ${name.toLowerCase()}.save();
            
            return {
                success: true,
                message: "${name} created successfully",
                data: saved${name}
            };
        } catch (error) {
            console.error("Error creating ${name.toLowerCase()}:", error);
            throw error;
        }
    };

    getAll = async () => {
        try {
            const ${pluralName.toLowerCase()} = await ${name}.find();
                
            return {
                success: true,
                data: ${pluralName.toLowerCase()}
            };
        } catch (error) {
            console.error("Error getting all ${pluralName.toLowerCase()}:", error);
            throw error;
        }
    };

    getById = async (id: string) => {
        try {
            if (!db.Types.ObjectId.isValid(id)) {
                throw new BadRequestError("Invalid ${name.toLowerCase()} ID");
            }
            
            const ${name.toLowerCase()} = await ${name}.findById(id);
                
            if (!${name.toLowerCase()}) {
                throw new NotFoundError("${name} not found");
            }
            
            return {
                success: true,
                data: ${name.toLowerCase()}
            };
        } catch (error) {
            console.error(\`Error getting ${name.toLowerCase()} with ID \${id}:\`, error);
            throw error;
        }
    };

    update = async (id: string, data: Update${name}) => {
        try {
            if (!db.Types.ObjectId.isValid(id)) {
                throw new BadRequestError("Invalid ${name.toLowerCase()} ID");
            }
            
            // Validasi data dengan Zod
            const validatedData = Update${name}Validate.parse(data);
            
            const updated${name} = await ${name}.findByIdAndUpdate(
                id,
                { ...validatedData },
                { new: true }
            );
            
            if (!updated${name}) {
                throw new NotFoundError("${name} not found");
            }
            
            return {
                success: true,
                message: "${name} updated successfully",
                data: updated${name}
            };
        } catch (error) {
            console.error(\`Error updating ${name.toLowerCase()} with ID \${id}:\`, error);
            throw error;
        }
    };

    delete = async (id: string) => {
        try {
            if (!db.Types.ObjectId.isValid(id)) {
                throw new BadRequestError("Invalid ${name.toLowerCase()} ID");
            }
            
            const deleted${name} = await ${name}.findByIdAndDelete(id);
                
            if (!deleted${name}) {
                throw new NotFoundError("${name} not found");
            }
            
            return {
                success: true,
                message: "${name} deleted successfully",
                data: deleted${name}
            };
        } catch (error) {
            console.error(\`Error deleting ${name.toLowerCase()} with ID \${id}:\`, error);
            throw error;
        }
    };
}

export const Service = new ${name}Service();
`;
// src/generators/languages/typescript/templates/framework/next/service/mongodb.ts
var generateMongodbService4 = (name, pluralName) => `import { Repository as ${name} } from "./${name.toLowerCase()}.repository";
import type { Create${name}, Update${name} } from "./${name.toLowerCase()}.schema";
import { 
    Create${name}Validate, 
    Update${name}Validate,
    ${name}IdValidate
} from "./${name.toLowerCase()}.schema";

export const Service = {
    create: async (data: Create${name}) => {
        try {
            const validated = Create${name}Validate.parse(data);
            return await ${name}.create(validated);
        } catch (error) {
            console.error("Service error creating ${name.toLowerCase()}:", error);
            throw error;
        }
    },
    
    getAll: async () => {
        try {
            return await ${name}.findAll();
        } catch (error) {
            console.error("Service error getting all ${pluralName.toLowerCase()}:", error);
            throw error;
        }
    },
    
    getById: async (id: string) => {
        try {
            const { id: validId } = ${name}IdValidate.parse({ id });
            return await ${name}.findById({ id: validId });
        } catch (error) {
            console.error("Service error getting ${name.toLowerCase()} by id:", error);
            throw error;
        }
    },
    
    update: async (id: string, data: Update${name}) => {
        try {
            const { id: validId } = ${name}IdValidate.parse({ id });
            const validated = Update${name}Validate.parse(data);
            return await ${name}.update({ id: validId }, validated);
        } catch (error) {
            console.error("Service error updating ${name.toLowerCase()}:", error);
            throw error;
        }
    },
    
    delete: async (id: string) => {
        try {
            const { id: validId } = ${name}IdValidate.parse({ id });
            return await ${name}.delete({ id: validId });
        } catch (error) {
            console.error("Service error deleting ${name.toLowerCase()}:", error);
            throw error;
        }
    }
};`;
// src/generators/languages/typescript/templates/framework/next/service/sql.ts
var generateSqlService4 = (name, pluralName) => `import { Repository as ${name} } from "./${name.toLowerCase()}.repository";
import type { Create${name}, Update${name}, ${pluralName} } from "./${name.toLowerCase()}.schema";
import { 
    Create${name}Validate, 
    Update${name}Validate 
} from "./${name.toLowerCase()}.schema";
import type { Result } from "./${name.toLowerCase()}.repository";

export const Service = {
    create: async (data: Create${name}): Promise<Result<${pluralName}>> => {
        try {
            const validated = Create${name}Validate.parse(data);
            return await ${name}.create(validated);
        } catch (error) {
            console.error("Service error creating ${name.toLowerCase()}:", error);
            return {
                success: false,
                message: error instanceof Error ? error.message : "Failed to create ${name.toLowerCase()}",
                data: null
            };
        }
    },
    
    getAll: async (): Promise<Result<${pluralName}[]>> => {
        try {
            return await ${name}.findAll();
        } catch (error) {
            console.error("Service error getting all ${pluralName.toLowerCase()}:", error);
            return {
                success: false,
                message: error instanceof Error ? error.message : "Failed to get all ${pluralName.toLowerCase()}",
                data: null
            };
        }
    },
    
    getById: async (id: string): Promise<Result<${pluralName}>> => {
        try {
            return await ${name}.findById({ id: Number(id) });
        } catch (error) {
            console.error("Service error getting ${name.toLowerCase()} by id:", error);
            return {
                success: false,
                message: error instanceof Error ? error.message : "Failed to get ${name.toLowerCase()} by id",
                data: null
            };
        }
    },
    
    update: async (id: string, data: Update${name}): Promise<Result<${pluralName}>> => {
        try {
            const validated = Update${name}Validate.parse(data);
            return await ${name}.update({ id: Number(id) }, validated);
        } catch (error) {
            console.error("Service error updating ${name.toLowerCase()}:", error);
            return {
                success: false,
                message: error instanceof Error ? error.message : "Failed to update ${name.toLowerCase()}",
                data: null
            };
        }
    },
    
    delete: async (id: string): Promise<Result<${pluralName}>> => {
        try {
            return await ${name}.delete({ id: Number(id) });
        } catch (error) {
            console.error("Service error deleting ${name.toLowerCase()}:", error);
            return {
                success: false,
                message: error instanceof Error ? error.message : "Failed to delete ${name.toLowerCase()}",
                data: null
            };
        }
    }
};`;
// src/generators/languages/typescript/templates/framework/next/controller.ts
var generateController4 = (name, pluralName) => ({
  main: `import { Service as ${name} } from "../../../modules/${pluralName.toLowerCase()}/${name.toLowerCase()}.service";
import { NextResponse } from "next/server";
import { handleError } from "../../../error";

export async function GET() {
    try {
        const result = await ${name}.getAll();
        return NextResponse.json(result);
    } catch (error) {
        return handleError(error);
    }
}

export async function POST(req: Request) {
    try {
        const body = await req.json();
        const result = await ${name}.create(body);
        return NextResponse.json(result, { status: 201 });
    } catch (error) {
        return handleError(error);
    }
}`,
  dynamic: `import { Service as ${name} } from "../../../../modules/${pluralName.toLowerCase()}/${name.toLowerCase()}.service";
import { NextResponse } from "next/server";
import { handleError } from "../../../../error";

export async function GET(_req: Request, { params }: { params: Promise<{ id: string }> }) {
    try {
        const { id } = await params;
        const result = await ${name}.getById(id);
        return NextResponse.json(result);
    } catch (error) {
        return handleError(error);
    }
}

export async function PUT(req: Request, { params }: { params: Promise<{ id: string }> }) {
    try {
        const { id } = await params;
        const body = await req.json();
        const result = await ${name}.update(id, body);
        return NextResponse.json(result);
    } catch (error) {
        return handleError(error);
    }
}

export async function DELETE(_req: Request, { params }: { params: Promise<{ id: string }> }) {
    try {
        const { id } = await params;
        const result = await ${name}.delete(id);
        return NextResponse.json(result);
    } catch (error) {
        return handleError(error);
    }
}`
});
// src/generators/languages/typescript/templates/framework/next/error.ts
var generateError4 = () => `import { NextResponse } from 'next/server';
import { ZodError } from 'zod';

// Kelas error kustom dengan status code
export class HttpError extends Error {
    statusCode: number;
    
    constructor(message: string, statusCode: number) {
        super(message);
        this.statusCode = statusCode;
        this.name = this.constructor.name;
        
        // Untuk mendapatkan stack trace yang benar
        Error.captureStackTrace(this, this.constructor);
    }
}

// Error untuk resource tidak ditemukan (404)
export class NotFoundError extends HttpError {
    constructor(message: string = 'Resource not found') {
        super(message, 404);
    }
}

// Error untuk permintaan yang tidak valid (400)
export class BadRequestError extends HttpError {
    constructor(message: string = 'Bad request') {
        super(message, 400);
    }
}

// Error untuk validasi gagal (422)
export class ValidationError extends HttpError {
    constructor(message: string = 'Validation failed') {
        super(message, 422);
    }
}

// Error untuk autentikasi gagal (401)
export class UnauthorizedError extends HttpError {
    constructor(message: string = 'Unauthorized access') {
        super(message, 401);
    }
}

// Error untuk akses terlarang (403)
export class ForbiddenError extends HttpError {
    constructor(message: string = 'Access forbidden') {
        super(message, 403);
    }
}

// Error untuk konflik data (409)
export class ConflictError extends HttpError {
    constructor(message: string = 'Resource conflict') {
        super(message, 409);
    }
}

// Fungsi untuk membuat respons error
export const createErrorResponse = (
    message: string, 
    statusCode: number = 500, 
    errors?: Record<string, unknown>
) => {
    return NextResponse.json({
        success: false,
        message,
        ...(errors && { errors })
    }, { status: statusCode });
};

// Fungsi untuk menangani error
export const handleError = (error: unknown): NextResponse => {
    console.error('Error caught by error handler:', error);
    
    // HttpError kustom
    if (error instanceof HttpError) {
        return createErrorResponse(error.message, error.statusCode);
    }
    
    // Zod validation errors
    if (error instanceof ZodError) {
        const formattedErrors = error.errors.map(err => ({
            path: err.path.join('.'),
            message: err.message
        }));
        
        return createErrorResponse('Validation failed', 422, { details: formattedErrors });
    }
    
    // Error MongoDB duplicate key
    if (error instanceof Error && error.message.includes('duplicate key error')) {
        return createErrorResponse('Duplicate entry found', 409);
    }
    
    // Error MongoDB validation
    if (error instanceof Error && error.name === 'ValidationError') {
        return createErrorResponse('Database validation failed', 422);
    }
    
    // Error MongoDB cast
    if (error instanceof Error && error.name === 'CastError') {
        return createErrorResponse('Invalid data format', 400);
    }
    
    // Generic errors
    if (error instanceof Error) {
        // Jika error memiliki pesan yang jelas, gunakan itu
        const message = error.message || 'Something went wrong';
        return createErrorResponse(message, 500);
    }
    
    // Unknown errors
    return createErrorResponse('An unexpected error occurred', 500);
};`;
// src/generators/languages/typescript/templates/database/postgresql/migration.ts
var generatePostgresMigration = (name, pluralName, fields) => {
  const pgTypes = {
    string: "VARCHAR(255)",
    number: "INTEGER",
    boolean: "BOOLEAN",
    date: "TIMESTAMP"
  };
  const columns = fields.map((field) => {
    const pgType = pgTypes[field.type] || "VARCHAR(255)";
    return `    "${field.name}" ${pgType}`;
  }).join(`,
`);
  return `import { sql } from "../../config";

export async function up() {
    await sql\`
        CREATE TABLE IF NOT EXISTS ${pluralName.toLowerCase()} (
            id SERIAL PRIMARY KEY,
            ${columns},
            "createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
            "updatedAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        )
    \`.simple();
    
    console.log('\u2705 Migration ${name} created successfully');
}

export async function down() {
    await sql\`DROP TABLE IF EXISTS ${pluralName.toLowerCase()}\`.simple();
    console.log('\u2705 Migration ${name} dropped successfully');
}

// Run migration
if (process.argv[2] === 'up') {
    up().catch(console.error).finally(() => process.exit());
}

if (process.argv[2] === 'down') {
    down().catch(console.error).finally(() => process.exit());
}`;
};
// src/generators/languages/typescript/templates/database/mariadb/migration.ts
var generateMariadbMigration = (name, pluralName, fields) => {
  const mariaTypes = {
    string: "VARCHAR(255)",
    number: "INT",
    boolean: "TINYINT(1)",
    date: "DATETIME"
  };
  const columns = fields.map((field) => {
    const mariaType = mariaTypes[field.type] || "VARCHAR(255)";
    return `    ${field.name} ${mariaType}`;
  }).join(`,
`);
  return `import { db } from "../../config";

export async function up() {
    await db.query(\`
        CREATE TABLE IF NOT EXISTS ${pluralName.toLowerCase()} (
            id INT AUTO_INCREMENT PRIMARY KEY,
${columns},
            createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
            updatedAt DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
        )
    \`);
    
    console.log('\u2705 Migration ${name} created successfully');
}

export async function down() {
    await db.query(\`
        DROP TABLE IF EXISTS ${pluralName.toLowerCase()}
    \`);
    
    console.log('\u2705 Migration ${name} dropped successfully');
}

// Run migration
if (process.argv[2] === 'up') {
    up()
        .catch(console.error)
        .finally(() => process.exit());
}

if (process.argv[2] === 'down') {
    down()
        .catch(console.error)
        .finally(() => process.exit());
}`;
};
// src/generators/languages/typescript/templates/database/sqlite/migration.ts
var generateSqliteMigration = (name, pluralName, fields) => {
  const sqliteTypes = {
    string: "TEXT",
    number: "INTEGER",
    boolean: "INTEGER",
    date: "TEXT"
  };
  const columns = fields.map((field) => {
    const sqliteType = sqliteTypes[field.type] || "TEXT";
    return `    ${field.name} ${sqliteType}`;
  }).join(`,
`);
  return `import { db } from "../../config";

export async function up() {
    db.query(\`
        CREATE TABLE IF NOT EXISTS ${pluralName.toLowerCase()} (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
${columns},
            createdAt TEXT DEFAULT (datetime('now')),
            updatedAt TEXT DEFAULT (datetime('now'))
        );
    \`).run();
    
    console.log('\u2705 Migration ${name} created successfully');
}

export async function down() {
    db.query(\`
        DROP TABLE IF EXISTS ${pluralName.toLowerCase()}
    \`).run();
    
    console.log('\u2705 Migration ${name} dropped successfully');
}

// Run migration
if (process.argv[2] === 'up') {
    up()
        .catch(console.error)
        .finally(() => process.exit());
}

if (process.argv[2] === 'down') {
    down()
        .catch(console.error)
        .finally(() => process.exit());
}`;
};
// src/generators/languages/typescript/templates/database/postgresql/seeding.ts
var generatePostgresSeeding = (name, pluralName, fields) => {
  return `import { sql } from "../../config";
import sampleData from "../../data/${pluralName.toLowerCase()}.json";

export async function seed() {
    // Gunakan fitur bulk insert dari Bun SQL
    await sql\`INSERT INTO ${pluralName.toLowerCase()} \${sql(sampleData)}\`;
    console.log('\u2705 Seeding ${name} completed successfully');
}

export async function unseed() {
    await sql\`TRUNCATE TABLE ${pluralName.toLowerCase()} RESTART IDENTITY\`.simple();
    console.log('\u2705 Unseeding ${name} completed successfully');
}

// Run seeding
if (process.argv[2] === 'seed') {
    seed().catch(console.error).finally(() => process.exit());
}

if (process.argv[2] === 'unseed') {
    unseed().catch(console.error).finally(() => process.exit());
}`;
};
// src/generators/languages/typescript/templates/database/mariadb/seeding.ts
var generateMariadbSeeding = (name, pluralName, fields) => {
  return `import { db } from "../../config";
import sampleData from "../../data/${pluralName.toLowerCase()}.json";

export async function seed() {
    const values = sampleData
        .map(data => {
            const fieldValues = [
                ${fields.map((f) => `data.${f.name}`).join(`,
                `)}
            ];
            return \`    (\${fieldValues.map(v => typeof v === 'string' ? \`'\${v}'\` : v).join(', ')}, NOW(), NOW())\`;
        })
        .join(',\\n');

    await db.query(\`
        INSERT INTO ${pluralName.toLowerCase()} (
            ${fields.map((f) => f.name).join(", ")},
            createdAt,
            updatedAt
        ) VALUES
\${values}
    \`);
    
    console.log('\u2705 Seeding ${name} completed successfully');
}

export async function unseed() {
    await db.query(\`
        TRUNCATE TABLE ${pluralName.toLowerCase()}
    \`);
    
    console.log('\u2705 Unseeding ${name} completed successfully');
}

// Run seeding
if (process.argv[2] === 'seed') {
    seed()
        .catch(console.error)
        .finally(() => process.exit());
}

if (process.argv[2] === 'unseed') {
    unseed()
        .catch(console.error)
        .finally(() => process.exit());
}`;
};
// src/generators/languages/typescript/templates/database/sqlite/seeding.ts
var generateSqliteSeeding = (name, pluralName, fields) => {
  return `import { db } from "../../config";
import sampleData from "../../data/${pluralName.toLowerCase()}.json";

export async function seed() {
    const values = sampleData
        .map(data => {
            const fieldValues = [
                ${fields.map((f) => `data.${f.name}`).join(`,
                `)}
            ];
            return \`    (\${fieldValues.map(v => typeof v === 'string' ? \`'\${v}'\` : v).join(', ')}, datetime('now'), datetime('now'))\`;
        })
        .join(',\\n');

    db.query(\`
        INSERT INTO ${pluralName.toLowerCase()} (
            ${fields.map((f) => f.name).join(", ")},
            createdAt,
            updatedAt
        ) VALUES
\${values}
    \`).run();
    
    console.log('\u2705 Seeding ${name} completed successfully');
}

export async function unseed() {
    db.query(\`
        DELETE FROM ${pluralName.toLowerCase()};
        DELETE FROM sqlite_sequence WHERE name = '${pluralName.toLowerCase()}';
    \`).run();
    
    console.log('\u2705 Unseeding ${name} completed successfully');
}

// Run seeding
if (process.argv[2] === 'seed') {
    seed()
        .catch(console.error)
        .finally(() => process.exit());
}

if (process.argv[2] === 'unseed') {
    unseed()
        .catch(console.error)
        .finally(() => process.exit());
}`;
};
// src/generators/languages/typescript/templates/database/mongodb/seeding.ts
var generateMongoSeeding = (name, pluralName) => `import { db, client } from "../../config";
import { ObjectId } from "mongodb";
import sampleData from "../../data/${pluralName.toLowerCase()}.json";

const seed = async () => {
    try {
        const collection = db.collection("${pluralName.toLowerCase()}");
        
        await collection.insertMany(
            sampleData.map(data => ({
                _id: new ObjectId(),
                ...data,
                createdAt: new Date(),
                updatedAt: new Date()
            }))
        );
        
        console.log('\u2705 Seeding ${name} completed successfully');
    } catch (error) {
        console.error('\u274C Seeding failed:', error);
    } finally {
        await client.close();
    }
};

const unseed = async () => {
    try {
        await db.collection("${pluralName.toLowerCase()}").deleteMany({});
        console.log('\u2705 Unseeding ${name} completed successfully');
    } catch (error) {
        console.error('\u274C Unseeding failed:', error);
    } finally {
        await client.close();
    }
};

// Run seeding
if (process.argv[2] === 'seed') {
    seed()
        .catch(console.error)
        .finally(() => process.exit());
}

if (process.argv[2] === 'unseed') {
    unseed()
        .catch(console.error)
        .finally(() => process.exit());
}

export { seed, unseed };`;
var generateMongooseSeeding = (name, pluralName) => `import { db } from "../../config";
import { ${name} } from "./${name.toLowerCase()}.schema";
import sampleData from "../../data/${pluralName.toLowerCase()}.json";

export async function seed() {
    try {
        // Transform data dari json ke format MongoDB
        const values = sampleData.map(data => ({
            ...data,
            // Mongoose akan otomatis generate ObjectId
            createdAt: new Date(),
            updatedAt: new Date()
        }));

        // Gunakan model mongoose untuk insert data
        await ${name}.insertMany(values);
        
        console.log('\u2705 Seeding ${name} completed successfully');
    } catch (error) {
        console.error('\u274C Seeding failed:', error);
        throw error;
    }
}

export async function unseed() {
    try {
        // Gunakan model mongoose untuk delete data
        await ${name}.deleteMany({});
        
        console.log('\u2705 Unseeding ${name} completed successfully');
    } catch (error) {
        console.error('\u274C Unseeding failed:', error);
        throw error;
    }
}

// Run seeding
if (process.argv[2] === 'seed') {
    seed()
        .catch(console.error)
        .finally(() => {
            db.disconnect();
            process.exit();
        });
}

if (process.argv[2] === 'unseed') {
    unseed()
        .catch(console.error)
        .finally(() => {
            db.disconnect();
            process.exit();
        });
}`;
// src/generators/languages/typescript/templates/database/postgresql/config.ts
var generatePostgresConfig = () => `import { SQL } from 'bun';
import config from './db.json';

const env = process.env.NODE_ENV || 'development';
const dbConfig = config[env as keyof typeof config];

export const sql = new SQL({
    hostname: dbConfig.host,
    port: dbConfig.port,
    username: dbConfig.username,
    password: dbConfig.password,
    database: dbConfig.database
});

sql\`SELECT 1\`.then(() => console.log(\`\u2705 PostgreSQL connected (\${env})\`))
    .catch(e => { console.error('\u274C DB connection failed:', e); process.exit(1); });

export default sql;`;
// src/generators/languages/typescript/templates/database/mariadb/config.ts
var generateMariadbConfig = () => `import mariadb from 'mariadb';
import config from './db.json';

const env = process.env.NODE_ENV || 'development';
const dbConfig = config[env as keyof typeof config];

type SqlValue = string | number | boolean | null | Date | Buffer;

// Create connection pool
const pool = mariadb.createPool({
    host: dbConfig.host,
    port: dbConfig.port,
    user: dbConfig.username,
    password: dbConfig.password,
    database: dbConfig.database
});

// Wrapper utk query database
export const db = {
    query: async (sql: string, values?: SqlValue[]) => {
        let conn;
        try {
            conn = await pool.getConnection();
            const result = await conn.query(sql, values);
            return result;
        } catch (error) {
            console.error('Database Error:', error);
            throw error;
        } finally {
            if (conn) conn.release();
        }
    }
};

// Helper utk cek koneksi
export const testConnection = async () => {
    let conn;
    try {
        conn = await pool.getConnection();
        console.log('\u2705 MariaDB connection successful!');
        return true;
    } catch (error) {
        console.error('\u274C MariaDB connection failed:', error);
        return false;
    } finally {
        if (conn) conn.release();
    }
};

export default pool;`;
// src/generators/languages/typescript/templates/database/sqlite/config.ts
var generateSqliteConfig = () => `import { Database } from 'bun:sqlite';
import config from './db.json';

const env = process.env.NODE_ENV || 'development';
const { database } = config[env as keyof typeof config];

export const db = new Database(database);

try {
    db.query('SELECT 1').get();
    console.log(\`\u2705 SQLite connected (\${env})\`);
} catch (error) {
    console.error('\u274C SQLite connection failed:', error);
    process.exit(1);
}

export default db;`;
// src/generators/languages/typescript/templates/database/mongodb/config.ts
var generateMongoConfig = () => `import { MongoClient, Db } from 'mongodb';
import config from './db.json';

const env = process.env.NODE_ENV || 'development';
const { url, database } = config[env as keyof typeof config];

export let db: Db;
export let client: MongoClient;

try {
    client = await MongoClient.connect(url);
    db = client.db(database);
    console.log('\u2705 MongoDB connected successfully!');
} catch (error) {
    console.error('\u274C MongoDB connection failed:', error);
    process.exit(1);
}`;
var generateMongooseConfig = () => `import mongoose from 'mongoose';
import config from './db.json';

const env = process.env.NODE_ENV || 'development';
const { url, database } = config[env as keyof typeof config];

// Connect ke MongoDB dan langsung export instance mongoose
try {
    // Hapus trailing slash jika ada di akhir URL
    const cleanUrl = url.endsWith('/') ? url.slice(0, -1) : url;
    const connectionString = \`\${cleanUrl}/\${database}\`;
    mongoose.connect(connectionString);
    console.log('\u2705 MongoDB connected successfully!');
} catch (error) {
    console.error('\u274C MongoDB connection failed:', error);
    process.exit(1);
}

// Export mongoose instance untuk digunakan di seluruh aplikasi
export const db = mongoose;`;
// src/generators/languages/typescript/templates/database/postgresql/config-json.ts
var generatePostgresConfigJson = () => `{
    "development": {
        "username": "postgres",
        "password": "postgres",
        "database": "postgres-dev",
        "host": "localhost",
        "port": 5432
    },
    "test": {
        "username": "postgres",
        "password": "postgres",
        "database": "postgres-test",
        "host": "localhost",
        "port": 5432
    },
    "production": {
        "username": "postgres",
        "password": "postgres",
        "database": "postgres-prod",
        "host": "localhost",
        "port": 5432
    }
}`;
// src/generators/languages/typescript/templates/database/mariadb/config-json.ts
var generateMariadbConfigJson = () => `{
    "development": {
        "host": "localhost",
        "port": 3306,
        "username": "root",
        "password": "",
        "database": "my_database"
    },
    "test": {
        "host": "localhost",
        "port": 3306,
        "username": "root",
        "password": "",
        "database": "my_database_test"
    },
    "production": {
        "host": "localhost",
        "port": 3306,
        "username": "root",
        "password": "",
        "database": "my_database_prod"
    }
}`;
// src/generators/languages/typescript/templates/database/sqlite/config-json.ts
var generateSqliteConfigJson = () => `{
    "development": {
        "database": "./database.sqlite"
    },
    "test": {
        "database": "./database.test.sqlite"
    },
    "production": {
        "database": "./database.prod.sqlite"
    }
}`;
// src/generators/languages/typescript/templates/database/mongodb/config-json.ts
var generateMongoConfigJson = () => `{
    "development": {
        "url": "mongodb://localhost:27017",
        "database": "my_database"
    },
    "test": {
        "url": "mongodb://localhost:27017",
        "database": "my_database_test"
    },
    "production": {
        "url": "mongodb://localhost:27017",
        "database": "my_database_prod"
    }
}`;
// src/generators/languages/typescript/src/mapping.ts
var configGenerators = {
  mongodb: {
    config: (mongoDriver = "mongoose") => mongoDriver === "mongoose" ? generateMongooseConfig() : generateMongoConfig(),
    configJson: generateMongoConfigJson
  },
  postgresql: {
    config: () => generatePostgresConfig(),
    configJson: generatePostgresConfigJson
  },
  mariadb: {
    config: () => generateMariadbConfig(),
    configJson: generateMariadbConfigJson
  },
  sqlite: {
    config: () => generateSqliteConfig(),
    configJson: generateSqliteConfigJson
  }
};
var repoGenerators = {
  express: {
    mongodb: generateMongoRepository,
    postgresql: generatePostgresRepository,
    mariadb: generateMariadbRepository,
    sqlite: generateSqliteRepository
  },
  elysia: {
    mongodb: generateMongoRepository2,
    postgresql: generatePostgresRepository2,
    mariadb: generateMariadbRepository2,
    sqlite: generateSqliteRepository2
  },
  hono: {
    mongodb: generateMongoRepository3,
    postgresql: generatePostgresRepository3,
    mariadb: generateMariadbRepository3,
    sqlite: generateSqliteRepository3
  },
  next: {
    mongodb: generateMongoRepository4,
    postgresql: generatePostgresRepository4,
    mariadb: generateMariadbRepository4,
    sqlite: generateSqliteRepository4
  }
};
var dbGenerators = {
  mongodb: {
    seed: (name, pluralName, mongoDriver) => {
      if (typeof mongoDriver === "string") {
        return mongoDriver === "mongoose" ? generateMongooseSeeding(name, pluralName) : generateMongoSeeding(name, pluralName);
      }
      return generateMongoSeeding(name, pluralName);
    }
  },
  postgresql: {
    migrate: generatePostgresMigration,
    seed: generatePostgresSeeding
  },
  mariadb: {
    migrate: generateMariadbMigration,
    seed: generateMariadbSeeding
  },
  sqlite: {
    migrate: generateSqliteMigration,
    seed: generateSqliteSeeding
  }
};
var serviceGenerators = {
  express: {
    sql: generateSqlService,
    mongodb: generateMongodbService,
    mongoose: generateMongooseService
  },
  elysia: {
    sql: generateSqlService2,
    mongodb: generateMongodbService2,
    mongoose: generateMongooseService2
  },
  hono: {
    sql: generateSqlService3,
    mongodb: generateMongodbService3,
    mongoose: generateMongooseService3
  },
  next: {
    sql: generateSqlService4,
    mongodb: generateMongodbService4,
    mongoose: generateMongooseService4
  }
};
var controllerGenerators = {
  express: generateController,
  elysia: generateController2,
  hono: generateController3,
  next: generateController4
};
var serverGenerators = {
  express: generateServer,
  elysia: generateServer2,
  hono: generateServer3
};
var errorGenerators = {
  express: generateError,
  elysia: generateError2,
  hono: generateError3,
  next: generateError4
};
var getSchemaGenerator = (framework, isNoSql, mongoDriver) => {
  if (isNoSql) {
    if (framework === "express") {
      return mongoDriver === "mongoose" ? generateMongooseSchema : generateMongodbSchema;
    }
    if (framework === "hono") {
      return mongoDriver === "mongoose" ? generateMongooseSchema3 : generateMongodbSchema3;
    }
    if (framework === "elysia") {
      return mongoDriver === "mongoose" ? generateMongooseSchema2 : generateMongodbSchema2;
    }
    if (framework === "next") {
      return mongoDriver === "mongoose" ? generateMongooseSchema4 : generateMongodbSchema4;
    }
  }
  const generators = {
    express: isNoSql ? generateMongodbSchema : generateSqlSchema,
    elysia: isNoSql ? generateMongodbSchema2 : generateSqlSchema2,
    hono: isNoSql ? generateMongodbSchema3 : generateSqlSchema3,
    next: isNoSql ? generateMongodbSchema4 : generateSqlSchema4
  };
  return generators[framework];
};
var getServiceGenerator = (framework, isNoSql, mongoDriver) => {
  if (framework === "express") {
    if (isNoSql) {
      return mongoDriver === "mongoose" ? serviceGenerators.express.mongoose : serviceGenerators.express.mongodb;
    }
    return serviceGenerators.express.sql;
  }
  if (framework === "hono") {
    if (isNoSql) {
      return mongoDriver === "mongoose" ? serviceGenerators.hono.mongoose : serviceGenerators.hono.mongodb;
    }
    return serviceGenerators.hono.sql;
  }
  if (framework === "elysia") {
    if (isNoSql) {
      return mongoDriver === "mongoose" ? serviceGenerators.elysia.mongoose : serviceGenerators.elysia.mongodb;
    }
    return serviceGenerators.elysia.sql;
  }
  if (framework === "next") {
    if (isNoSql) {
      return mongoDriver === "mongoose" ? serviceGenerators.next.mongoose : serviceGenerators.next.mongodb;
    }
    return serviceGenerators.next.sql;
  }
  throw new Error(`Service generator untuk framework ${framework} tidak ditemukan`);
};

// src/generators/languages/typescript/src/index.ts
async function generateCrud(name, fields, config) {
  const { framework, database, projectDir, mongoDriver = "mongoose" } = config;
  const isNoSql = database === "mongodb";
  const cwd = process.cwd();
  console.log(source_default.blue("\uD83D\uDCE6 Detail Generate:"));
  console.log(source_default.yellow(`Framework: ${framework}`));
  console.log(source_default.yellow(`Database: ${database}`));
  if (database === "mongodb") {
    console.log(source_default.yellow(`MongoDB Driver: ${mongoDriver}`));
  }
  console.log(source_default.yellow(`Model: ${name}`));
  console.log(source_default.yellow(`Project Directory: ${projectDir || "root"}`));
  console.log(source_default.yellow("Fields:"));
  fields.forEach((field) => {
    console.log(source_default.yellow(`  - ${field.name}: ${field.type}`));
  });
  const configDir = `${cwd}/${projectDir ? projectDir + "/" : ""}config`;
  await Bun.spawn(["mkdir", "-p", configDir]).exited;
  const { config: configGenerator, configJson: configJsonGenerator } = configGenerators[database];
  if (!configGenerator || !configJsonGenerator) {
    throw new Error(`Database ${database} blm didukung`);
  }
  await Bun.write(`${configDir}/db.json`, configJsonGenerator());
  console.log(source_default.green("Created db.json"));
  await Bun.write(`${configDir}/index.ts`, configGenerator(mongoDriver));
  console.log(source_default.green("Created config/index.ts"));
  const structure = exports_constants[`${framework}Structure`];
  const modulePath = `${cwd}/${structure.getModulesPath(projectDir || "")}`;
  const moduleDir = `${modulePath}/${pluralize(name.toLowerCase())}`;
  await Bun.spawn(["mkdir", "-p", moduleDir]).exited;
  const schemaGenerator = getSchemaGenerator(framework, isNoSql, mongoDriver);
  if (!schemaGenerator) {
    throw new Error(`Framework ${framework} blm didukung`);
  }
  await Bun.write(`${moduleDir}/${name.toLowerCase()}.schema.ts`, schemaGenerator(name, fields));
  console.log(source_default.green(`Created ${name.toLowerCase()}.schema.ts`));
  const skipRepository = isNoSql && mongoDriver === "mongoose";
  if (!skipRepository) {
    const repoGenerator = repoGenerators[framework]?.[database];
    if (!repoGenerator) {
      throw new Error(`Database ${database} atau framework ${framework} blm didukung`);
    }
    await Bun.write(`${moduleDir}/${name.toLowerCase()}.repository.ts`, repoGenerator(name, pluralize(name)));
    console.log(source_default.green(`Created ${name.toLowerCase()}.repository.ts`));
  } else {
    console.log(source_default.yellow(`Skipping repository generation for mongoose (not needed)`));
  }
  const dbGenerator = dbGenerators[database];
  if (dbGenerator) {
    if (dbGenerator?.migrate) {
      await Bun.write(`${moduleDir}/${name.toLowerCase()}.migrate.ts`, dbGenerator.migrate(name, pluralize(name), fields));
      console.log(source_default.green(`Created ${name.toLowerCase()}.migrate.ts`));
    }
    if (dbGenerator?.seed) {
      if (database === "mongodb") {
        await Bun.write(`${moduleDir}/${name.toLowerCase()}.seed.ts`, dbGenerator.seed(name, pluralize(name), mongoDriver));
      } else {
        await Bun.write(`${moduleDir}/${name.toLowerCase()}.seed.ts`, dbGenerator.seed(name, pluralize(name), fields));
      }
      console.log(source_default.green(`Created ${name.toLowerCase()}.seed.ts`));
    }
  }
  const serviceGenerator = getServiceGenerator(framework, isNoSql, mongoDriver);
  if (serviceGenerator) {
    await Bun.write(`${moduleDir}/${name.toLowerCase()}.service.ts`, serviceGenerator(name, pluralize(name)));
    console.log(source_default.green(`Created ${name.toLowerCase()}.service.ts`));
  }
  const controllerGenerator = controllerGenerators[framework];
  if (controllerGenerator) {
    if (framework === "next") {
      const apiDir = `${cwd}/${projectDir ? projectDir + "/" : ""}app/api/${pluralize(name.toLowerCase())}`;
      await Bun.spawn(["mkdir", "-p", `${apiDir}/[id]`]).exited;
      const controllers = controllerGenerator(name, pluralize(name));
      await Bun.write(`${apiDir}/route.ts`, controllers.main);
      console.log(source_default.green(`Created route.ts in ${apiDir}`));
      await Bun.write(`${apiDir}/[id]/route.ts`, controllers.dynamic);
      console.log(source_default.green(`Created route.ts in ${apiDir}/[id]`));
    } else {
      await Bun.write(`${moduleDir}/index.ts`, controllerGenerator(name, pluralize(name)));
      console.log(source_default.green(`Created index.ts with controller`));
    }
  }
  try {
    await updateRouter(name, framework, projectDir);
    console.log(source_default.green(`Updated router.ts with new routes`));
  } catch (error) {
    console.error(source_default.red(`Failed to update router.ts: ${error.message}`));
  }
  const dataDir = `${cwd}/${projectDir ? projectDir + "/" : ""}data`;
  await Bun.spawn(["mkdir", "-p", dataDir]).exited;
  await Bun.write(`${dataDir}/${pluralize(name.toLowerCase())}.json`, generateJSONData(name, fields));
  console.log(source_default.green(`Created ${pluralize(name.toLowerCase())}.json with sample data`));
  const serverGenerator = serverGenerators[framework];
  const indexPath = `${cwd}/${projectDir ? projectDir + "/" : ""}index.ts`;
  if (serverGenerator) {
    try {
      await Bun.write(indexPath, serverGenerator());
      console.log(source_default.green(`Updated index.ts with ${framework} server setup`));
    } catch (error) {
      console.error(source_default.red(`Failed to update index.ts: ${error.message}`));
    }
  }
  const errorGenerator = errorGenerators[framework];
  if (errorGenerator) {
    try {
      await Bun.write(`${cwd}/${projectDir ? projectDir + "/" : ""}error.ts`, errorGenerator());
      console.log(source_default.green(`Created error.ts with error handler`));
    } catch (error) {
      console.error(source_default.red(`Failed to create error.ts: ${error.message}`));
    }
  }
  console.log(source_default.green(`
\u2728 Files generated successfully!`));
}

// src/generators/utils/package.ts
import { readFile, writeFile as writeFile6 } from "fs/promises";
import { join as join7 } from "path";
async function updatePackageJson() {
  try {
    const packagePath = join7(process.cwd(), "package.json");
    const content = await readFile(packagePath, "utf-8");
    const pkg = JSON.parse(content);
    pkg.scripts = {
      ...pkg.scripts,
      dev: "henotic dev",
      start: "henotic start",
      build: "henotic build"
    };
    pkg.main = "dist/index.js";
    await writeFile6(packagePath, JSON.stringify(pkg, null, 2));
    console.log(source_default.green("\u2728 Package.json berhasil diupdate!"));
  } catch (error) {
    throw new Error("Gagal update package.json: " + error.message);
  }
}

// src/generators/languages/typescript/index.ts
async function generateCommand(name, fields) {
  try {
    console.log(source_default.cyan(`
\uD83D\uDE80 Memulai generate CRUD...
`));
    const config = await readConfig();
    const parsedFields = parseFields(fields);
    await generateCrud(name, parsedFields, config);
    await updatePackageJson();
    console.log(source_default.green(`
\u2728 Generate CRUD berhasil!
`));
  } catch (error) {
    const errMsg = error instanceof Error ? source_default.red(error.message) : "Unknown error occurred";
    console.error(source_default.red(`
\u274C Aduh error nih: ${errMsg}
`));
    process.exit(1);
  }
}

// src/generators/languages/go/src/index.ts
import path4 from "path";

// src/generators/languages/go/src/seed.ts
import { access } from "fs/promises";
async function fileExists(path4) {
  try {
    await access(path4);
    return true;
  } catch {
    return false;
  }
}
async function updateSeedMain(name, projectDir = "", isFirstGenerate = false) {
  try {
    if (isFirstGenerate) {
      return;
    }
    const cwd = process.cwd();
    const pluralName = pluralize(name);
    const seedMainPath = `${cwd}/${projectDir ? projectDir + "/" : ""}cmd/seed/main.go`;
    if (!await fileExists(seedMainPath)) {
      console.log(source_default.yellow("\u26A0\uFE0F File seed/main.go tidak ditemukan, skip update..."));
      return;
    }
    let content = await Bun.file(seedMainPath).text();
    if (content.includes(`seed.${pluralName}`)) {
      return;
    }
    const importSection = content.match(/import \(([\s\S]*?)\)/)?.[0] || "";
    const newImport = `${name.toLowerCase()}Entity "project-name/internal/module/${name.toLowerCase()}/entity"`;
    if (!importSection.includes(newImport)) {
      content = content.replace(/import \(([\s\S]*?)\)/, `import (
	${newImport}$1)`);
    }
    const migrationsSection = content.match(/migrations := \[\]interface{}{([\s\S]*?)}/)?.[0] || "";
    const newMigration = `&${name.toLowerCase()}Entity.${name}{}`;
    if (!migrationsSection.includes(newMigration)) {
      content = content.replace(/migrations := \[\]interface{}{([\s\S]*?)}/, `migrations := []interface{}{
		${newMigration},$1}`);
    }
    const seedsSection = content.match(/seeds := \[\]struct {([\s\S]*?)}{([\s\S]*?)}/)?.[0] || "";
    const newSeed = `{"${name.toLowerCase()}", seed.${pluralName}}`;
    if (!seedsSection.includes(newSeed)) {
      content = content.replace(/seeds := \[\]struct {([\s\S]*?)}{([\s\S]*?)}/, `seeds := []struct {$1}{
		${newSeed},$2}`);
    }
    await Bun.write(seedMainPath, content);
    console.log(source_default.green(`\u2705 Updated seed/main.go dengan seed untuk ${name}`));
  } catch (error) {
    console.error(source_default.red(`\u274C Error updating seed/main.go: ${error.message}`));
  }
}

// src/generators/languages/go/src/main.ts
import { readdir, access as access2 } from "fs/promises";
import { join as join8 } from "path";
async function fileExists2(path4) {
  try {
    await access2(path4);
    return true;
  } catch {
    return false;
  }
}
async function updateMainGo(name, projectDir = "", isFirstGenerate = false) {
  try {
    if (isFirstGenerate) {
      return;
    }
    const cwd = process.cwd();
    const lowerName = name.toLowerCase();
    const mainPath = `${cwd}/${projectDir ? projectDir + "/" : ""}cmd/main/main.go`;
    if (!await fileExists2(mainPath)) {
      console.log(source_default.yellow("\u26A0\uFE0F File main.go tidak ditemukan, skip update..."));
      return;
    }
    let content = await Bun.file(mainPath).text();
    const importRegex = new RegExp(`"project-name/internal/module/${lowerName}"`, "g");
    if (importRegex.test(content)) {
      return;
    }
    const importSection = content.match(/import \(\n([\s\S]*?)\)/)?.[0] || "";
    if (!importSection) {
      console.log(source_default.yellow("\u26A0\uFE0F Format main.go tidak sesuai, skip update import..."));
      return;
    }
    const newImportSection = importSection.replace(/import \(\n([\s\S]*?)\)/, `import (
$1	"project-name/internal/module/${lowerName}"
)`);
    content = content.replace(importSection, newImportSection);
    const initRegex = new RegExp(`${lowerName}\\.Initialize\\(db, api\\)`, "g");
    if (initRegex.test(content)) {
      return;
    }
    const lastInitIndex = content.lastIndexOf(".Initialize(db, api)");
    if (lastInitIndex === -1) {
      console.log(source_default.yellow("\u26A0\uFE0F Format main.go tidak sesuai, skip update inisialisasi..."));
      return;
    }
    const lastInitLine = content.substring(0, lastInitIndex).split(`
`).pop() + ".Initialize(db, api)";
    content = content.replace(lastInitLine, `${lastInitLine}
	${lowerName}.Initialize(db, api)`);
    await Bun.write(mainPath, content);
    console.log(source_default.green(`\u2705 Updated main.go dengan modul ${name}`));
  } catch (error) {
    console.error(source_default.red(`\u274C Error updating main.go: ${error.message}`));
  }
}
async function getExistingModules(projectDir = "") {
  try {
    const cwd = process.cwd();
    const modulesPath = join8(cwd, projectDir, "internal/module");
    if (!await fileExists2(modulesPath)) {
      return [];
    }
    const modules = await readdir(modulesPath);
    return modules.map((module) => {
      const pascalCase = module.charAt(0).toUpperCase() + module.slice(1);
      return {
        name: pascalCase,
        lowerName: module
      };
    });
  } catch (error) {
    console.error(source_default.red(`\u274C Error getting existing modules: ${error}`));
    return [];
  }
}

// src/generators/languages/go/templates/database/mariadb/config.ts
var generateGoMariadbConfig = () => `package config

import (
    "log"
    "os"

    "github.com/joho/godotenv"
)

type Config struct {
    DBHost         string
    DBPort         string
    DBUser         string
    DBPassword     string
    DBName         string
    ServerPort     string
    Environment    string
    TrustedProxies string
}

func LoadConfig() *Config {
    err := godotenv.Load()
    if err != nil {
        log.Println("Warning: .env file not found, using default values")
    }

    return &Config{
        DBHost:         getEnv("DB_HOST", "localhost"),
        DBPort:         getEnv("DB_PORT", "3306"),
        DBUser:         getEnv("DB_USER", "root"),
        DBPassword:     getEnv("DB_PASSWORD", "password"),
        DBName:         getEnv("DB_NAME", "mariadb"),
        ServerPort:     getEnv("SERVER_PORT", "8080"),
        Environment:    getEnv("APP_ENV", "development"),
        TrustedProxies: getEnv("TRUSTED_PROXIES", "127.0.0.1"),
    }
}

func getEnv(key, fallback string) string {
    if value, exists := os.LookupEnv(key); exists {
        return value
    }
    return fallback
}
`;

// src/generators/languages/go/templates/database/mariadb/database.ts
var generateGoMariadbDatabase = () => `package database

import (
    "fmt"
    "log"
    "project-name/pkg/config"

    "gorm.io/driver/mysql"
    "gorm.io/gorm"
)

func Connect() *gorm.DB {
    // Load config
    cfg := config.LoadConfig()

    // Connect to MariaDB
    dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local",
        cfg.DBUser,
        cfg.DBPassword,
        cfg.DBHost,
        cfg.DBPort,
        cfg.DBName,
    )

    db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
    if err != nil {
        log.Fatal("Failed to connect to database:", err)
    }

    return db
}
`;

// src/generators/languages/go/templates/database/mariadb/env.ts
var generateGoMariadbEnv = () => `DB_HOST=localhost
DB_PORT=3306
DB_USER=root
DB_PASSWORD=password
DB_NAME=mariadb
SERVER_PORT=8080
APP_ENV=development
TRUSTED_PROXIES=127.0.0.1
`;

// src/generators/languages/go/templates/database/postgresql/config.ts
var generateGoPostgresqlConfig = () => `package config

import (
    "log"
    "os"

    "github.com/joho/godotenv"
)

type Config struct {
    DBHost      string
    DBPort      string
    DBUser      string
    DBPassword  string
    DBName      string
    ServerPort  string
    Environment string
    TrustedProxies string
}

func LoadConfig() *Config {
    err := godotenv.Load()
    if err != nil {
        log.Println("Warning: .env file not found, using default values")
    }

    return &Config{
        DBHost:      getEnv("DB_HOST", "localhost"),
        DBPort:      getEnv("DB_PORT", "5432"),
        DBUser:      getEnv("DB_USER", "postgres"),
        DBPassword:  getEnv("DB_PASSWORD", "postgres"),
        DBName:      getEnv("DB_NAME", "postgres"),
        ServerPort:  getEnv("SERVER_PORT", "8080"),
        Environment: getEnv("APP_ENV", "development"),
        TrustedProxies: getEnv("TRUSTED_PROXIES", "127.0.0.1"),
    }
}

func getEnv(key, fallback string) string {
    if value, exists := os.LookupEnv(key); exists {
        return value
    }
    return fallback
}
`;

// src/generators/languages/go/templates/database/postgresql/database.ts
var generateGoPostgresqlDatabase = () => `package database

import (
    "fmt"
    "log"
    "project-name/pkg/config"

    "gorm.io/driver/postgres"
    "gorm.io/gorm"
)

func Connect() *gorm.DB {
    // Load config
    cfg := config.LoadConfig()

    // Connect to PostgreSQL
    dsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%s sslmode=disable",
        cfg.DBHost, cfg.DBUser, cfg.DBPassword, cfg.DBName, cfg.DBPort)

    db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
    if err != nil {
        log.Fatal("Failed to connect to database:", err)
    }

    return db
}
`;

// src/generators/languages/go/templates/database/postgresql/env.ts
var generateGoPostgresqlEnv = () => `DB_HOST=localhost
DB_PORT=5432
DB_USER=postgres
DB_PASSWORD=postgres
DB_NAME=postgres
SERVER_PORT=8080
APP_ENV=development
TRUSTED_PROXIES=127.0.0.1
`;

// src/generators/languages/go/templates/database/sqlite/config.ts
var generateGoSqliteConfig = () => `package config

import (
    "log"
    "os"

    "github.com/joho/godotenv"
)

type Config struct {
    DBPath         string // Path file SQLite
    ServerPort     string
    Environment    string
    TrustedProxies string
}

func LoadConfig() *Config {
    err := godotenv.Load()
    if err != nil {
        log.Println("Warning: .env file not found, using default values")
    }

    return &Config{
        DBPath:         getEnv("DB_PATH", "database.db"),
        ServerPort:     getEnv("SERVER_PORT", "8080"),
        Environment:    getEnv("APP_ENV", "development"),
        TrustedProxies: getEnv("TRUSTED_PROXIES", "127.0.0.1"),
    }
}

func getEnv(key, fallback string) string {
    if value, exists := os.LookupEnv(key); exists {
        return value
    }
    return fallback
}
`;

// src/generators/languages/go/templates/database/sqlite/database.ts
var generateGoSqliteDatabase = () => `package database

import (
    "log"
    "project-name/pkg/config"

    "gorm.io/driver/sqlite"
    "gorm.io/gorm"
)

func Connect() *gorm.DB {
    // Load config
    cfg := config.LoadConfig()

    // Connect to SQLite
    db, err := gorm.Open(sqlite.Open(cfg.DBPath), &gorm.Config{})
    if err != nil {
        log.Fatal("Failed to connect to database:", err)
    }

    return db
}
`;

// src/generators/languages/go/templates/database/sqlite/env.ts
var generateGoSqliteEnv = () => `DB_PATH=database.db
SERVER_PORT=8080
APP_ENV=development
TRUSTED_PROXIES=127.0.0.1
`;

// src/generators/languages/go/templates/gorm/sql/entity.ts
var generateGoGormEntity = (name, fields) => {
  const typeMapping = {
    string: "string",
    number: "float64",
    boolean: "bool",
    date: "time.Time",
    text: "string",
    json: "json.RawMessage",
    enum: "string"
  };
  const fieldDefinitions = fields.map((field) => {
    const goType = typeMapping[field.type] || "string";
    const fieldName = field.name.charAt(0).toUpperCase() + field.name.slice(1);
    let binding = "";
    if (field.type === "string" || field.type === "text") {
      binding = ' binding:"max=255"';
    } else if (field.type === "number") {
      binding = ' binding:"numeric"';
    }
    return `    ${fieldName}        ${goType}    \`json:"${field.name}"${binding}\``;
  }).join(`
`);
  return `package entity

import (
    "time"
    ${fields.some((f) => f.type === "json") ? `
    "encoding/json"` : ""}
    "github.com/go-playground/validator/v10"
)

type ${name} struct {
    ID          uint      \`json:"id" gorm:"primaryKey"\`
${fieldDefinitions}
    CreatedAt   time.Time \`json:"created_at"\`
    UpdatedAt   time.Time \`json:"updated_at"\`
}

func (p *${name}) Validate() error {
    validate := validator.New()
    return validate.Struct(p)
}
`;
};

// src/generators/languages/go/templates/gorm/sql/service.ts
var generateGoGormService = (name, pluralName) => `package service

import (
    "project-name/internal/module/${name.toLowerCase()}/entity"

    "gorm.io/gorm"
)

type ${name}Service struct {
    db *gorm.DB
}

func New${name}Service(db *gorm.DB) *${name}Service {
    return &${name}Service{db}
}

func (s *${name}Service) Create(${name.toLowerCase()} *entity.${name}) error {
    if err := ${name.toLowerCase()}.Validate(); err != nil {
        return err
    }
    return s.db.Create(${name.toLowerCase()}).Error
}

func (s *${name}Service) GetByID(id uint) (*entity.${name}, error) {
    var ${name.toLowerCase()} entity.${name}
    err := s.db.First(&${name.toLowerCase()}, id).Error
    return &${name.toLowerCase()}, err
}

func (s *${name}Service) GetAll() ([]entity.${name}, error) {
    var ${pluralName.toLowerCase()} []entity.${name}
    err := s.db.Find(&${pluralName.toLowerCase()}).Error
    return ${pluralName.toLowerCase()}, err
}

func (s *${name}Service) Update(${name.toLowerCase()} *entity.${name}) error {
    if err := ${name.toLowerCase()}.Validate(); err != nil {
        return err
    }

    // Cek apakah ${name.toLowerCase()} ada
    var existing${name} entity.${name}
    if err := s.db.First(&existing${name}, ${name.toLowerCase()}.ID).Error; err != nil {
        return err
    }

    return s.db.Save(${name.toLowerCase()}).Error
}

func (s *${name}Service) Delete(id uint) error {
    return s.db.Delete(&entity.${name}{}, id).Error
}
`;

// src/generators/languages/go/templates/gorm/sql/handler.ts
var generateGoGormHandler = (name, pluralName) => `package handler

import (
    "net/http"
    "project-name/internal/module/${name.toLowerCase()}/entity"
    "project-name/internal/module/${name.toLowerCase()}/service"
    "project-name/pkg/utils"
    "strconv"

    "github.com/gin-gonic/gin"
)

type ${name}Handler struct {
    service *service.${name}Service
}

func New${name}Handler(service *service.${name}Service) *${name}Handler {
    return &${name}Handler{service}
}

func (h *${name}Handler) Create(c *gin.Context) {
    var ${name.toLowerCase()} entity.${name}
    if err := c.ShouldBindJSON(&${name.toLowerCase()}); err != nil {
        c.JSON(http.StatusBadRequest, utils.ErrorResponse(err.Error()))
        return
    }

    if err := h.service.Create(&${name.toLowerCase()}); err != nil {
        c.JSON(http.StatusInternalServerError, utils.ErrorResponse(err.Error()))
        return
    }

    c.JSON(http.StatusCreated, utils.SuccessResponse(${name.toLowerCase()}))
}

func (h *${name}Handler) GetByID(c *gin.Context) {
    id, err := strconv.ParseUint(c.Param("id"), 10, 32)
    if err != nil {
        c.JSON(http.StatusBadRequest, utils.ErrorResponse("Invalid ID"))
        return
    }

    ${name.toLowerCase()}, err := h.service.GetByID(uint(id))
    if err != nil {
        c.JSON(http.StatusNotFound, utils.ErrorResponse("${name} not found"))
        return
    }

    c.JSON(http.StatusOK, utils.SuccessResponse(${name.toLowerCase()}))
}

func (h *${name}Handler) GetAll(c *gin.Context) {
    ${pluralName.toLowerCase()}, err := h.service.GetAll()
    if err != nil {
        c.JSON(http.StatusInternalServerError, utils.ErrorResponse(err.Error()))
        return
    }

    c.JSON(http.StatusOK, utils.SuccessResponse(${pluralName.toLowerCase()}))
}

func (h *${name}Handler) Update(c *gin.Context) {
    id, err := strconv.ParseUint(c.Param("id"), 10, 32)
    if err != nil {
        c.JSON(http.StatusBadRequest, utils.ErrorResponse("Invalid ID"))
        return
    }

    var ${name.toLowerCase()} entity.${name}
    if err := c.ShouldBindJSON(&${name.toLowerCase()}); err != nil {
        c.JSON(http.StatusBadRequest, utils.ErrorResponse(err.Error()))
        return
    }

    // Set ID dari parameter URL
    ${name.toLowerCase()}.ID = uint(id)

    if err := h.service.Update(&${name.toLowerCase()}); err != nil {
        c.JSON(http.StatusInternalServerError, utils.ErrorResponse(err.Error()))
        return
    }

    c.JSON(http.StatusOK, utils.SuccessResponse(${name.toLowerCase()}))
}

func (h *${name}Handler) Delete(c *gin.Context) {
    id, err := strconv.ParseUint(c.Param("id"), 10, 32)
    if err != nil {
        c.JSON(http.StatusBadRequest, utils.ErrorResponse("Invalid ID"))
        return
    }

    if err := h.service.Delete(uint(id)); err != nil {
        c.JSON(http.StatusInternalServerError, utils.ErrorResponse(err.Error()))
        return
    }

    c.JSON(http.StatusOK, utils.SuccessResponse("${name} deleted successfully"))
}
`;

// src/generators/languages/go/templates/gorm/sql/route.ts
var generateGoGormRoute = (name, pluralName) => `package handler

import (
    "github.com/gin-gonic/gin"
)

func RegisterRoutes(router *gin.RouterGroup, handler *${name}Handler) {
    ${pluralName.toLowerCase()} := router.Group("/${pluralName.toLowerCase()}")
    {
        ${pluralName.toLowerCase()}.POST("", handler.Create)
        ${pluralName.toLowerCase()}.GET("/:id", handler.GetByID)
        ${pluralName.toLowerCase()}.GET("", handler.GetAll)
        ${pluralName.toLowerCase()}.PUT("/:id", handler.Update)
        ${pluralName.toLowerCase()}.DELETE("/:id", handler.Delete)
    }
}
`;

// src/generators/languages/go/templates/gorm/sql/main.ts
var generateGoGormMain = (name, existingModules = []) => {
  const allModules = [...existingModules, { name, lowerName: name.toLowerCase() }];
  const imports = allModules.map((module) => `	"project-name/internal/module/${module.lowerName}"`).join(`
`);
  const initializations = allModules.map((module) => `	${module.lowerName}.Initialize(db, api)`).join(`
`);
  return `package main

import (
	"log"
	"strings"
${imports}
	"project-name/pkg/config"
	"project-name/pkg/database"
	"project-name/pkg/middleware"

	"github.com/gin-gonic/gin"
)

func main() {
	// Load config
	cfg := config.LoadConfig()

	// Set mode berdasarkan environment
	if cfg.Environment == "production" {
		gin.SetMode(gin.ReleaseMode)
	}

	// Connect to database
	db := database.Connect()

	// Setup router
	r := gin.Default()

	// Set trusted proxies dari environment atau gunakan default
	trustedProxies := strings.Split(cfg.TrustedProxies, ",")
	r.SetTrustedProxies(trustedProxies)

	r.Use(middleware.CORS())

	// API routes
	api := r.Group("/api")

	// Initialize modules
${initializations}

	// Start server
	log.Printf("\uD83D\uDE80 Server running on port %s", cfg.ServerPort)
	r.Run(":" + cfg.ServerPort)
}
`;
};

// src/generators/languages/go/templates/gorm/sql/middleware.ts
var generateGoGormMiddleware = () => `package middleware

import (
    "github.com/gin-gonic/gin"
)

func Logger() gin.HandlerFunc {
    return gin.Logger()
}

func CORS() gin.HandlerFunc {
    return func(c *gin.Context) {
        c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
        c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
        c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")

        if c.Request.Method == "OPTIONS" {
            c.AbortWithStatus(204)
            return
        }

        c.Next()
    }
}
`;

// src/generators/languages/go/templates/gorm/sql/response.ts
var generateGoGormResponse = () => `package utils

type Response struct {
    Success bool        \`json:"success"\`
    Data    interface{} \`json:"data,omitempty"\`
    Error   string      \`json:"error,omitempty"\`
}

func SuccessResponse(data interface{}) Response {
    return Response{
        Success: true,
        Data:    data,
    }
}

func ErrorResponse(err string) Response {
    return Response{
        Success: false,
        Error:   err,
    }
}
`;

// src/generators/utils/singular.ts
function singularize(word) {
  const irregulars = {
    Categories: "Category",
    Properties: "Property",
    Cities: "City",
    Stories: "Story",
    Babies: "Baby",
    People: "Person",
    Men: "Man",
    Women: "Woman",
    Children: "Child",
    Teeth: "Tooth",
    Feet: "Foot",
    Mice: "Mouse",
    Beliefs: "Belief"
  };
  if (irregulars[word.toLowerCase()]) {
    return irregulars[word.toLowerCase()];
  }
  if (word.match(/ies$/)) {
    return word.replace(/ies$/, "y");
  }
  if (word.match(/es$/)) {
    return word.replace(/es$/, "");
  }
  if (word.match(/s$/)) {
    return word.replace(/s$/, "");
  }
  return word;
}

// src/generators/languages/go/templates/gorm/sql/seedMain.ts
var generateGoGormSeedMain = (_name, pluralName, existingModules = []) => {
  const allModules = [...existingModules, pluralName];
  const entityImports = allModules.map((module) => `	${module.toLowerCase()}Entity "project-name/internal/module/${singularize(module).toLowerCase()}/entity"`).join(`
`);
  return `package main

import (
	"fmt"
	"log"
${entityImports}
	"project-name/internal/seed"
	"project-name/pkg/database"
	
	"gorm.io/gorm"
)

// SeedFunction adalah tipe untuk fungsi seeding
type SeedFunction func(*gorm.DB) error

// runMigrations menjalankan migrasi sesuai urutan
func runMigrations(db *gorm.DB) error {
	fmt.Println("\uD83D\uDE80 Running migrations in order...")

	migrations := []interface{}{
		${allModules.map((module) => `&${module.toLowerCase()}Entity.${module.slice(0, -1)}{}`).join(`,
		`)},
		// Tambahkan entity lain
	}

	for _, model := range migrations {
		if err := db.AutoMigrate(model); err != nil {
			return fmt.Errorf("error migrating %T: %w", model, err)
		}
		fmt.Printf("\uD83D\uDCDD Migrated %T successfully\\n", model)
	}

	return nil
}

// runSeeds menjalankan seeding sesuai urutan
func runSeeds(db *gorm.DB) error {
	fmt.Println("\uD83C\uDF31 Running seeds in order...")

	seeds := []struct {
		name string
		fn   SeedFunction
	}{
		${allModules.map((module) => `{"${module.toLowerCase()}", seed.${module}}`).join(`,
		`)},
		// Tambahkan fungsi seed lainnya
	}

	for _, seed := range seeds {
		fmt.Printf("\uD83C\uDF31 Seeding %s...", seed.name)
		if err := seed.fn(db); err != nil {
			return fmt.Errorf("error seeding %s: %w", seed.name, err)
		}
		fmt.Printf("\u2705 Seeded %s successfully\\n", seed.name)
	}

	return nil
}

func main() {
	db := database.Connect()

	if err := runMigrations(db); err != nil {
		log.Fatalf("Error running migrations: %v", err)
	}

	if err := runSeeds(db); err != nil {
		log.Fatalf("Error running seeds: %v", err)
	}

	log.Println("\u2705 All data migrated and seeded successfully")
}
`;
};

// src/generators/languages/go/templates/gorm/sql/seed.ts
var generateGoGormSeed = (name, pluralName) => `package seed

import (
    "encoding/json"
    "fmt"
    ${name.toLowerCase()}Entity "project-name/internal/module/${name.toLowerCase()}/entity"
    "os"

    "gorm.io/gorm"
)

// ${pluralName} - fungsi untuk seed data ${name.toLowerCase()}
func ${pluralName}(db *gorm.DB) error {
    // Read JSON file
    data, err := os.ReadFile("data/${pluralName.toLowerCase()}.json")
    if err != nil {
        return fmt.Errorf("error reading ${pluralName.toLowerCase()}.json: %w", err)
    }

    // Parse JSON data
    var ${pluralName.toLowerCase()} []${name.toLowerCase()}Entity.${name}
    err = json.Unmarshal(data, &${pluralName.toLowerCase()})
    if err != nil {
        return fmt.Errorf("error parsing ${pluralName.toLowerCase()}.json: %w", err)
    }

    // Seed data
    for _, ${name.toLowerCase()} := range ${pluralName.toLowerCase()} {
        if err := db.Create(&${name.toLowerCase()}).Error; err != nil {
            return fmt.Errorf("error seeding ${name.toLowerCase()}: %w", err)
        }
    }

    fmt.Println("\uD83C\uDF31 ${name} data seeded successfully!")
    return nil
}
`;

// src/generators/languages/go/templates/gorm/sql/bootstrap.ts
var generateGoGormBootstrap = (name) => `package ${name.toLowerCase()}

import (
	"project-name/internal/module/${name.toLowerCase()}/handler"
	"project-name/internal/module/${name.toLowerCase()}/service"

	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
)

// Initialize - Fungsi untuk menginisialisasi modul ${name.toLowerCase()}
func Initialize(db *gorm.DB, router *gin.RouterGroup) {
	// Initialize service
	${name.toLowerCase()}Service := service.New${name}Service(db)

	// Initialize handler
	${name.toLowerCase()}Handler := handler.New${name}Handler(${name.toLowerCase()}Service)

	// Register routes
	handler.RegisterRoutes(router, ${name.toLowerCase()}Handler)
}
`;

// src/generators/languages/go/src/mapping.ts
var configGenerators2 = {
  postgresql: {
    config: generateGoPostgresqlConfig,
    database: generateGoPostgresqlDatabase,
    env: generateGoPostgresqlEnv
  },
  mariadb: {
    config: generateGoMariadbConfig,
    database: generateGoMariadbDatabase,
    env: generateGoMariadbEnv
  },
  sqlite: {
    config: generateGoSqliteConfig,
    database: generateGoSqliteDatabase,
    env: generateGoSqliteEnv
  }
};
var entityGenerator = generateGoGormEntity;
var serviceGenerator = generateGoGormService;
var handlerGenerator = generateGoGormHandler;
var routeGenerator = generateGoGormRoute;
var mainGenerator = generateGoGormMain;
var middlewareGenerator = generateGoGormMiddleware;
var responseGenerator = generateGoGormResponse;
var seedGenerators = {
  main: generateGoGormSeedMain,
  seed: generateGoGormSeed
};
var bootstrapGenerator = generateGoGormBootstrap;

// src/generators/languages/go/src/index.ts
async function generateGoCrud(name, fields, config) {
  const { database, projectDir } = config;
  const cwd = process.cwd();
  const pluralName = pluralize(name);
  let moduleName = "";
  try {
    const goModContent = await Bun.file(`${cwd}/go.mod`).text();
    const moduleMatch = goModContent.match(/module\s+(.+)/);
    if (moduleMatch && moduleMatch[1]) {
      moduleName = moduleMatch[1].trim();
    } else {
      moduleName = path4.basename(cwd);
    }
  } catch (error) {
    moduleName = path4.basename(cwd);
  }
  console.log(source_default.blue("\uD83D\uDCE6 Detail Generate:"));
  console.log(source_default.yellow(`Database: ${database}`));
  console.log(source_default.yellow(`Model: ${name}`));
  console.log(source_default.yellow(`Project Directory: ${projectDir || "root"}`));
  console.log(source_default.yellow(`Module Name: ${moduleName}`));
  console.log(source_default.yellow("Fields:"));
  fields.forEach((field) => {
    console.log(source_default.yellow(`  - ${field.name}: ${field.type}`));
  });
  const existingModules = await getExistingModules(projectDir);
  const isFirstGenerate = existingModules.length === 0;
  const pkgDir = `${cwd}/${projectDir ? projectDir + "/" : ""}pkg`;
  const configDir = `${pkgDir}/config`;
  const databaseDir = `${pkgDir}/database`;
  const utilsDir = `${pkgDir}/utils`;
  await Bun.spawn(["mkdir", "-p", configDir]).exited;
  await Bun.spawn(["mkdir", "-p", databaseDir]).exited;
  await Bun.spawn(["mkdir", "-p", utilsDir]).exited;
  const dbConfig = configGenerators2[database];
  if (!dbConfig) {
    throw new Error(`Database ${database} belum didukung \uD83D\uDE22`);
  }
  await Bun.write(`${configDir}/config.go`, dbConfig.config().replace(/project-name/g, moduleName));
  console.log(source_default.green("\u2705 Created config.go"));
  await Bun.write(`${databaseDir}/database.go`, dbConfig.database().replace(/project-name/g, moduleName));
  console.log(source_default.green("\u2705 Created database.go"));
  if (dbConfig.env) {
    await Bun.write(`${cwd}/${projectDir ? projectDir + "/" : ""}.env`, dbConfig.env());
    console.log(source_default.green("\u2705 Created .env file"));
  }
  const internalDir = `${cwd}/${projectDir ? projectDir + "/" : ""}internal`;
  const moduleDir = `${internalDir}/module/${name.toLowerCase()}`;
  const entityDir = `${moduleDir}/entity`;
  const handlerDir = `${moduleDir}/handler`;
  const serviceDir = `${moduleDir}/service`;
  await Bun.spawn(["mkdir", "-p", entityDir]).exited;
  await Bun.spawn(["mkdir", "-p", handlerDir]).exited;
  await Bun.spawn(["mkdir", "-p", serviceDir]).exited;
  await Bun.write(`${entityDir}/${name.toLowerCase()}.go`, entityGenerator(name, fields).replace(/project-name/g, moduleName));
  console.log(source_default.green(`\u2705 Created ${name.toLowerCase()}.go entity`));
  await Bun.write(`${moduleDir}/bootstrap.go`, bootstrapGenerator(name).replace(/project-name/g, moduleName));
  console.log(source_default.green(`\u2705 Created bootstrap.go`));
  await Bun.write(`${serviceDir}/service.go`, serviceGenerator(name, pluralName).replace(/project-name/g, moduleName));
  console.log(source_default.green(`\u2705 Created service.go`));
  await Bun.write(`${handlerDir}/handler.go`, handlerGenerator(name, pluralName).replace(/project-name/g, moduleName));
  console.log(source_default.green(`\u2705 Created handler.go`));
  await Bun.write(`${handlerDir}/route.go`, routeGenerator(name, pluralName).replace(/project-name/g, moduleName));
  console.log(source_default.green(`\u2705 Created route.go`));
  await Bun.write(`${pkgDir}/middleware/middleware.go`, middlewareGenerator());
  console.log(source_default.green(`\u2705 Created middleware.go`));
  await Bun.write(`${utilsDir}/response.go`, responseGenerator());
  console.log(source_default.green(`\u2705 Created response.go`));
  const cmdDir = `${cwd}/${projectDir ? projectDir + "/" : ""}cmd`;
  await Bun.spawn(["mkdir", "-p", `${cmdDir}/main`]).exited;
  await Bun.write(`${cmdDir}/main/main.go`, mainGenerator(name, existingModules).replace(/project-name/g, moduleName));
  console.log(source_default.green(`\u2705 Created main.go`));
  const seedDir = `${cwd}/${projectDir ? projectDir + "/" : ""}cmd/seed`;
  await Bun.spawn(["mkdir", "-p", seedDir]).exited;
  if (isFirstGenerate) {
    await Bun.write(`${seedDir}/main.go`, seedGenerators.main(name, pluralName).replace(/project-name/g, moduleName));
  } else {
    const existingModuleNames = existingModules.map((m) => pluralize(m.name));
    await Bun.write(`${seedDir}/main.go`, seedGenerators.main(name, pluralName, existingModuleNames).replace(/project-name/g, moduleName));
  }
  console.log(source_default.green(`\u2705 Created seed main.go`));
  await Bun.spawn(["mkdir", "-p", `${internalDir}/seed`]).exited;
  await Bun.write(`${internalDir}/seed/${name.toLowerCase()}.go`, seedGenerators.seed(name, pluralName).replace(/project-name/g, moduleName));
  console.log(source_default.green(`\u2705 Created seed ${name.toLowerCase()}.go`));
  const dataDir = `${cwd}/${projectDir ? projectDir + "/" : ""}data`;
  await Bun.spawn(["mkdir", "-p", dataDir]).exited;
  await Bun.write(`${dataDir}/${pluralName.toLowerCase()}.json`, generateJSONData(name, fields));
  console.log(source_default.green(`\u2705 Created ${pluralName.toLowerCase()}.json with sample data`));
  await updateMainGo(name, projectDir, isFirstGenerate);
  await updateSeedMain(name, projectDir, isFirstGenerate);
  console.log(source_default.green(`
\u2728 Files generated successfully!`));
}

// src/generators/languages/go/index.ts
async function generateCommand2(name, fields) {
  try {
    console.log(source_default.cyan(`
\uD83D\uDE80 Memulai generate CRUD untuk Go...
`));
    const config = await readConfig();
    const parsedFields = parseFields(fields);
    await generateGoCrud(name, parsedFields, config);
    console.log(source_default.green(`
\u2728 Generate CRUD Go berhasil!
`));
  } catch (error) {
    const errMsg = error instanceof Error ? source_default.red(error.message) : "Unknown error occurred";
    console.error(source_default.red(`
\u274C Aduh error nih: ${errMsg}
`));
    process.exit(1);
  }
}

// src/index.ts
var promptsConfig5 = {
  onCancel: () => {
    console.log(source_default.yellow(`
\uD83D\uDED1 Operasi dibatalkan oleh pengguna`));
    process.exit(0);
  }
};
var packageJson;
var version = process.env.HENOTIC_VERSION;
if (version) {
  packageJson = {
    name: "henotic-cli",
    version,
    author: "Hens MSN <hendymms@engineer.com>",
    description: "Henotic CLI is the ultimate multi-language backend generator"
  };
} else {
  try {
    packageJson = JSON.parse(await Bun.file(`${import.meta.dir}/../package.json`).text());
  } catch (error) {
    console.error(source_default.yellow("\u26A0\uFE0F Tidak dapat membaca versi, menggunakan versi default"));
    packageJson = {
      name: "henotic-cli",
      version: "unknown",
      author: "Hens MSN <hendymms@engineer.com>",
      description: "Henotic CLI is the ultimate multi-language backend generator"
    };
  }
}
function showHelp() {
  console.log(source_default.bold(`
\uD83E\uDD9C Henotic CLI - The Ultimate Backend Generator
`));
  console.log(`
${source_default.bold("Usage:")}
    ${source_default.cyan("henotic new <project-name>")}   Buat project baru
    ${source_default.cyan("henotic generate <model>")}     Generate model baru

    ${source_default.cyan("henotic seed <module>")}        Jalankan seed pada module
    ${source_default.cyan("henotic unseed <module>")}      Jalankan unseed pada module
    ${source_default.cyan("henotic migrate <module>")}     Jalankan migrate pada module
    ${source_default.cyan("henotic drop <module>")}        Jalankan drop table pada module
    ${source_default.cyan("henotic reset <module>")}       Drop + migrate + seed pada module

    ${source_default.cyan("henotic start")}                Jalankan aplikasi (production)
    ${source_default.cyan("henotic dev")}                  Jalankan aplikasi (development)
    ${source_default.cyan("henotic build")}                Build aplikasi (TypeScript)
    
    ${source_default.cyan("henotic [options]")}

${source_default.bold("Options:")}
    ${source_default.green("-h, --help")}     Tampilkan bantuan
    ${source_default.green("-v, --version")}  Tampilkan versi CLI
    ${source_default.green("--all")}          Jalankan pada semua module (untuk seed/unseed/migrate/drop/reset)

${source_default.bold("Examples:")}
    ${source_default.cyan("henotic new my-app")}    Buat project di folder baru
    ${source_default.cyan("henotic new .")}         Inisialisasi di folder saat ini
    ${source_default.cyan("henotic generate Product title:string price:number")}  Generate model
    ${source_default.cyan("henotic seed User")}     Jalankan seed pada module User
    ${source_default.cyan("henotic reset User")}    Reset module User (drop + migrate + seed)
    ${source_default.cyan("henotic reset --all")}   Reset semua module
    ${source_default.cyan("henotic dev")}           Jalankan aplikasi dalam mode development
    ${source_default.cyan("henotic -v")}            Cek versi terinstall
    ${source_default.cyan("henotic update")}        Update CLI ke versi terbaru
`);
}
function showVersion() {
  console.log(`
\uD83E\uDD9C Henotic v${packageJson.version}`);
  console.log(`\uD83C\uDF10 ${source_default.blue("https://github.com/hens-msn")}
`);
}
async function deleteHenotic() {
  const { confirm } = await import_prompts7.default({
    type: "confirm",
    name: "confirm",
    message: "Apakah kamu yakin ingin menghapus Henotic CLI?",
    initial: false
  }, promptsConfig5);
  if (!confirm) {
    console.log(source_default.yellow("\u274C Penghapusan Henotic CLI dibatalkan"));
    return;
  }
  console.log(source_default.cyan(`
\uD83D\uDDD1\uFE0F  Menghapus Henotic CLI...`));
  try {
    const osProcess = Bun.spawn(["uname", "-s"], {
      stdout: "pipe"
    });
    const osOutput = await new Response(osProcess.stdout).text();
    const os2 = osOutput.trim();
    const homeDir = process.env.HOME || process.env.USERPROFILE || ".";
    const installDir = `${homeDir}/.henotic`;
    const binLocations = [
      "/usr/local/bin/henotic",
      `${homeDir}/.local/bin/henotic`,
      "/usr/bin/henotic"
    ];
    if (os2 === "Linux" || os2 === "Darwin") {
      console.log(source_default.cyan("\uD83D\uDD0D Mencari dan menghapus symlink Henotic..."));
      for (const binPath of binLocations) {
        const fileExists3 = await Bun.file(binPath).exists();
        if (fileExists3) {
          console.log(source_default.cyan(`\uD83D\uDDD1\uFE0F Menghapus ${binPath}...`));
          let rmProcess = Bun.spawn(["rm", "-f", binPath], {
            stdio: ["inherit", "inherit", "inherit"]
          });
          let exitCode = await rmProcess.exited;
          if (exitCode !== 0) {
            console.log(source_default.yellow(`\u26A0\uFE0F Memerlukan hak akses root untuk menghapus ${binPath}...`));
            rmProcess = Bun.spawn(["sudo", "rm", "-f", binPath], {
              stdio: ["inherit", "inherit", "inherit"]
            });
            await rmProcess.exited;
          }
        }
      }
    }
    if (await Bun.file(installDir).exists()) {
      console.log(source_default.cyan(`\uD83D\uDDD1\uFE0F Menghapus direktori instalasi ${installDir}...`));
      const rmDirProcess = Bun.spawn(["rm", "-rf", installDir], {
        stdio: ["inherit", "inherit", "inherit"]
      });
      await rmDirProcess.exited;
    }
    console.log(source_default.cyan("\uD83D\uDD0D Memeriksa apakah diinstall dengan bun..."));
    const bunListProcess = Bun.spawn(["bun", "pm", "ls", "-g"], {
      stdout: "pipe"
    });
    const bunListOutput = await new Response(bunListProcess.stdout).text();
    if (bunListOutput.includes("henotic-cli")) {
      console.log(source_default.cyan("\uD83D\uDDD1\uFE0F Menghapus henotic-cli dari bun global packages..."));
      const deleteProcess = Bun.spawn([
        "bun",
        "rm",
        "-g",
        "--silent",
        "henotic-cli"
      ], {
        stdio: ["inherit", "inherit", "inherit"]
      });
      await deleteProcess.exited;
    }
    const whichProcess = Bun.spawn(["which", "henotic"], {
      stdout: "pipe",
      stderr: "pipe"
    });
    await whichProcess.exited;
    if (whichProcess.exitCode === 0) {
      const henoticPath = await new Response(whichProcess.stdout).text();
      console.log(source_default.yellow(`\u26A0\uFE0F Henotic masih terdeteksi di ${henoticPath.trim()}`));
      console.log(source_default.yellow("   Mungkin ada instalasi lain yang belum terhapus."));
    } else {
      console.log(source_default.green("\u2705 Henotic CLI berhasil dihapus dari sistem!"));
    }
    console.log(source_default.cyan("\uD83D\uDC4B Terima kasih telah menggunakan Henotic CLI!"));
  } catch (error) {
    console.error(source_default.red(`\u274C Gagal menghapus Henotic CLI: ${error instanceof Error ? error.message : String(error)}`));
    process.exit(1);
  }
}
async function getLatestVersion() {
  try {
    console.log(source_default.cyan("\uD83D\uDD0D Mengecek versi terbaru..."));
    const response = await fetch("https://api.github.com/repos/hens-msn/henotic/releases/latest", {
      headers: {
        Accept: "application/vnd.github.v3+json",
        "User-Agent": "Henotic-CLI"
      }
    });
    if (response.ok) {
      const data = await response.json();
      if (data.assets && data.assets.length > 0) {
        for (const asset of data.assets) {
          const versionMatch = asset.name.match(/v(\d+\.\d+\.\d+)/);
          if (versionMatch && versionMatch[1]) {
            return versionMatch[1];
          }
        }
      }
    }
    return null;
  } catch (error) {
    console.error(source_default.yellow(`\u26A0\uFE0F Gagal mengecek versi terbaru: ${error instanceof Error ? error.message : String(error)}`));
    return null;
  }
}
async function updateHenotic() {
  console.log(source_default.cyan(`
\uD83D\uDE80 Updating Henotic CLI...`));
  const latestVersion = await getLatestVersion();
  const currentVersion = packageJson.version;
  if (latestVersion) {
    if (latestVersion === currentVersion) {
      console.log(source_default.green(`\u2705 Henotic CLI sudah versi terbaru (v${currentVersion})!`));
      return;
    } else {
      console.log(source_default.cyan(`\uD83D\uDCCC Versi terbaru: v${latestVersion} (terpasang: v${currentVersion})`));
    }
  } else {
    console.log(source_default.yellow(`\u26A0\uFE0F Tidak dapat mengecek versi terbaru. Melanjutkan dengan versi saat ini (v${currentVersion}).`));
  }
  const version2 = latestVersion || currentVersion;
  const tempDir = `/tmp/henotic-update-${Date.now()}`;
  try {
    await Bun.spawn(["mkdir", "-p", tempDir], {
      stdio: ["inherit", "inherit", "inherit"]
    }).exited;
    const osProcess = Bun.spawn(["uname", "-s"], {
      stdout: "pipe"
    });
    const osOutput = await new Response(osProcess.stdout).text();
    const os2 = osOutput.trim();
    const archProcess = Bun.spawn(["uname", "-m"], {
      stdout: "pipe"
    });
    const archOutput = await new Response(archProcess.stdout).text();
    const arch = archOutput.trim();
    console.log(source_default.cyan(`\uD83D\uDD0D Terdeteksi sistem: ${os2} ${arch}`));
    let downloadUrl = "";
    let filename = "";
    if (os2 === "Linux") {
      if (arch === "x86_64") {
        downloadUrl = `https://github.com/hens-msn/henotic/releases/download/henotic/henotic-linux-x64-v${version2}.tar.gz`;
        filename = `henotic-linux-x64-v${version2}.tar.gz`;
      } else {
        throw new Error(`Arsitektur Linux ${arch} belum didukung.`);
      }
    } else if (os2 === "Darwin") {
      if (arch === "arm64") {
        downloadUrl = `https://github.com/hens-msn/henotic/releases/download/henotic/henotic-mac-arm64-v${version2}.tar.gz`;
        filename = `henotic-mac-arm64-v${version2}.tar.gz`;
      } else {
        throw new Error(`Arsitektur macOS ${arch} belum didukung.`);
      }
    } else if (os2.includes("MINGW") || os2.includes("MSYS") || os2.includes("CYGWIN")) {
      downloadUrl = `https://github.com/hens-msn/henotic/releases/download/henotic/henotic-win-v${version2}.exe`;
      filename = `henotic-win-v${version2}.exe`;
    } else {
      throw new Error(`OS ${os2} tidak didukung.`);
    }
    console.log(source_default.cyan(`\uD83D\uDCE5 Mengunduh Henotic dari ${downloadUrl}...`));
    const downloadProcess = Bun.spawn(["curl", "-L", downloadUrl, "-o", `${tempDir}/${filename}`], {
      stdio: ["inherit", "inherit", "inherit"]
    });
    await downloadProcess.exited;
    if (downloadProcess.exitCode !== 0) {
      throw new Error("Gagal mengunduh file update.");
    }
    const statProcess = Bun.spawn(["stat", "-c", "%s", `${tempDir}/${filename}`], {
      stdout: "pipe"
    });
    const fileSize = parseInt(await new Response(statProcess.stdout).text().then((s) => s.trim()), 10);
    if (isNaN(fileSize) || fileSize < 1000) {
      throw new Error(`File yang diunduh terlalu kecil (${fileSize} bytes). URL mungkin tidak valid.`);
    }
    let executablePath = "";
    if (filename.endsWith(".tar.gz")) {
      console.log(source_default.cyan("\uD83D\uDCE6 Mengekstrak file tar.gz..."));
      const extractProcess = Bun.spawn(["tar", "-xzf", `${tempDir}/${filename}`, "-C", tempDir], {
        stdio: ["inherit", "inherit", "inherit"]
      });
      await extractProcess.exited;
      if (extractProcess.exitCode !== 0) {
        throw new Error("Gagal mengekstrak file tar.gz.");
      }
      const findProcess = Bun.spawn(["find", tempDir, "-type", "f", "-executable"], {
        stdout: "pipe"
      });
      const findOutput = await new Response(findProcess.stdout).text();
      const executableFiles = findOutput.trim().split(`
`).filter(Boolean);
      if (executableFiles.length === 0) {
        console.log(source_default.yellow("\u26A0\uFE0F Tidak dapat menemukan file executable dalam tar.gz."));
        const lsProcess = Bun.spawn(["ls", "-la", tempDir], {
          stdio: ["inherit", "inherit", "inherit"]
        });
        await lsProcess.exited;
        throw new Error("Tidak dapat menemukan file executable dalam tar.gz.");
      }
      executablePath = executableFiles[0];
      console.log(source_default.cyan(`\u2705 File executable ditemukan: ${executablePath}`));
    } else {
      executablePath = `${tempDir}/${filename}`;
      await Bun.spawn(["chmod", "+x", executablePath], {
        stdio: ["inherit", "inherit", "inherit"]
      }).exited;
    }
    const installDir = os2 === "Linux" || os2 === "Darwin" ? "/usr/local/bin" : ".";
    if (os2 === "Linux" || os2 === "Darwin") {
      console.log(source_default.cyan(`\uD83D\uDCCB Menginstall ke ${installDir}/henotic...`));
      const tempExecutable = `${installDir}/henotic.new`;
      let installProcess = Bun.spawn(["cp", executablePath, tempExecutable], {
        stdio: ["inherit", "inherit", "inherit"]
      });
      let exitCode = await installProcess.exited;
      if (exitCode !== 0) {
        console.log(source_default.yellow("\u26A0\uFE0F Memerlukan hak akses root, mencoba dengan sudo..."));
        installProcess = Bun.spawn(["sudo", "cp", executablePath, tempExecutable], {
          stdio: ["inherit", "inherit", "inherit"]
        });
        exitCode = await installProcess.exited;
        if (exitCode !== 0) {
          throw new Error(`Gagal menyalin ke ${tempExecutable}`);
        }
        await Bun.spawn(["sudo", "chmod", "+x", tempExecutable], {
          stdio: ["inherit", "inherit", "inherit"]
        }).exited;
        console.log(source_default.cyan("\uD83D\uDD04 Mengganti file executable lama..."));
        const mvProcess = Bun.spawn(["sudo", "mv", "-f", tempExecutable, `${installDir}/henotic`], {
          stdio: ["inherit", "inherit", "inherit"]
        });
        exitCode = await mvProcess.exited;
        if (exitCode !== 0) {
          console.log(source_default.yellow("\u26A0\uFE0F Tidak dapat mengganti file yang sedang digunakan."));
          console.log(source_default.yellow("   File update tersedia di " + tempExecutable));
          console.log(source_default.yellow("   Silakan tutup terminal ini dan jalankan:"));
          console.log(source_default.cyan(`   sudo mv -f ${tempExecutable} ${installDir}/henotic`));
        }
      } else {
        await Bun.spawn(["chmod", "+x", tempExecutable], {
          stdio: ["inherit", "inherit", "inherit"]
        }).exited;
        console.log(source_default.cyan("\uD83D\uDD04 Mengganti file executable lama..."));
        const mvProcess = Bun.spawn(["mv", "-f", tempExecutable, `${installDir}/henotic`], {
          stdio: ["inherit", "inherit", "inherit"]
        });
        exitCode = await mvProcess.exited;
        if (exitCode !== 0) {
          console.log(source_default.yellow("\u26A0\uFE0F Memerlukan hak akses root, mencoba dengan sudo..."));
          const sudoMvProcess = Bun.spawn(["sudo", "mv", "-f", tempExecutable, `${installDir}/henotic`], {
            stdio: ["inherit", "inherit", "inherit"]
          });
          exitCode = await sudoMvProcess.exited;
          if (exitCode !== 0) {
            console.log(source_default.yellow("\u26A0\uFE0F Tidak dapat mengganti file yang sedang digunakan."));
            console.log(source_default.yellow("   File update tersedia di " + tempExecutable));
            console.log(source_default.yellow("   Silakan tutup terminal ini dan jalankan:"));
            console.log(source_default.cyan(`   sudo mv -f ${tempExecutable} ${installDir}/henotic`));
          }
        }
      }
    } else {
      console.log(source_default.yellow("\u26A0\uFE0F Untuk Windows, silakan install manual dengan menjalankan file yang diunduh."));
      console.log(source_default.cyan(`\uD83D\uDCCB File executable tersedia di: ${executablePath}`));
    }
    await Bun.spawn(["rm", "-rf", tempDir], {
      stdio: ["inherit", "inherit", "inherit"]
    }).exited;
    console.log(source_default.green("\u2705 Henotic CLI berhasil diupdate!"));
    console.log(source_default.cyan("\uD83D\uDD04 Silakan restart terminal untuk menggunakan versi baru."));
  } catch (error) {
    console.error(source_default.red(`\u274C Gagal mengupdate Henotic CLI: ${error instanceof Error ? error.message : String(error)}`));
    await Bun.spawn(["rm", "-rf", tempDir], {
      stdio: ["inherit", "inherit", "inherit"]
    }).exited;
    process.exit(1);
  }
}
async function generateModel(modelName, fields) {
  if (!modelName || fields.length === 0) {
    console.error(source_default.red(`
\u274C Format command generate: henotic generate <ModelName> <field:type> ...`));
    console.log(source_default.yellow("Contoh: henotic generate Product title:string price:number"));
    process.exit(1);
  }
  try {
    const config = JSON.parse(await Bun.file("henotic.config.json").text());
    if (config.language === "typescript") {
      await generateCommand(modelName, fields);
    } else if (config.language === "golang" || config.language === "go") {
      await generateCommand2(modelName, fields);
    } else {
      console.error(source_default.red(`
\u274C Generator untuk ${config.language} belum tersedia!`));
      process.exit(1);
    }
  } catch (error) {
    console.error(source_default.red(`
\u274C Gagal generate - pastikan sudah di dalam project henotic!`));
    console.log(source_default.yellow("Tips: Jalankan dari root project yg sudah di-init"));
    process.exit(1);
  }
}
async function seedModule(moduleName, options) {
  try {
    const config = await readConfig();
    const modulePath = config.projectDir ? `${config.projectDir}/modules` : "modules";
    if (config.language === "typescript") {
      const seedProcess = Bun.spawn([
        "bun",
        `${modulePath}/${pluralize(moduleName).toLowerCase()}/${moduleName.toLowerCase()}.seed.ts`,
        "seed"
      ], {
        stdio: ["inherit", "inherit", "inherit"]
      });
      await seedProcess.exited;
    } else if (config.language === "golang" || config.language === "go") {
      const seedProcess = Bun.spawn([
        "go",
        "run",
        "cmd/seed/main.go"
      ], {
        stdio: ["inherit", "inherit", "inherit"]
      });
      await seedProcess.exited;
    }
  } catch (error) {
    console.error(source_default.red(`
\u274C Gagal seed - pastikan sudah di dalam project henotic!`));
    process.exit(1);
  }
}
async function unseedModule(moduleName, options) {
  try {
    const config = await readConfig();
    const modulePath = config.projectDir ? `${config.projectDir}/modules` : "modules";
    if (config.language === "typescript") {
      const unseedProcess = Bun.spawn([
        "bun",
        `${modulePath}/${pluralize(moduleName).toLowerCase()}/${moduleName.toLowerCase()}.seed.ts`,
        "unseed"
      ], {
        stdio: ["inherit", "inherit", "inherit"]
      });
      await unseedProcess.exited;
    } else if (config.language === "golang" || config.language === "go") {
      console.log(source_default.yellow(`
\u26A0\uFE0F Untuk golang, gunakan henotic seed saja karena sudah termasuk unseed.`));
      process.exit(0);
    }
  } catch (error) {
    console.error(source_default.red(`
\u274C Gagal unseed - pastikan sudah di dalam project henotic!`));
    process.exit(1);
  }
}
async function migrateModule(moduleName, options) {
  try {
    const config = await readConfig();
    const modulePath = config.projectDir ? `${config.projectDir}/modules` : "modules";
    if (config.language === "typescript") {
      const migrateProcess = Bun.spawn([
        "bun",
        `${modulePath}/${pluralize(moduleName).toLowerCase()}/${moduleName.toLowerCase()}.migrate.ts`,
        "up"
      ], {
        stdio: ["inherit", "inherit", "inherit"]
      });
      await migrateProcess.exited;
    } else if (config.language === "golang" || config.language === "go") {
      console.log(source_default.yellow(`
\u26A0\uFE0F Untuk golang, gunakan henotic seed saja karena sudah termasuk migrate.`));
      process.exit(0);
    }
  } catch (error) {
    console.error(source_default.red(`
\u274C Gagal migrate - pastikan sudah di dalam project henotic!`));
    process.exit(1);
  }
}
async function dropModule(moduleName, options) {
  try {
    const config = await readConfig();
    const modulePath = config.projectDir ? `${config.projectDir}/modules` : "modules";
    if (config.language === "typescript") {
      const dropProcess = Bun.spawn([
        "bun",
        `${modulePath}/${pluralize(moduleName).toLowerCase()}/${moduleName.toLowerCase()}.migrate.ts`,
        "down"
      ], {
        stdio: ["inherit", "inherit", "inherit"]
      });
      await dropProcess.exited;
    } else if (config.language === "golang" || config.language === "go") {
      console.log(source_default.yellow(`
\u26A0\uFE0F Untuk golang, gunakan henotic seed saja karena sudah termasuk drop.`));
      process.exit(0);
    }
  } catch (error) {
    console.error(source_default.red(`
\u274C Gagal drop - pastikan sudah di dalam project henotic!`));
    process.exit(1);
  }
}
async function runDev() {
  try {
    const config = await readConfig();
    console.log(source_default.cyan(`
\uD83D\uDE80 Menjalankan aplikasi dalam mode development...`));
    if (config.language === "typescript") {
      if (config.framework === "next") {
        const devProcess = Bun.spawn(["bun", "next", "dev"], {
          stdio: ["inherit", "inherit", "inherit"]
        });
        await devProcess.exited;
      } else {
        const entryPoint = config.projectDir ? `${config.projectDir}/index.ts` : "index.ts";
        const devProcess = Bun.spawn(["bun", entryPoint], {
          stdio: ["inherit", "inherit", "inherit"]
        });
        await devProcess.exited;
      }
    } else if (config.language === "golang" || config.language === "go") {
      const devProcess = Bun.spawn(["go", "run", "cmd/main/main.go"], {
        stdio: ["inherit", "inherit", "inherit"],
        env: { ...process.env, APP_ENV: "development" }
      });
      await devProcess.exited;
    } else {
      console.error(source_default.red(`
\u274C Bahasa ${config.language} belum didukung untuk mode development!`));
      process.exit(1);
    }
  } catch (error) {
    console.error(source_default.red(`
\u274C Gagal menjalankan aplikasi - pastikan sudah di dalam project henotic!`));
    process.exit(1);
  }
}
async function runStart() {
  try {
    const config = await readConfig();
    console.log(source_default.cyan(`
\uD83D\uDD28 Building aplikasi terlebih dahulu...`));
    await buildApp();
    console.log(source_default.cyan(`
\uD83D\uDE80 Menjalankan aplikasi dalam mode production...`));
    if (config.language === "typescript") {
      if (config.framework === "next") {
        const startProcess = Bun.spawn(["bun", "next", "start"], {
          stdio: ["inherit", "inherit", "inherit"],
          cwd: process.cwd()
        });
        await startProcess.exited;
      } else {
        const startProcess = Bun.spawn(["bun", "dist/index.js"], {
          stdio: ["inherit", "inherit", "inherit"],
          cwd: process.cwd(),
          env: { ...process.env, NODE_ENV: "production" }
        });
        await startProcess.exited;
      }
    } else if (config.language === "golang" || config.language === "go") {
      const startProcess = Bun.spawn(["./dist/app"], {
        stdio: ["inherit", "inherit", "inherit"],
        cwd: process.cwd(),
        env: { ...process.env, APP_ENV: "production" }
      });
      await startProcess.exited;
    } else {
      console.error(source_default.red(`
\u274C Bahasa ${config.language} belum didukung untuk mode production!`));
      process.exit(1);
    }
  } catch (error) {
    console.error(source_default.red(`
\u274C Gagal menjalankan aplikasi - pastikan sudah di dalam project henotic!`));
    console.log(source_default.yellow(`Detail error: ${error instanceof Error ? error.message : String(error)}`));
    process.exit(1);
  }
}
async function buildApp() {
  try {
    const config = await readConfig();
    if (config.language === "typescript") {
      console.log(source_default.cyan(`
\uD83D\uDD28 Building aplikasi TypeScript...`));
      if (config.framework === "next") {
        const buildProcess = Bun.spawn(["bun", "next", "build"], {
          stdio: ["inherit", "inherit", "inherit"],
          cwd: process.cwd()
        });
        await buildProcess.exited;
        if (buildProcess.exitCode === 0) {
          console.log(source_default.green(`
\u2705 Build Next.js berhasil!`));
        } else {
          console.error(source_default.red(`
\u274C Build Next.js gagal!`));
          process.exit(1);
        }
      } else {
        const entryPoint = config.projectDir ? `${config.projectDir}/index.ts` : "index.ts";
        let finalEntryPoint = entryPoint;
        if (!await Bun.file(entryPoint).exists()) {
          console.log(source_default.yellow(`
\u26A0\uFE0F File ${entryPoint} tidak ditemukan, mencoba mencari index.ts di root...`));
          if (await Bun.file("index.ts").exists()) {
            finalEntryPoint = "index.ts";
          } else {
            throw new Error(`File entrypoint tidak ditemukan: ${entryPoint} atau index.ts`);
          }
        }
        console.log(source_default.cyan("\uD83E\uDDF9 Membersihkan folder dist..."));
        const rmProcess = Bun.spawn(["rm", "-rf", "dist"], {
          stdio: ["inherit", "inherit", "inherit"],
          cwd: process.cwd()
        });
        await rmProcess.exited;
        console.log(source_default.cyan("\uD83D\uDD28 Building dengan Bun..."));
        const buildProcess = Bun.spawn(["bun", "build", finalEntryPoint, "--outdir", "./dist", "--target", "bun"], {
          stdio: ["inherit", "inherit", "inherit"],
          cwd: process.cwd()
        });
        await buildProcess.exited;
        if (buildProcess.exitCode === 0) {
          console.log(source_default.green(`
\u2705 Build berhasil! Output tersedia di folder ./dist`));
        } else {
          console.error(source_default.red(`
\u274C Build gagal!`));
          process.exit(1);
        }
      }
    } else if (config.language === "golang" || config.language === "go") {
      console.log(source_default.cyan(`
\uD83D\uDD28 Building aplikasi Go...`));
      const mkdirProcess = Bun.spawn(["mkdir", "-p", "./dist"], {
        stdio: ["inherit", "inherit", "inherit"],
        cwd: process.cwd()
      });
      await mkdirProcess.exited;
      const buildProcess = Bun.spawn(["go", "build", "-o", "./dist/app", "./cmd/main/main.go"], {
        stdio: ["inherit", "inherit", "inherit"],
        cwd: process.cwd()
      });
      await buildProcess.exited;
      if (buildProcess.exitCode === 0) {
        console.log(source_default.green(`
\u2705 Build berhasil! Output tersedia di ./dist/app`));
      } else {
        console.error(source_default.red(`
\u274C Build gagal!`));
        process.exit(1);
      }
    } else {
      console.error(source_default.red(`
\u274C Bahasa ${config.language} belum didukung untuk build!`));
      process.exit(1);
    }
  } catch (error) {
    console.error(source_default.red(`
\u274C Gagal build aplikasi - pastikan sudah di dalam project henotic!`));
    console.log(source_default.yellow(`Detail error: ${error instanceof Error ? error.message : String(error)}`));
    process.exit(1);
  }
}
async function resetModule(moduleName, options) {
  try {
    const config = await readConfig();
    if (config.language === "typescript") {
      console.log(source_default.cyan(`
\uD83D\uDD04 Melakukan reset pada module ${options.all ? "semua" : moduleName}...`));
      console.log(source_default.yellow(`
\uD83D\uDCE5 Menjalankan drop...`));
      await dropModule(moduleName, options);
      console.log(source_default.yellow(`
\uD83D\uDCE4 Menjalankan migrate...`));
      await migrateModule(moduleName, options);
      console.log(source_default.yellow(`
\uD83C\uDF31 Menjalankan seed...`));
      await seedModule(moduleName, options);
      console.log(source_default.green(`
\u2705 Reset ${options.all ? "semua module" : `module ${moduleName}`} berhasil!`));
    } else if (config.language === "golang" || config.language === "go") {
      console.log(source_default.cyan(`
\uD83D\uDD04 Untuk Go, cukup jalankan seed yang sudah mencakup reset...`));
      await seedModule(moduleName, options);
    } else {
      console.error(source_default.red(`
\u274C Bahasa ${config.language} belum didukung untuk reset!`));
      process.exit(1);
    }
  } catch (error) {
    console.error(source_default.red(`
\u274C Gagal reset - pastikan sudah di dalam project henotic!`));
    console.log(source_default.yellow(`Detail error: ${error instanceof Error ? error.message : String(error)}`));
    process.exit(1);
  }
}
var args = Bun.argv;
var command = args[2];
var projectName = args[3];
var hasAllFlag = args.includes("--all");
switch (command) {
  case "new":
    if (!projectName) {
      console.error(source_default.red(`
\u274C Nama project harus diisi!`));
      showHelp();
      process.exit(1);
    }
    await init(projectName);
    break;
  case "generate":
    await generateModel(args[3], args.slice(4));
    break;
  case "seed":
    await seedModule(hasAllFlag ? "" : args[3], { all: hasAllFlag });
    break;
  case "unseed":
    await unseedModule(hasAllFlag ? "" : args[3], { all: hasAllFlag });
    break;
  case "migrate":
    await migrateModule(hasAllFlag ? "" : args[3], { all: hasAllFlag });
    break;
  case "drop":
    await dropModule(hasAllFlag ? "" : args[3], { all: hasAllFlag });
    break;
  case "reset":
    await resetModule(hasAllFlag ? "" : args[3], { all: hasAllFlag });
    break;
  case "dev":
    await runDev();
    break;
  case "start":
    await runStart();
    break;
  case "build":
    await buildApp();
    break;
  case "--version":
  case "-v":
    showVersion();
    break;
  case "--help":
  case "-h":
  case undefined:
    showHelp();
    break;
  case "update":
    await updateHenotic();
    break;
  case "delete":
    await deleteHenotic();
    break;
  default:
    console.error(source_default.red(`
\u274C Command tidak valid: ${command}`));
    showHelp();
    process.exit(1);
}