var __defProp = Object.defineProperty;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __esm = (fn, res) => function __init() {
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
};
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};

// src/utils/errors.ts
function fileNotFoundError(filePath) {
  return new CliError(`File not found: ${filePath}`, ExitCode.FILE_ERROR);
}
function fileReadError(filePath, cause) {
  const msg = cause ? `Failed to read file: ${filePath} \u2014 ${cause.message}` : `Failed to read file: ${filePath}`;
  return new CliError(msg, ExitCode.FILE_ERROR);
}
function parseError(filePath, detail) {
  const msg = detail ? `Failed to parse file: ${filePath} \u2014 ${detail}` : `Failed to parse file: ${filePath}`;
  return new CliError(msg, ExitCode.FILE_ERROR);
}
function inputError(message) {
  return new CliError(message, ExitCode.INPUT_ERROR);
}
function handleError(err) {
  if (err instanceof CliError) {
    process.stderr.write(`Error: ${err.message}
`);
    process.exit(err.exitCode);
  }
  const message = err instanceof Error ? err.message : String(err);
  process.stderr.write(`Internal error: ${message}
`);
  process.exit(ExitCode.INTERNAL_ERROR);
}
var ExitCode, CliError;
var init_errors = __esm({
  "src/utils/errors.ts"() {
    "use strict";
    ExitCode = {
      SUCCESS: 0,
      VALIDATION_FAILURE: 1,
      FILE_ERROR: 2,
      INPUT_ERROR: 3,
      INTERNAL_ERROR: 4
    };
    CliError = class extends Error {
      exitCode;
      constructor(message, exitCode) {
        super(message);
        this.name = "CliError";
        this.exitCode = exitCode;
      }
    };
  }
});

// src/utils/loader.ts
var loader_exports = {};
__export(loader_exports, {
  detectFormat: () => detectFormat,
  readFhirResource: () => readFhirResource,
  readFileAsObject: () => readFileAsObject,
  readRawFile: () => readRawFile,
  writeOutputFile: () => writeOutputFile
});
import { readFileSync, existsSync, writeFileSync, mkdirSync } from "node:fs";
import { extname, dirname } from "node:path";
import * as yaml from "js-yaml";
function detectFormat(filePath) {
  const ext = extname(filePath).toLowerCase();
  if (ext === ".yaml" || ext === ".yml") return "yaml";
  return "json";
}
function readRawFile(filePath) {
  if (!existsSync(filePath)) {
    throw fileNotFoundError(filePath);
  }
  try {
    return readFileSync(filePath, "utf-8");
  } catch (err) {
    throw fileReadError(filePath, err instanceof Error ? err : void 0);
  }
}
function readFileAsObject(filePath) {
  const content = readRawFile(filePath);
  const format = detectFormat(filePath);
  try {
    if (format === "yaml") {
      return yaml.load(content);
    }
    return JSON.parse(content);
  } catch (err) {
    const detail = err instanceof Error ? err.message : void 0;
    throw parseError(filePath, detail);
  }
}
function readFhirResource(filePath) {
  const obj = readFileAsObject(filePath);
  if (!obj || typeof obj !== "object" || Array.isArray(obj)) {
    throw parseError(filePath, "Expected a JSON object");
  }
  const record = obj;
  if (typeof record.resourceType !== "string" || record.resourceType.length === 0) {
    throw parseError(filePath, "Missing or invalid resourceType");
  }
  return record;
}
function writeOutputFile(filePath, content) {
  const dir = dirname(filePath);
  mkdirSync(dir, { recursive: true });
  writeFileSync(filePath, content, "utf-8");
}
var init_loader = __esm({
  "src/utils/loader.ts"() {
    "use strict";
    init_errors();
  }
});

// src/index.ts
import { Command } from "commander";

// src/commands/validate.ts
init_loader();

// src/utils/context.ts
import { dirname as dirname2, join } from "node:path";
import { fileURLToPath } from "node:url";
import {
  FhirContextImpl,
  MemoryLoader,
  SnapshotGenerator,
  buildCanonicalProfile,
  createRuntime
} from "fhir-runtime";
function getDirname() {
  if (typeof import.meta !== "undefined" && import.meta.url) {
    return dirname2(fileURLToPath(import.meta.url));
  }
  return typeof __dirname !== "undefined" ? __dirname : process.cwd();
}
var currentDir = getDirname();
function getCoreDefsDir() {
  const devPath = join(currentDir, "..", "core-definitions");
  const prodPath = join(currentDir, "core-definitions");
  if (currentDir.includes("src")) {
    return devPath;
  }
  return prodPath;
}
var _ctx = null;
var _preloaded = false;
var _runtime = null;
function getContext() {
  if (!_ctx) {
    _ctx = new FhirContextImpl({
      loaders: [new MemoryLoader(/* @__PURE__ */ new Map())],
      specDirectory: getCoreDefsDir()
    });
  }
  return _ctx;
}
async function ensureCoreDefinitions() {
  const ctx = getContext();
  if (!_preloaded) {
    await ctx.preloadCoreDefinitions();
    _preloaded = true;
  }
  return ctx;
}
async function getRuntime() {
  if (!_runtime) {
    const ctx = await ensureCoreDefinitions();
    _runtime = await createRuntime({ context: ctx, preloadCore: false });
  }
  return _runtime;
}

// src/utils/printer.ts
import chalk from "chalk";
function printSuccess(message) {
  console.log(chalk.green("\u2714") + " " + message);
}
function printError(message) {
  console.error(chalk.red("\u2716") + " " + message);
}
function printInfo(label, value) {
  console.log(chalk.cyan(label) + " " + value);
}
function printJson(data) {
  console.log(JSON.stringify(data, null, 2));
}
function printHeader(title) {
  console.log("");
  console.log(chalk.bold.underline(title));
  console.log("");
}
function printList(items, indent = 2) {
  const pad = " ".repeat(indent);
  for (const item of items) {
    console.log(`${pad}${item}`);
  }
}
function buildTree(obj, prefix = "", isLast = true) {
  const lines = [];
  const keys = Object.keys(obj);
  for (let i = 0; i < keys.length; i++) {
    const key = keys[i];
    const value = obj[key];
    const last = i === keys.length - 1;
    const connector = last ? "\u2514 " : "\u251C ";
    const extension = last ? "  " : "\u2502 ";
    lines.push(`${prefix}${connector}${key}`);
    if (value !== null && typeof value === "object" && !Array.isArray(value)) {
      const subtree = buildTree(
        value,
        prefix + extension,
        last
      );
      lines.push(...subtree);
    }
  }
  return lines;
}

// src/commands/validate.ts
init_errors();
async function runValidate(filePath, options) {
  const resource = readFhirResource(filePath);
  const resourceType = resource.resourceType;
  const runtime = await getRuntime();
  const profileUrl = `http://hl7.org/fhir/StructureDefinition/${resourceType}`;
  const result = await runtime.validate(resource, profileUrl);
  const issues = result.issues ?? [];
  const errors = issues.filter((i) => i.severity === "error");
  const warnings = issues.filter((i) => i.severity === "warning");
  const isValid = options.strict ? errors.length === 0 && warnings.length === 0 : errors.length === 0;
  if (options.json) {
    printJson({
      valid: isValid,
      resourceType,
      errors: errors.length,
      warnings: warnings.length,
      issues: issues.map((i) => ({
        severity: i.severity,
        path: i.path ?? "",
        message: i.message
      }))
    });
  } else if (isValid) {
    printSuccess(`Resource Type: ${resourceType}`);
    printSuccess("Validation Passed");
    if (warnings.length > 0) {
      printHeader(`Warnings (${warnings.length})`);
      printList(
        warnings.map(
          (w) => `${w.path ?? ""} \u2014 warning: ${w.message}`
        )
      );
    }
  } else {
    printError(`Validation Failed (${errors.length} error(s), ${warnings.length} warning(s))`);
    printHeader("Issues");
    printList(
      issues.map(
        (i) => `${i.path ?? ""} \u2014 ${i.severity}: ${i.message}`
      )
    );
  }
  process.exitCode = isValid ? ExitCode.SUCCESS : ExitCode.VALIDATION_FAILURE;
}
function registerValidateCommand(program) {
  program.command("validate <file>").description("Validate a FHIR resource").option("--json", "Output in JSON format").option("--strict", "Strict mode: treat warnings as errors").action(async (file, opts) => {
    try {
      await runValidate(file, opts);
    } catch (err) {
      handleError(err);
    }
  });
}

// src/commands/fhirpath.ts
init_loader();
import { evalFhirPath, evalFhirPathBoolean } from "fhir-runtime";
init_errors();
async function runFhirPath(expression, filePath, options) {
  if (!expression || expression.trim().length === 0) {
    throw inputError("FHIRPath expression is required");
  }
  const resource = readFhirResource(filePath);
  try {
    if (options.boolean) {
      const result = evalFhirPathBoolean(expression, resource);
      if (options.json) {
        printJson({ expression, result });
      } else {
        console.log(String(result));
      }
    } else {
      const results = evalFhirPath(expression, resource);
      if (options.json) {
        printJson({ expression, results });
      } else {
        console.log(JSON.stringify(results));
      }
    }
    process.exitCode = ExitCode.SUCCESS;
  } catch (err) {
    const message = err instanceof Error ? err.message : String(err);
    printError(`FHIRPath evaluation failed: ${message}`);
    process.exitCode = ExitCode.VALIDATION_FAILURE;
  }
}
function registerFhirPathCommand(program) {
  program.command("fhirpath <expression> <file>").description("Evaluate a FHIRPath expression against a FHIR resource").option("--json", "Output in JSON format").option("--boolean", "Evaluate as boolean (true/false)").action(async (expression, file, opts) => {
    try {
      await runFhirPath(expression, file, opts);
    } catch (err) {
      handleError(err);
    }
  });
}

// src/commands/inspect.ts
init_loader();
init_errors();
function buildStructureMap(obj) {
  const result = {};
  if (obj === null || obj === void 0 || typeof obj !== "object") {
    return result;
  }
  const record = obj;
  for (const key of Object.keys(record)) {
    const value = record[key];
    if (Array.isArray(value)) {
      if (value.length > 0 && typeof value[0] === "object" && value[0] !== null) {
        result[key] = buildStructureMap(value[0]);
      } else {
        result[key] = {};
      }
    } else if (typeof value === "object" && value !== null) {
      result[key] = buildStructureMap(value);
    } else {
      result[key] = {};
    }
  }
  return result;
}
function getFieldInfo(resource) {
  if (!resource || typeof resource !== "object") return [];
  const record = resource;
  return Object.keys(record).map((key) => {
    const value = record[key];
    if (Array.isArray(value)) {
      if (value.length > 0 && typeof value[0] === "object" && value[0] !== null) {
        return { name: key, type: "object[]" };
      }
      return { name: key, type: "array" };
    }
    if (typeof value === "object" && value !== null) {
      return { name: key, type: "object" };
    }
    return { name: key, type: typeof value };
  });
}
async function runInspect(filePath, options) {
  const resource = readFhirResource(filePath);
  const resourceType = resource.resourceType;
  if (options.json) {
    const fields2 = getFieldInfo(resource);
    printJson({
      resourceType,
      fieldCount: fields2.length,
      fields: fields2
    });
    process.exitCode = ExitCode.SUCCESS;
    return;
  }
  if (options.tree) {
    const structureMap = buildStructureMap(resource);
    console.log(resourceType);
    const treeLines = buildTree(structureMap);
    for (const line of treeLines) {
      console.log(` ${line}`);
    }
    process.exitCode = ExitCode.SUCCESS;
    return;
  }
  printSuccess(`Resource: ${resourceType}`);
  printHeader("Fields");
  const fields = getFieldInfo(resource);
  printList(fields.map((f) => f.name));
  process.exitCode = ExitCode.SUCCESS;
}
function registerInspectCommand(program) {
  program.command("inspect <file>").description("Inspect a FHIR resource structure").option("--tree", "Display as tree structure").option("--json", "Output in JSON format").action(async (file, opts) => {
    try {
      await runInspect(file, opts);
    } catch (err) {
      handleError(err);
    }
  });
}

// src/commands/bundle.ts
init_loader();
import { extractReferencesFromBundle } from "fhir-runtime";
init_errors();
function assertBundle(resource) {
  if (resource.resourceType !== "Bundle") {
    throw inputError(`Expected a Bundle resource, got: ${resource.resourceType}`);
  }
}
function getEntries(resource) {
  return resource.entry ?? [];
}
async function runBundleAnalyze(filePath, options) {
  const resource = readFhirResource(filePath);
  assertBundle(resource);
  const bundleType = resource.type ?? "unknown";
  const entries = getEntries(resource);
  const counts = /* @__PURE__ */ new Map();
  const details = [];
  for (let i = 0; i < entries.length; i++) {
    const entry = entries[i];
    const res = entry.resource;
    if (!res) continue;
    const rt = res.resourceType ?? "Unknown";
    const id = res.id ?? "";
    counts.set(rt, (counts.get(rt) ?? 0) + 1);
    details.push({ index: i + 1, resourceType: rt, id });
  }
  if (options.json) {
    const resourceCounts = {};
    for (const [k, v] of counts) resourceCounts[k] = v;
    printJson({
      bundleType,
      totalEntries: entries.length,
      resourceCounts,
      ...options.verbose ? { entries: details } : {}
    });
  } else {
    printSuccess(`Bundle Type: ${bundleType}`);
    printSuccess(`Total Entries: ${entries.length}`);
    printHeader("Resources");
    const lines = [];
    for (const [rt, count] of counts) {
      lines.push(`${rt.padEnd(24)} ${count}`);
    }
    printList(lines);
    if (options.verbose) {
      printHeader("Entries");
      printList(
        details.map(
          (d) => `#${String(d.index).padEnd(4)} ${d.resourceType.padEnd(24)} ${d.id}`
        )
      );
    }
  }
  process.exitCode = ExitCode.SUCCESS;
}
async function runBundleExtract(filePath, options) {
  const resource = readFhirResource(filePath);
  assertBundle(resource);
  const entries = getEntries(resource);
  const filtered = entries.filter((e) => {
    if (!e.resource) return false;
    if (options.type && e.resource.resourceType !== options.type) return false;
    return true;
  });
  if (filtered.length === 0) {
    printError(
      options.type ? `No ${options.type} resources found in Bundle` : "No resources found in Bundle"
    );
    process.exitCode = ExitCode.SUCCESS;
    return;
  }
  if (options.output) {
    let written = 0;
    for (const entry of filtered) {
      const res = entry.resource;
      const rt = res.resourceType;
      const id = res.id ?? `unknown-${written}`;
      const outPath = `${options.output}/${rt}-${id}.json`;
      writeOutputFile(outPath, JSON.stringify(res, null, 2));
      written++;
    }
    printSuccess(`Extracted ${written} resource(s) to ${options.output}/`);
  } else if (options.json) {
    printJson(filtered.map((e) => e.resource));
  } else {
    for (const entry of filtered) {
      console.log(JSON.stringify(entry.resource, null, 2));
    }
  }
  process.exitCode = ExitCode.SUCCESS;
}
async function runBundleRefs(filePath, options) {
  const resource = readFhirResource(filePath);
  assertBundle(resource);
  const allRefs = extractReferencesFromBundle(resource);
  const filtered = options.type ? allRefs.filter((r) => r.referenceType === options.type) : allRefs;
  const entries = getEntries(resource);
  const augmented = filtered.map((ref) => {
    const pathParts = ref.path.split(".");
    const sourceType = pathParts[0] ?? "";
    const sourceEntry = entries.find(
      (e) => e.resource && e.resource.resourceType === sourceType
    );
    const sourceId = sourceEntry?.resource?.id;
    const sourceResource = sourceId ? `${sourceType}/${sourceId}` : sourceType;
    return { ...ref, sourceResource };
  });
  if (options.json) {
    printJson(augmented);
  } else {
    printSuccess(`Bundle References: ${augmented.length}`);
    if (augmented.length > 0) {
      printHeader("References");
      printList(
        augmented.map(
          (r) => `${r.sourceResource.padEnd(28)} \u2192 ${r.reference.padEnd(28)} (${r.referenceType})`
        )
      );
    }
  }
  process.exitCode = ExitCode.SUCCESS;
}
function registerBundleCommand(program) {
  const bundle = program.command("bundle").description("Analyze and manipulate FHIR Bundles");
  bundle.command("analyze <file>").description("Analyze a FHIR Bundle \u2014 resource type counts and distribution").option("--json", "Output in JSON format").option("--verbose", "Show each entry with id and resourceType").action(async (file, opts) => {
    try {
      await runBundleAnalyze(file, opts);
    } catch (err) {
      handleError(err);
    }
  });
  bundle.command("extract <file>").description("Extract resources from a FHIR Bundle").option("--type <resourceType>", "Extract only the specified resource type").option("--output <dir>", "Write extracted resources to directory").option("--json", "Output as JSON array to stdout").action(async (file, opts) => {
    try {
      await runBundleExtract(file, opts);
    } catch (err) {
      handleError(err);
    }
  });
  bundle.command("refs <file>").description("Extract reference relationships from a FHIR Bundle").option("--json", "Output in JSON format").option("--type <refType>", "Filter by reference type (literal/absolute/contained/logical)").action(async (file, opts) => {
    try {
      await runBundleRefs(file, opts);
    } catch (err) {
      handleError(err);
    }
  });
}

// src/commands/convert.ts
init_loader();
import * as yaml2 from "js-yaml";
init_errors();
function resolveFormats(inputPath, outputPath, options) {
  const fromFmt = options.from ?? detectFormat(inputPath);
  let toFmt;
  if (options.to) {
    toFmt = options.to;
  } else {
    toFmt = detectFormat(outputPath);
  }
  if (fromFmt === toFmt) {
    throw inputError(`Source and target formats are the same: ${fromFmt}`);
  }
  return { fromFmt, toFmt };
}
async function runConvert(inputPath, outputPath, options) {
  const { toFmt } = resolveFormats(inputPath, outputPath, options);
  const obj = readFileAsObject(inputPath);
  let output;
  if (toFmt === "yaml") {
    output = yaml2.dump(obj, {
      indent: 2,
      lineWidth: 120,
      noRefs: true,
      sortKeys: false
    });
  } else {
    const indent = options.pretty !== false ? 2 : 0;
    output = JSON.stringify(obj, null, indent) + "\n";
  }
  writeOutputFile(outputPath, output);
  printSuccess(`Converted to ${toFmt}: ${outputPath}`);
  process.exitCode = ExitCode.SUCCESS;
}
function registerConvertCommand(program) {
  program.command("convert <input> <output>").description("Convert a FHIR resource between JSON and YAML formats").option("--from <format>", "Source format (json/yaml, auto-detected from extension)").option("--to <format>", "Target format (json/yaml, auto-detected from extension)").option("--pretty", "Pretty-print JSON output (default: true)").action(async (input, output, opts) => {
    try {
      await runConvert(input, output, opts);
    } catch (err) {
      handleError(err);
    }
  });
}

// src/commands/profile.ts
init_loader();
import {
  buildCanonicalProfile as buildCanonicalProfile2,
  SnapshotGenerator as SnapshotGenerator2
} from "fhir-runtime";
init_errors();
function assertStructureDefinition(resource) {
  if (resource.resourceType !== "StructureDefinition") {
    throw inputError(
      `Expected a StructureDefinition resource, got: ${resource.resourceType}`
    );
  }
}
function isUrl(input) {
  return input.startsWith("http://") || input.startsWith("https://");
}
async function runProfileShow(urlOrFile, options) {
  const ctx = await ensureCoreDefinitions();
  let sd = null;
  if (isUrl(urlOrFile)) {
    sd = await ctx.loadStructureDefinition(urlOrFile);
    if (!sd) {
      throw inputError(`StructureDefinition not found: ${urlOrFile}`);
    }
  } else {
    const resource = readFhirResource(urlOrFile);
    assertStructureDefinition(resource);
    sd = resource;
  }
  const name = sd.name ?? "Unknown";
  const url = sd.url ?? "";
  const kind = sd.kind ?? "";
  const abstract_ = sd.abstract;
  const baseDefinition = sd.baseDefinition ?? "";
  const version = sd.version ?? "";
  const status = sd.status ?? "";
  const snapshot = sd.snapshot;
  let sdForCanonical = sd;
  if (!snapshot || !snapshot.element?.length) {
    const generator = new SnapshotGenerator2(ctx, { generateCanonical: false });
    const snapResult = await generator.generate(sd);
    if (snapResult.success) {
      sdForCanonical = snapResult.structureDefinition;
    }
  }
  const canonical = buildCanonicalProfile2(sdForCanonical);
  const elements = canonical.elements ? [...canonical.elements.values()] : [];
  if (options.json) {
    printJson({
      url,
      name,
      kind,
      abstract: abstract_ ?? false,
      baseDefinition,
      version,
      status,
      elementCount: elements.length,
      elements: elements.map((el) => ({
        path: el.path,
        min: el.min,
        max: el.max,
        types: el.types?.map((t) => t.code) ?? [],
        binding: el.binding ? { strength: el.binding.strength, valueSet: el.binding.valueSetUrl } : void 0,
        mustSupport: el.mustSupport ?? false
      }))
    });
    process.exitCode = ExitCode.SUCCESS;
    return;
  }
  printInfo("Profile:", `${name} (${url})`);
  printInfo("Kind:   ", kind);
  if (baseDefinition) {
    printInfo("Base:   ", baseDefinition);
  }
  if (options.full) {
    if (version) printInfo("Version:", version);
    if (status) printInfo("Status: ", status);
    printInfo("Abstract:", String(abstract_ ?? false));
  }
  const required = elements.filter((el) => el.min > 0 && el.path.split(".").length === 2);
  const optional = elements.filter((el) => el.min === 0 && el.path.split(".").length === 2);
  if (required.length > 0) {
    printHeader("REQUIRED");
    printList(
      required.map((el) => {
        const shortPath = el.path.split(".").pop() ?? el.path;
        const typeStr = el.types?.map((t) => t.code).join("|") ?? "";
        const maxStr = el.max === "unbounded" ? "[]" : "";
        const bindingStr = el.binding ? ` (binding: ${el.binding.strength})` : "";
        return `${shortPath.padEnd(20)} ${typeStr}${maxStr}${bindingStr}`;
      })
    );
  }
  if (optional.length > 0) {
    printHeader("OPTIONAL");
    printList(
      optional.map((el) => {
        const shortPath = el.path.split(".").pop() ?? el.path;
        const typeStr = el.types?.map((t) => t.code).join("|") ?? "";
        const maxStr = el.max === "unbounded" ? "[]" : "";
        const bindingStr = el.binding ? ` (binding: ${el.binding.strength})` : "";
        return `${shortPath.padEnd(20)} ${typeStr}${maxStr}${bindingStr}`;
      })
    );
  }
  process.exitCode = ExitCode.SUCCESS;
}
async function runProfileSnapshot(filePath, options) {
  const resource = readFhirResource(filePath);
  assertStructureDefinition(resource);
  const ctx = await ensureCoreDefinitions();
  const generator = new SnapshotGenerator2(ctx, { generateCanonical: !!options.canonical });
  const result = await generator.generate(resource);
  if (!result.success) {
    const issues = result.issues ?? [];
    printError("Snapshot generation failed");
    if (issues.length > 0) {
      printList(issues.map((i) => i.message));
    }
    process.exitCode = ExitCode.VALIDATION_FAILURE;
    return;
  }
  const outputSd = result.structureDefinition;
  const name = outputSd.name ?? "Unknown";
  const url = outputSd.url ?? "";
  const snapshotElements = outputSd.snapshot?.element?.length ?? 0;
  const indent = options.pretty !== false ? 2 : 0;
  const jsonOutput = JSON.stringify(outputSd, null, indent);
  if (options.output) {
    writeOutputFile(options.output, jsonOutput);
    printSuccess("Snapshot generated");
    printInfo("Profile: ", name);
    printInfo("URL:     ", url);
    printInfo("Elements:", String(snapshotElements));
    printInfo("Output:  ", options.output);
  } else {
    console.log(jsonOutput);
  }
  if (options.canonical && result.canonical) {
    printHeader("Canonical Profile");
    console.log(JSON.stringify(result.canonical, null, 2));
  }
  process.exitCode = ExitCode.SUCCESS;
}
async function runProfileValidate(filePath, options) {
  const resource = readFhirResource(filePath);
  assertStructureDefinition(resource);
  const issues = [];
  const requiredFields = ["url", "name", "kind", "type", "status"];
  for (const field of requiredFields) {
    if (!resource[field]) {
      issues.push({
        severity: "error",
        message: `Missing required field: ${field}`
      });
    }
  }
  if (resource.abstract === void 0) {
    issues.push({
      severity: "warning",
      message: 'Field "abstract" is not set (defaults to false)'
    });
  }
  if (resource.derivation === "constraint" && !resource.baseDefinition) {
    issues.push({
      severity: "error",
      message: "Constraint profiles must have a baseDefinition"
    });
  }
  if (!resource.differential) {
    issues.push({
      severity: "warning",
      message: "No differential defined"
    });
  }
  if (issues.filter((i) => i.severity === "error").length === 0) {
    try {
      const ctx = await ensureCoreDefinitions();
      const generator = new SnapshotGenerator2(ctx, { generateCanonical: false });
      const result = await generator.generate(resource);
      if (!result.success) {
        const genIssues = result.issues ?? [];
        for (const gi of genIssues) {
          issues.push({
            severity: "error",
            message: `Snapshot generation: ${gi.message}`
          });
        }
      }
    } catch (err) {
      issues.push({
        severity: "error",
        message: `Snapshot generation failed: ${err instanceof Error ? err.message : String(err)}`
      });
    }
  }
  const errors = issues.filter((i) => i.severity === "error");
  const warnings = issues.filter((i) => i.severity === "warning");
  const isValid = errors.length === 0;
  if (options.json) {
    printJson({
      valid: isValid,
      name: resource.name ?? "",
      url: resource.url ?? "",
      errors: errors.length,
      warnings: warnings.length,
      issues
    });
  } else if (isValid) {
    printSuccess(`StructureDefinition: ${resource.name ?? ""}`);
    printSuccess("Profile validation passed");
    if (warnings.length > 0) {
      printHeader(`Warnings (${warnings.length})`);
      printList(warnings.map((w) => `warning: ${w.message}`));
    }
  } else {
    printError(
      `Profile validation failed (${errors.length} error(s), ${warnings.length} warning(s))`
    );
    printHeader("Issues");
    printList(
      issues.map((i) => `${i.severity}: ${i.message}`)
    );
  }
  process.exitCode = isValid ? ExitCode.SUCCESS : ExitCode.VALIDATION_FAILURE;
}
function registerProfileCommand(program) {
  const profile = program.command("profile").description("View and manipulate FHIR StructureDefinition profiles");
  profile.command("show <url-or-file>").description("Show profile constraints and metadata").option("--fields", "Show field constraints (default)").option("--full", "Show full metadata").option("--json", "Output in JSON format").action(async (urlOrFile, opts) => {
    try {
      await runProfileShow(urlOrFile, opts);
    } catch (err) {
      handleError(err);
    }
  });
  profile.command("snapshot <file>").description("Generate a snapshot for a StructureDefinition").option("--output <file>", "Write output to file").option("--pretty", "Pretty-print JSON (default: true)").option("--canonical", "Also output CanonicalProfile representation").action(async (file, opts) => {
    try {
      await runProfileSnapshot(file, opts);
    } catch (err) {
      handleError(err);
    }
  });
  profile.command("validate <file>").description("Validate a StructureDefinition file").option("--json", "Output in JSON format").action(async (file, opts) => {
    try {
      await runProfileValidate(file, opts);
    } catch (err) {
      handleError(err);
    }
  });
}

// src/commands/package.ts
import { NpmPackageLoader, PackageManager } from "fhir-runtime";
init_errors();
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
import { join as join2 } from "node:path";
var _packageManager = null;
function getPackageManager() {
  if (!_packageManager) {
    _packageManager = new PackageManager();
  }
  return _packageManager;
}
async function runPackageLoad(pkgPath, options) {
  if (!existsSync2(pkgPath)) {
    throw fileNotFoundError(pkgPath);
  }
  const pm = getPackageManager();
  pm.registerPackage(pkgPath);
  const loader = new NpmPackageLoader(pkgPath);
  const manifest = loader.getManifest();
  const entries = loader.getEntries() ?? [];
  const sds = loader.getEntriesByType("StructureDefinition") ?? [];
  const extensions = sds.filter((sd) => sd.type === "Extension");
  const profiles = sds.filter((sd) => sd.type !== "Extension");
  const name = manifest?.name ?? "unknown";
  const version = manifest?.version ?? "";
  if (options.json) {
    printJson({
      name,
      version,
      fhirVersions: manifest?.fhirVersions ?? [],
      totalResources: entries.length,
      profiles: profiles.length,
      extensions: extensions.length
    });
  } else {
    printSuccess("Package loaded");
    printInfo("Name:      ", name);
    printInfo("Version:   ", version);
    printInfo("FHIR:      ", (manifest?.fhirVersions ?? []).join(", "));
    printInfo("Profiles:  ", String(profiles.length));
    printInfo("Extensions:", String(extensions.length));
    printInfo("Total:     ", String(entries.length));
  }
  process.exitCode = ExitCode.SUCCESS;
}
async function runPackageList(options) {
  const pm = getPackageManager();
  const packages = pm.getPackages();
  if (options.json) {
    const result = packages.map((pkg) => {
      const loader = new NpmPackageLoader(pkg.path);
      const sds = loader.getEntriesByType("StructureDefinition") ?? [];
      return {
        name: pkg.name,
        version: pkg.version,
        profiles: sds.length,
        totalResources: pkg.resourceCount,
        ...options.verbose ? { urls: sds.map((sd) => sd.url).filter(Boolean) } : {}
      };
    });
    printJson({
      count: packages.length,
      packages: result
    });
  } else {
    printSuccess(`Loaded Packages: ${packages.length}`);
    if (packages.length === 0) {
      printInfo("", "No packages loaded. Use: fhir package load <path>");
    } else {
      printHeader("Packages");
      const lines = [];
      for (const pkg of packages) {
        lines.push(
          `${pkg.name.padEnd(30)} ${(pkg.version ?? "").padEnd(10)} ${pkg.resourceCount} resources`
        );
      }
      printList(lines);
      if (options.verbose) {
        for (const pkg of packages) {
          const loader = new NpmPackageLoader(pkg.path);
          const sds = loader.getEntriesByType("StructureDefinition") ?? [];
          if (sds.length > 0) {
            printHeader(`${pkg.name} ${pkg.version}`);
            printList(sds.map((sd) => sd.url ?? sd.filename));
          }
        }
      }
    }
  }
  process.exitCode = ExitCode.SUCCESS;
}
async function runPackageResolve(url, options) {
  const pm = getPackageManager();
  const result = pm.resolveCanonical(url);
  if (!result) {
    printError(`Not found: ${url}`);
    printInfo("", "No loaded package contains this canonical URL.");
    printInfo("", "Try: fhir package load <path>");
    process.exitCode = ExitCode.VALIDATION_FAILURE;
    return;
  }
  let resource = null;
  const pkg = pm.getPackages().find(
    (p) => p.name === result.packageName
  );
  if (pkg) {
    try {
      const filePath = join2(pkg.path, result.filename);
      const content = readFileSync2(filePath, "utf-8");
      resource = JSON.parse(content);
    } catch {
    }
  }
  const resourceType = result.resourceType ?? "";
  const kind = resource?.kind ?? "";
  const baseDefinition = resource?.baseDefinition ?? "";
  if (options.json) {
    printJson({
      url,
      package: result.packageName,
      version: result.packageVersion,
      resourceType,
      kind: kind || void 0,
      baseDefinition: baseDefinition || void 0,
      ...options.show && resource ? { resource } : {}
    });
  } else {
    printSuccess(`Resolved: ${url}`);
    printInfo("Package:  ", `${result.packageName} ${result.packageVersion}`);
    printInfo("Type:     ", resourceType);
    if (kind) printInfo("Kind:     ", kind);
    if (baseDefinition) printInfo("Base:     ", baseDefinition);
    if (options.show && resource) {
      printHeader("Resource");
      console.log(JSON.stringify(resource, null, 2));
    }
  }
  process.exitCode = ExitCode.SUCCESS;
}
function registerPackageCommand(program) {
  const pkg = program.command("package").description("Manage FHIR IG packages");
  pkg.command("load <path>").description("Load a FHIR IG package (.tgz or directory)").option("--json", "Output in JSON format").action(async (path, opts) => {
    try {
      await runPackageLoad(path, opts);
    } catch (err) {
      handleError(err);
    }
  });
  pkg.command("list").description("List loaded FHIR IG packages").option("--json", "Output in JSON format").option("--verbose", "Show profile URLs for each package").action(async (opts) => {
    try {
      await runPackageList(opts);
    } catch (err) {
      handleError(err);
    }
  });
  pkg.command("resolve <url>").description("Resolve a canonical URL to a StructureDefinition").option("--json", "Output in JSON format").option("--show", "Show the full StructureDefinition content").action(async (url, opts) => {
    try {
      await runPackageResolve(url, opts);
    } catch (err) {
      handleError(err);
    }
  });
}

// src/commands/compose.ts
init_loader();
init_errors();
async function runCompose(templatePath, options) {
  const resource = readFhirResource(templatePath);
  const resourceType = resource.resourceType;
  const id = resource.id ?? "";
  const indent = options.pretty !== false ? 2 : 0;
  const jsonOutput = JSON.stringify(resource, null, indent);
  if (options.output) {
    writeOutputFile(options.output, jsonOutput + "\n");
    printSuccess("Resource composed");
    printInfo("Type:  ", resourceType);
    if (id) printInfo("ID:    ", id);
    printInfo("Output:", options.output);
  } else {
    printSuccess("Resource composed");
    printInfo("Type:  ", resourceType);
    if (id) printInfo("ID:    ", id);
    console.log("");
    console.log(jsonOutput);
  }
  process.exitCode = ExitCode.SUCCESS;
  if (options.validate) {
    console.log("");
    await runValidate(templatePath, { json: false });
  }
}
function registerComposeCommand(program) {
  program.command("compose <template>").description("Compose a normalized FHIR R4 JSON resource from a template (YAML/JSON)").option("--validate", "Validate the composed resource").option("--output <file>", "Write output to file").option("--pretty", "Pretty-print JSON (default: true)").action(async (template, opts) => {
    try {
      await runCompose(template, opts);
    } catch (err) {
      handleError(err);
    }
  });
}

// src/commands/search.ts
init_loader();
import {
  parseSearchParameter,
  extractSearchValues,
  buildCapabilityFragment
} from "fhir-runtime";
init_errors();
async function runSearchExtract(resourceFile, searchParamFile, options) {
  const resource = readFhirResource(resourceFile);
  const spRaw = readFhirResource(searchParamFile);
  let searchParams = [];
  if (spRaw.resourceType === "Bundle") {
    const entries = spRaw.entry ?? [];
    for (const entry of entries) {
      if (entry.resource?.resourceType === "SearchParameter") {
        const parsed = parseSearchParameter(entry.resource);
        if (parsed.success) {
          searchParams.push(parsed.data);
        }
      }
    }
  } else if (spRaw.resourceType === "SearchParameter") {
    const parsed = parseSearchParameter(spRaw);
    if (parsed.success) {
      searchParams.push(parsed.data);
    } else {
      printError("Failed to parse SearchParameter");
      process.exitCode = ExitCode.VALIDATION_FAILURE;
      return;
    }
  } else {
    throw inputError(`Expected SearchParameter or Bundle, got: ${spRaw.resourceType}`);
  }
  if (options.param) {
    searchParams = searchParams.filter((sp) => sp.code === options.param);
  }
  const resourceType = resource.resourceType;
  const id = resource.id ?? "";
  const results = [];
  for (const sp of searchParams) {
    try {
      const values = extractSearchValues(resource, sp);
      results.push({ code: sp.code, type: sp.type, values });
    } catch {
      results.push({ code: sp.code, type: sp.type, values: [] });
    }
  }
  if (options.json) {
    printJson(results);
  } else {
    printSuccess(`Search Index Values for: ${resourceType}/${id}`);
    if (results.length === 0) {
      printInfo("", "No search values extracted");
    } else {
      printHeader("Values");
      printList(
        results.map((r) => {
          const valStr = r.values.length > 0 ? JSON.stringify(r.values) : "(none)";
          return `${r.code.padEnd(16)} (${r.type.padEnd(8)}) ${valStr}`;
        })
      );
    }
  }
  process.exitCode = ExitCode.SUCCESS;
}
async function runSearchValidate(spFile, options) {
  const spRaw = readFhirResource(spFile);
  if (spRaw.resourceType !== "SearchParameter") {
    throw inputError(`Expected SearchParameter, got: ${spRaw.resourceType}`);
  }
  const parsed = parseSearchParameter(spRaw);
  if (parsed.success) {
    const sp = parsed.data;
    if (options.json) {
      printJson({
        valid: true,
        code: sp.code,
        type: sp.type,
        base: sp.base,
        expression: sp.expression
      });
    } else {
      printSuccess("SearchParameter valid");
      printInfo("Code:  ", sp.code);
      printInfo("Type:  ", sp.type);
      printInfo("Base:  ", sp.base.join(", "));
      printInfo("Expr:  ", sp.expression);
    }
    process.exitCode = ExitCode.SUCCESS;
  } else {
    const issues = parsed.issues ?? [];
    if (options.json) {
      printJson({
        valid: false,
        issues: issues.map((i) => i.message)
      });
    } else {
      printError("SearchParameter invalid");
      if (issues.length > 0) {
        printHeader("Issues");
        printList(issues.map((i) => i.message));
      }
    }
    process.exitCode = ExitCode.VALIDATION_FAILURE;
  }
}
async function runSearchCapability(profileFiles, options) {
  if (profileFiles.length === 0) {
    throw inputError("At least one profile file is required");
  }
  const profiles = [];
  for (const file of profileFiles) {
    const resource = readFhirResource(file);
    if (resource.resourceType !== "StructureDefinition") {
      throw inputError(`Expected StructureDefinition, got: ${resource.resourceType} in ${file}`);
    }
    profiles.push(resource);
  }
  let searchParams = [];
  if (options.searchParams) {
    const spRaw = readFhirResource(options.searchParams);
    if (spRaw.resourceType === "Bundle") {
      const entries = spRaw.entry ?? [];
      for (const entry of entries) {
        if (entry.resource?.resourceType === "SearchParameter") {
          const parsed = parseSearchParameter(entry.resource);
          if (parsed.success) {
            searchParams.push(parsed.data);
          }
        }
      }
    } else if (spRaw.resourceType === "SearchParameter") {
      const parsed = parseSearchParameter(spRaw);
      if (parsed.success) {
        searchParams.push(parsed.data);
      }
    }
  }
  const mode = options.mode ?? "server";
  const fragment = buildCapabilityFragment(
    profiles,
    searchParams,
    mode
  );
  const indent = options.pretty !== false ? 2 : 0;
  const jsonOutput = JSON.stringify(fragment, null, indent);
  if (options.output) {
    const { writeOutputFile: writeOutputFile2 } = await Promise.resolve().then(() => (init_loader(), loader_exports));
    writeOutputFile2(options.output, jsonOutput + "\n");
    printSuccess(`CapabilityStatement fragment written to ${options.output}`);
  } else {
    console.log(jsonOutput);
  }
  process.exitCode = ExitCode.SUCCESS;
}
function registerSearchCommand(program) {
  const search = program.command("search").description("FHIR SearchParameter tools");
  search.command("extract <resource-file> <search-params-file>").description("Extract search index values from a FHIR resource").option("--param <code>", "Only extract the specified parameter code").option("--json", "Output in JSON format").action(async (resourceFile, spFile, opts) => {
    try {
      await runSearchExtract(resourceFile, spFile, opts);
    } catch (err) {
      handleError(err);
    }
  });
  search.command("validate <file>").description("Validate a SearchParameter definition").option("--json", "Output in JSON format").action(async (file, opts) => {
    try {
      await runSearchValidate(file, opts);
    } catch (err) {
      handleError(err);
    }
  });
  search.command("capability <profile-files...>").description("Generate a CapabilityStatement REST fragment from profiles").option("--search-params <file>", "SearchParameter Bundle to associate").option("--mode <mode>", "REST mode: server or client (default: server)").option("--output <file>", "Write output to file").option("--pretty", "Pretty-print JSON (default: true)").action(async (profileFiles, opts) => {
    try {
      await runSearchCapability(profileFiles, opts);
    } catch (err) {
      handleError(err);
    }
  });
}

// src/index.ts
function createProgram() {
  const program = new Command();
  program.name("fhir").description("FHIR Runtime CLI \u2014 parse, validate, inspect FHIR R4 resources").version("0.2.1");
  registerValidateCommand(program);
  registerFhirPathCommand(program);
  registerInspectCommand(program);
  registerBundleCommand(program);
  registerConvertCommand(program);
  registerProfileCommand(program);
  registerPackageCommand(program);
  registerComposeCommand(program);
  registerSearchCommand(program);
  return program;
}
async function run(argv) {
  const program = createProgram();
  await program.parseAsync(argv ?? process.argv);
}
export {
  createProgram,
  run
};
//# sourceMappingURL=index.mjs.map
