{"version":3,"file":"connect-config-_kiSMsbG.mjs","sources":["../src/utils/get-at-path.ts","../src/services/connect-config.ts"],"sourcesContent":["/**\n * Walk a parsed path (e.g. from remeda's `stringToPath`) through a runtime-\n * typed object, returning the value or `undefined` if any segment is\n * missing.\n *\n * Remeda's `prop` is overload-typed for compile-time literal paths and\n * doesn't accept a runtime path array via spread, so we walk inline for\n * the dynamic-path case used by `ph connect config --get`.\n */\nexport function getAtPath(\n  obj: unknown,\n  parts: ReadonlyArray<string | number>,\n): unknown {\n  let cur: unknown = obj;\n  for (const key of parts) {\n    if (cur === null || typeof cur !== \"object\") return undefined;\n    cur = (cur as Record<string, unknown>)[String(key)];\n  }\n  return cur;\n}\n","// `ph connect config` — read or update Connect's runtime configuration.\n//\n// Mode dispatch (exactly one mode per invocation; mutex enforced below):\n//\n//   ph connect config                              → list mode (print effective merged config)\n//   ph connect config <key>                        → get mode (positional)\n//   ph connect config --get <dotted.path>          → get mode (flag form, equivalent)\n//   ph connect config <key> <value>                → set mode (positional, dual-write source + dist)\n//   ph connect config --<field> <value>            → set mode (flag form)\n//   ph connect config --json '{...}'               → bulk-set mode (dual-write)\n//\n// Dual-write semantics for set / bulk-set:\n//   - Source `powerhouse.config.json` (project root) gets the connect.* patch\n//     deep-merged into `connect.*`. `--packages-registry` lands at the\n//     top-level `packageRegistryUrl` field (project-wide setting, also read\n//     by `ph install` / `ph publish` / Switchboard).\n//   - Dist `powerhouse.config.json` (default `.ph/connect-build/dist/`) gets\n//     the same connect.* patch deep-merged in, and the same top-level\n//     `packageRegistryUrl` if set. The runtime schema mirrors the source\n//     schema, so the field lives at the same path in both files.\n//\n// The dist write is skipped silently if the dist file doesn't exist — that's\n// the \"config-only-before-first-build\" workflow, not an error.\n//\n// Field flags + the 4 commonArgs flags (base, log-level, default-drives-url,\n// drive-preserve-strategy) come from the same source as `ph connect build`'s\n// flags, so the two commands share identical CLI surfaces. The 4 commonArgs\n// flags carry cmd-ts defaults; we gate them through `wasFlagExplicitlyPassed`\n// for the same reason `buildCliConnectOverride` does — to avoid leaking\n// default values into a write the user didn't request.\n\nimport type {\n  PHConnectRuntimeConfig,\n  PowerhouseConfig,\n} from \"@powerhousedao/shared/clis\";\nimport {\n  ConfigLoader,\n  JsonConfigAdapter,\n  deepMerge,\n  resolveSourceConnect,\n} from \"@powerhousedao/shared/connect\";\nimport { existsSync } from \"node:fs\";\nimport { isAbsolute, join, resolve } from \"node:path\";\nimport { stringToPath } from \"remeda\";\nimport type { ConnectConfigArgs } from \"../types.js\";\nimport {\n  buildConnectFlagPatch,\n  wasFlagExplicitlyPassed,\n  type ConnectFlagInput,\n} from \"../utils/cli-connect-override.js\";\nimport {\n  normalizeKey,\n  parseCliValue,\n  validateConnectKeyValue,\n  validateConnectPatch,\n} from \"../utils/connect-config-validation.js\";\nimport { getAtPath } from \"../utils/get-at-path.js\";\n\ntype ConnectPartial = Partial<PHConnectRuntimeConfig>;\n\nconst SOURCE_FILE = \"powerhouse.config.json\";\nconst DEFAULT_DIST_SUBPATH = \".ph/connect-build/dist\";\n\nfunction resolveSourcePath(cwd: string): string {\n  return join(cwd, SOURCE_FILE);\n}\n\nfunction resolveDistPath(cwd: string, distDirArg: string | undefined): string {\n  const fromArg = distDirArg;\n  const fromEnv = process.env.PH_CONNECT_OUTDIR;\n  const dir = fromArg ?? fromEnv ?? DEFAULT_DIST_SUBPATH;\n  const abs = isAbsolute(dir) ? dir : resolve(cwd, dir);\n  return join(abs, SOURCE_FILE);\n}\n\n/**\n * Read the source file's raw bytes (no merge with defaults). Returns an empty\n * object stub when the file doesn't exist — the operator can config their way\n * to a complete file before ever running `ph connect build`.\n */\nasync function readSourceRaw(path: string): Promise<Record<string, unknown>> {\n  if (!existsSync(path)) return {};\n  const adapter = new JsonConfigAdapter({ path });\n  const raw = await adapter.read();\n  return raw && typeof raw === \"object\" && !Array.isArray(raw)\n    ? (raw as Record<string, unknown>)\n    : {};\n}\n\nasync function writeSourceRaw(\n  path: string,\n  next: Record<string, unknown>,\n): Promise<void> {\n  const adapter = new JsonConfigAdapter({ path });\n  // ConfigShape requires a `connect` key; ensure it's present.\n  const shape = {\n    ...next,\n    connect: (next.connect as PHConnectRuntimeConfig | undefined) ?? {},\n  };\n  await adapter.write(shape);\n}\n\n/**\n * Build the merged \"effective\" connect block for list/get mode: defaults <\n * source.workflows < source.connect. Doesn't go through env or dist — list\n * mode shows what the source declares + defaults, which is what the next\n * build will produce as a baseline (before env seeds + CLI overrides).\n */\nfunction effectiveConnect(\n  source: Record<string, unknown>,\n): PHConnectRuntimeConfig {\n  const sourceConnect =\n    source.connect &&\n    typeof source.connect === \"object\" &&\n    !Array.isArray(source.connect)\n      ? (source.connect as ConnectPartial)\n      : {};\n  return resolveSourceConnect({\n    connect: sourceConnect,\n    workflows: source.workflows as PowerhouseConfig[\"workflows\"],\n  });\n}\n\nfunction printJson(value: unknown): void {\n  process.stdout.write(`${JSON.stringify(value, null, 2)}\\n`);\n}\n\n/**\n * Translate the parsed `ph connect config` args into the structural\n * `ConnectFlagInput` consumed by `buildConnectFlagPatch`. Common-args flags\n * with cmd-ts defaults are gated through `wasFlagExplicitlyPassed` so the\n * defaults don't leak into a write the user didn't request. `--base` is\n * not translated here — it's rejected up front by `runConnectConfig`.\n */\nfunction argsToFlagInput(args: ConnectConfigArgs): ConnectFlagInput {\n  return {\n    renownUrl: args.renownUrl,\n    renownNetworkId: args.renownNetworkId,\n    renownChainId: args.renownChainId,\n    renownNamespace: args.renownNamespace,\n    renownSwitchboardUrl: args.renownSwitchboardUrl,\n    allowAddDrive: args.allowAddDrive,\n    externalPackages: args.externalPackages,\n    workflows: args.workflows,\n    remoteDrivesEnabled: args.remoteDrivesEnabled,\n    remoteDrivesAllowAdd: args.remoteDrivesAllowAdd,\n    remoteDrivesAllowDelete: args.remoteDrivesAllowDelete,\n    localDrivesEnabled: args.localDrivesEnabled,\n    localDrivesAllowAdd: args.localDrivesAllowAdd,\n    localDrivesAllowDelete: args.localDrivesAllowDelete,\n    appName: args.appName,\n    homeBackground: args.homeBackground,\n    sentryDsn: args.sentryDsn,\n    sentryEnv: args.sentryEnv,\n    sentryTracingEnabled: args.sentryTracingEnabled,\n    logLevel: wasFlagExplicitlyPassed(\"log-level\") ? args.logLevel : undefined,\n    defaultDrivesUrl: wasFlagExplicitlyPassed(\"default-drives-url\")\n      ? args.defaultDrivesUrl\n      : undefined,\n    drivesPreserveStrategy: wasFlagExplicitlyPassed(\"drive-preserve-strategy\")\n      ? args.drivesPreserveStrategy\n      : undefined,\n  };\n}\n\n/**\n * Whether any field flag (any of the 20) was passed. Distinguishes the\n * single-field-set mode from list mode when neither `--get` nor `--json` is\n * present.\n */\nfunction hasAnyFieldFlag(input: ConnectFlagInput): boolean {\n  // Object.values doesn't include json (which isn't in ConnectFlagInput here).\n  // Cast to a generic record so the `!== undefined` predicate is type-aware:\n  // ConnectFlagInput's optional properties narrow `v` in a way TS thinks\n  // excludes `undefined`, even though at runtime any of them can be unset.\n  return Object.values(input as Record<string, unknown>).some(\n    (v) => v !== undefined,\n  );\n}\n\nexport async function runConnectConfig(args: ConnectConfigArgs): Promise<void> {\n  // `--base` is a build-time field (baked into the Vite bundle's asset URLs\n  // and the nginx config template), so writing it post-build leaves the\n  // layers disagreeing and the SPA's assets 404. The flag stays declared so\n  // cmd-ts parses it; we reject explicit use here with an actionable error.\n  if (wasFlagExplicitlyPassed(\"base\")) {\n    throw new Error(\n      \"ph connect config: --base is a build-time field; run `ph connect build --base <value>` and redeploy the container (or restart with PH_CONNECT_BASE_PATH=<value> set in the environment).\",\n    );\n  }\n\n  const cwd = process.cwd();\n  const sourcePath = resolveSourcePath(cwd);\n  const distPath = resolveDistPath(cwd, args.distDir);\n\n  const flagInput = argsToFlagInput(args);\n  const hasGet = args.get !== undefined;\n  const hasJson = args.json !== undefined;\n  const hasFieldFlag = hasAnyFieldFlag(flagInput);\n  // `--packages-registry` is a top-level field, not part of the connect-flag\n  // patch. Track it separately so the set-mode write puts it in the right\n  // place and the mutex counts it as a \"field flag\".\n  const explicitRegistry = args.packagesRegistry;\n  const hasExplicitRegistry = explicitRegistry !== undefined;\n  // Positional pair: 1 positional = get, 2 = set. cmd-ts assigns the first\n  // positional to `keyPositional` and the second to `valuePositional`, so a\n  // standalone <value> isn't representable here.\n  const hasPositionalKey = args.keyPositional !== undefined;\n  const hasPositionalValue = args.valuePositional !== undefined;\n  const hasPositional = hasPositionalKey;\n\n  // Mutex: positional / --get / --json / (any field flag OR\n  // --packages-registry) are mutually exclusive. Exactly one mode (or none →\n  // list) per call. Counting positional as a single mode regardless of arity:\n  // a `<key>` alone is a get, `<key> <value>` is a set, both occupy the same\n  // \"positional mode\" slot vs. the other forms.\n  const modeCount = [\n    hasPositional,\n    hasGet,\n    hasJson,\n    hasFieldFlag || hasExplicitRegistry,\n  ].filter(Boolean).length;\n  if (modeCount > 1) {\n    throw new Error(\n      \"ph connect config: positional <key>/<value>, --get, --json, and individual field flags are mutually exclusive. Use one mode per invocation.\",\n    );\n  }\n\n  const source = await readSourceRaw(sourcePath);\n\n  // List mode.\n  if (modeCount === 0) {\n    printJson(effectiveConnect(source));\n    return;\n  }\n\n  // Get mode (either positional `<key>` alone or `--get <key>`).\n  if (hasGet || (hasPositional && !hasPositionalValue)) {\n    const rawKey = hasGet ? args.get! : args.keyPositional!;\n    const sourceLabel = hasGet ? \"--get\" : \"<key>\";\n    const normalized = normalizeKey(rawKey);\n    if (!normalized) {\n      throw new Error(\n        `ph connect config ${sourceLabel}: key cannot be empty. Pass a dotted path inside connect.* (e.g. connect.renown.url).`,\n      );\n    }\n    // `packageRegistryUrl` is a top-level field — look it up on the raw\n    // source object, not inside `effectiveConnect`.\n    if (normalized === \"packageRegistryUrl\") {\n      const value = source.packageRegistryUrl;\n      if (value === undefined) {\n        throw new Error(\n          `ph connect config ${sourceLabel}: no value at key \"${normalized}\". Run \\`ph connect config\\` (no args) to see the available paths.`,\n        );\n      }\n      printJson(value);\n      return;\n    }\n    const value = getAtPath(effectiveConnect(source), stringToPath(normalized));\n    if (value === undefined) {\n      throw new Error(\n        `ph connect config ${sourceLabel}: no value at key \"${normalized}\". Run \\`ph connect config\\` (no args) to see the available paths.`,\n      );\n    }\n    printJson(value);\n    return;\n  }\n\n  // Set / bulk-set mode. Build the connect-side patch from positional\n  // `<key> <value>` (Ajv-validated against the schema at that path), --json\n  // (Ajv-validated as a partial connect.* blob), or individual field flags\n  // (shape guaranteed by cmd-ts type coercion). `--packages-registry` is a\n  // top-level field; if positional `<key>` is `packageRegistryUrl` or --json\n  // carries it, route that to the top-level write.\n  let topLevelRegistry: string | undefined = explicitRegistry;\n  let patch: ConnectPartial;\n  if (hasPositional && hasPositionalValue) {\n    const normalized = normalizeKey(args.keyPositional!);\n    if (!normalized) {\n      throw new Error(\n        \"ph connect config <key>: key cannot be empty. Pass a dotted path inside connect.* (e.g. connect.renown.url).\",\n      );\n    }\n    // Top-level: positional `packageRegistryUrl <value>` writes the top-level\n    // field instead of a connect.* path.\n    if (normalized === \"packageRegistryUrl\") {\n      const parsed = parseCliValue(args.valuePositional!);\n      if (typeof parsed !== \"string\") {\n        throw new Error(\n          `ph connect config: packageRegistryUrl must be a string (got ${typeof parsed}).`,\n        );\n      }\n      topLevelRegistry = parsed;\n      patch = {};\n    } else {\n      patch = validateConnectKeyValue(\n        normalized,\n        args.valuePositional!,\n      ) as ConnectPartial;\n    }\n  } else if (hasJson) {\n    const validated = validateConnectPatch(args.json!) as Record<\n      string,\n      unknown\n    >;\n    if (typeof validated.packageRegistryUrl === \"string\") {\n      topLevelRegistry = topLevelRegistry ?? validated.packageRegistryUrl;\n    }\n    const connectOnly = { ...validated };\n    delete connectOnly.packageRegistryUrl;\n    patch = connectOnly as ConnectPartial;\n  } else {\n    patch = buildConnectFlagPatch(flagInput) as ConnectPartial;\n  }\n\n  if (Object.keys(patch).length === 0 && topLevelRegistry === undefined) {\n    throw new Error(\n      \"ph connect config: nothing to set. Pass at least one field flag (e.g. --renown-url <url>) or --json with a non-empty payload.\",\n    );\n  }\n\n  // Build the next source: top-level packageRegistryUrl (if set) +\n  // connect.* deep-merge.\n  const currentConnect =\n    source.connect &&\n    typeof source.connect === \"object\" &&\n    !Array.isArray(source.connect)\n      ? (source.connect as PHConnectRuntimeConfig)\n      : ({} as PHConnectRuntimeConfig);\n  const nextConnect = deepMerge(\n    currentConnect,\n    patch as PHConnectRuntimeConfig,\n  );\n  const nextSource: Record<string, unknown> = {\n    ...source,\n    connect: nextConnect,\n  };\n  if (topLevelRegistry !== undefined) {\n    nextSource.packageRegistryUrl = topLevelRegistry;\n  }\n\n  await writeSourceRaw(sourcePath, nextSource);\n\n  // Dual-write to dist if it exists. Same shape as source: connect.* block\n  // is deep-merged; top-level `packageRegistryUrl` is set in place.\n  if (existsSync(distPath)) {\n    const distLoader = new ConfigLoader(\n      new JsonConfigAdapter({ path: distPath }),\n    );\n    const distPatch: Record<string, unknown> = { connect: patch };\n    if (topLevelRegistry !== undefined) {\n      distPatch.packageRegistryUrl = topLevelRegistry;\n    }\n    await distLoader.write(distPatch);\n  }\n\n  process.stdout.write(\n    `ph connect config: wrote ${sourcePath}${existsSync(distPath) ? ` and ${distPath}` : \"\"}\\n`,\n  );\n}\n"],"names":[],"mappings":"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","debug_id":"69e6ceee-600a-53f7-8dcb-05415e6549dd"}