network.ts 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. import type { Argv, InferredOptionTypes } from "yargs"
  2. import { ConfigV1 } from "@kirincode-ai/core/v1/config/config"
  3. import type { Config } from "@/config/config"
  4. import { Effect } from "effect"
  5. const options = {
  6. port: {
  7. type: "number" as const,
  8. describe: "port to listen on",
  9. default: 0,
  10. },
  11. hostname: {
  12. type: "string" as const,
  13. describe: "hostname to listen on",
  14. default: "127.0.0.1",
  15. },
  16. mdns: {
  17. type: "boolean" as const,
  18. describe: "enable mDNS service discovery (defaults hostname to 0.0.0.0)",
  19. default: false,
  20. },
  21. "mdns-domain": {
  22. type: "string" as const,
  23. describe: "custom domain name for mDNS service (default: kirincode.local)",
  24. default: "kirincode.local",
  25. },
  26. cors: {
  27. type: "string" as const,
  28. array: true,
  29. describe: "additional domains to allow for CORS",
  30. default: [] as string[],
  31. },
  32. }
  33. export type NetworkOptions = InferredOptionTypes<typeof options>
  34. export function withNetworkOptions<T>(yargs: Argv<T>) {
  35. return yargs.options(options)
  36. }
  37. export function hasArg(name: string) {
  38. return networkArgs().some((arg) => arg === name || arg.startsWith(name + "="))
  39. }
  40. function hasBooleanArg(name: string) {
  41. return networkArgs().some(
  42. (arg) => arg === name || arg === name + "=true" || arg === name + "=false" || arg === "--no-" + name.slice(2),
  43. )
  44. }
  45. function networkArgs() {
  46. const separator = process.argv.indexOf("--")
  47. return process.argv.slice(2, separator === -1 ? undefined : separator)
  48. }
  49. export const resolveNetworkOptions = Effect.fn("Cli.resolveNetworkOptions")(function* (args: NetworkOptions) {
  50. const { Config } = yield* Effect.promise(() => import("@/config/config"))
  51. const config = yield* Config.Service.use((cfg) => cfg.getGlobal())
  52. return resolveNetworkOptionsNoConfig(args, config)
  53. })
  54. export function resolveNetworkOptionsNoConfig(args: NetworkOptions, config?: ConfigV1.Info) {
  55. const portExplicitlySet = hasArg("--port")
  56. const hostnameExplicitlySet = hasArg("--hostname")
  57. const mdnsExplicitlySet = hasBooleanArg("--mdns")
  58. const mdnsDomainExplicitlySet = hasArg("--mdns-domain")
  59. const mdns = mdnsExplicitlySet ? args.mdns : (config?.server?.mdns ?? args.mdns)
  60. const mdnsDomain = mdnsDomainExplicitlySet ? args["mdns-domain"] : (config?.server?.mdnsDomain ?? args["mdns-domain"])
  61. const port = portExplicitlySet ? args.port : (config?.server?.port ?? args.port)
  62. const hostname = hostnameExplicitlySet
  63. ? args.hostname
  64. : mdns && !config?.server?.hostname
  65. ? "0.0.0.0"
  66. : (config?.server?.hostname ?? args.hostname)
  67. const configCors = config?.server?.cors ?? []
  68. const argsCors = Array.isArray(args.cors) ? args.cors : args.cors ? [args.cors] : []
  69. const cors = [...configCors, ...argsCors]
  70. return { hostname, port, mdns, mdnsDomain, cors }
  71. }