var S=Object.defineProperty;var A=(r)=>r;function I(r,o){this[r]=A.bind(null,o)}var O=(r,o)=>{for(var m in o)S(r,m,{get:o[m],enumerable:!0,configurable:!0,set:I.bind(o,m)})};var R=(r,o)=>()=>(r&&(o=r(r=0)),o);var g=`import {
  createImportPlan,
  createRecordBatch,
  defineDataExchangeTemplate,
  previewImport,
} from "@contractspec/lib.data-exchange-core";
import { defineSchemaModel, ScalarTypeEnum } from "@contractspec/lib.schema";

const AccountImportSchema = defineSchemaModel({
  name: "AccountImport",
  fields: {
    id: { type: ScalarTypeEnum.ID(), isOptional: false },
    status: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
    amount: { type: ScalarTypeEnum.Float_unsecure(), isOptional: false },
    active: { type: ScalarTypeEnum.Boolean(), isOptional: false },
    tags: { type: ScalarTypeEnum.JSON(), isOptional: true },
  },
});

const accountImportTemplate = defineDataExchangeTemplate({
  key: "accounts.import",
  version: "1.0.0",
  title: "Account import",
  columns: [
    {
      key: "id",
      label: "Account ID",
      targetField: "id",
      required: true,
      sourceAliases: ["Account Identifier", "External ID", "No compte"],
    },
    {
      key: "status",
      label: "Status",
      targetField: "status",
      required: true,
      sourceAliases: ["Statut", "State"],
      format: { kind: "text", trim: true, case: "lowercase" },
    },
    {
      key: "amount",
      label: "Amount",
      targetField: "amount",
      required: true,
      sourceAliases: ["Montant", "Balance"],
      format: { kind: "number", decimalSeparator: ",", thousandsSeparator: "." },
    },
    {
      key: "active",
      label: "Active",
      targetField: "active",
      sourceAliases: ["Actif", "Enabled"],
      format: { kind: "boolean", trueValues: ["yes", "oui"], falseValues: ["no", "non"] },
    },
    {
      key: "tags",
      label: "Tags",
      targetField: "tags",
      format: { kind: "split", delimiter: ";" },
    },
  ],
});

const sourceBatch = createRecordBatch([
  {
    "No compte": "acc-1",
    Statut: " Active ",
    Montant: "1.234,50",
    Actif: "oui",
    Tags: "vip; beta",
  },
]);

const preview = previewImport(
  createImportPlan({
    source: { kind: "memory", batch: sourceBatch, format: "csv" },
    target: { kind: "memory", format: "json" },
    schema: AccountImportSchema,
    sourceBatch,
    template: accountImportTemplate,
  }),
);

console.log(preview.plan.mappingSource); // "template"
console.log(preview.normalizedRecords[0]);`,h=`import { defineDataExchangeTemplate } from "@contractspec/lib.data-exchange-core";
import { dryRunImport, executeImport } from "@contractspec/lib.data-exchange-server";

const template = defineDataExchangeTemplate({
  key: "accounts.import",
  version: "1.0.0",
  columns: [
    { key: "id", label: "Account ID", targetField: "id", required: true, sourceAliases: ["Account Identifier"] },
    { key: "amount", label: "Amount", targetField: "amount", format: { kind: "currency", currencySymbol: "€", decimalSeparator: "," } },
  ],
});

const partnerSource = {
  kind: "file",
  path: "partner-accounts.csv",
  format: "csv",
  codecOptions: { csv: { delimiter: ";", skipRows: 1 } },
} as const;

const formatProfile = {
  columns: {
    amount: { kind: "currency", currencySymbol: "€", decimalSeparator: "," },
  },
} as const;

const preview = await dryRunImport({
  source: partnerSource,
  target: { kind: "memory", format: "json" },
  schema: AccountImportSchema,
  template,
  formatProfile,
});

const blockingIssues = preview.issues.filter((issue) => issue.severity === "error");

if (blockingIssues.length === 0) {
  await executeImport({
    source: partnerSource,
    target: { kind: "memory", format: "json" },
    schema: AccountImportSchema,
    template,
    formatProfile,
  });
}`,f=`"use client";

import { useDataExchangeController } from "@contractspec/lib.data-exchange-client";

export function ImportMappingReview({ preview }) {
  const controller = useDataExchangeController({ preview });
  const replacementSourceColumn = controller.model.ignoredSourceColumns[0];

  return (
    <section>
      {controller.model.templateRows.map((row) => (
        <button
          key={row.id}
          type="button"
          disabled={!replacementSourceColumn}
          onClick={() => {
            if (!replacementSourceColumn) return;
            controller.selectAlias(row.targetField, replacementSourceColumn);
          }}
        >
          {row.label}: {row.sourceField || "Unmatched"} -> {row.targetField}
          {row.required ? " required" : ""}
          {row.formatLabel ? \` (\${row.formatLabel})\` : ""}
        </button>
      ))}
      {controller.model.unmatchedRequiredRows.length > 0 ? (
        <p>Resolve required columns before import.</p>
      ) : null}
    </section>
  );
}`,b=`You are adding an import flow to a ContractSpec app.

Define a reusable data-exchange template for this canonical schema:
- target fields, required flags, and display labels
- known partner column aliases
- value formats for numbers, dates, booleans, JSON, split/join lists, currency, and percentages

Wire the template into core preview planning and server dry-run execution. Keep explicit mappings higher precedence than template resolution. Return the template, preview call, server dry-run call, and tests for alias matching plus localized formatting.`,y=`A partner sent a CSV/JSON/XML file that does not match our recommended import template.

Compare the incoming headers and value samples against this ContractSpec data-exchange template. Propose:
- source-to-target column matches with confidence
- missing required target fields
- ignored source columns
- format overrides for localized numbers, booleans, dates, JSON, split/join lists, currency, or percentages

Do not execute the import. Produce a dry-run plan and the user-facing review copy.`,v=`cd packages/libs/data-exchange-core && bun test && bun run typecheck && bun run lint:check
cd packages/libs/data-exchange-client && bun test && bun run typecheck && bun run lint:check
cd packages/libs/data-exchange-server && bun test && bun run typecheck && bun run lint:check`;import{CodeBlock as c}from"@contractspec/lib.design-system";import{HStack as k,VStack as a}from"@contractspec/lib.design-system/layout";import{List as s,ListItem as l}from"@contractspec/lib.design-system/list";import{Code as d,H1 as E,H2 as i,H3 as u,P as p,Text as n}from"@contractspec/lib.design-system/typography";import w from"@contractspec/lib.ui-link";import{ChevronRight as D}from"lucide-react";import{jsx as e,jsxs as t}from"react/jsx-runtime";var F=["Explicit mappings win first, so existing integrations can keep their current mapping arrays.","Template resolution checks exact headers, aliases, normalized labels, and SchemaModel fallback inference.","Format profiles can override formats by target field or template column key without changing the template.","Required template columns become visible preview issues when no source column can be matched."],q=["text trim and case normalization","localized numbers with decimal and thousands separators","custom true/false boolean labels","dates and datetimes with accepted input formats","JSON parsing, empty-as-null, and default values","split/join delimiters, currency symbols, and percentages"];function U(){return t(a,{className:"space-y-8",children:[t(a,{className:"space-y-3",children:[e(n,{className:"editorial-kicker",children:"Build"}),e(E,{className:"font-bold text-4xl",children:"Import flexible files with data-exchange templates"}),e(p,{className:"max-w-3xl text-lg text-muted-foreground leading-8",children:"Publish one recommended import shape, then let users import CSV/JSON/XML files with partner-specific headers, skipped rows, localized values, and alternate metadata layouts."})]}),t(a,{className:"card-subtle space-y-4 p-6",children:[e(i,{className:"font-bold text-2xl",children:"What you'll build"}),t(s,{className:"space-y-2 text-muted-foreground text-sm",children:[e(l,{children:e(n,{children:"A canonical template with target fields, aliases, and formats."})}),e(l,{children:e(n,{children:"A dry-run import that reports confidence, gaps, and ignored columns."})}),e(l,{children:e(n,{children:"A client review state where users remap, update formats, or accept inferred mappings."})})]})]}),t(a,{className:"space-y-4",children:[e(i,{className:"font-bold text-2xl",children:"1) Define the template"}),t(p,{className:"text-muted-foreground text-sm leading-7",children:["Use ",e(d,{children:"defineDataExchangeTemplate"})," for neutral import/export naming. ",e(d,{children:"defineImportTemplate"})," and"," ",e(d,{children:"defineExportTemplate"})," remain available aliases."]}),e(c,{language:"typescript",filename:"src/data-exchange/accounts-import.ts",code:g})]}),t(a,{className:"grid gap-4 md:grid-cols-2",children:[t(a,{className:"card-subtle space-y-3 p-6",children:[e(u,{className:"font-bold text-xl",children:"Mapping precedence"}),e(s,{className:"space-y-2 text-muted-foreground text-sm",children:F.map((r)=>e(l,{children:e(n,{children:r})},r))})]}),t(a,{className:"card-subtle space-y-3 p-6",children:[e(u,{className:"font-bold text-xl",children:"Supported value formats"}),e(s,{className:"space-y-2 text-muted-foreground text-sm",children:q.map((r)=>e(l,{children:e(n,{children:r})},r))})]})]}),t(a,{className:"space-y-4",children:[e(i,{className:"font-bold text-2xl",children:"2) Dry-run partner CSV, JSON, or XML files on the server"}),e(p,{className:"text-muted-foreground text-sm leading-7",children:"File, HTTP, and storage adapters accept codec options. CSV can set delimiters, quotes, skipped rows, header rows, or explicit columns. JSON can read records and metadata from custom keys. XML can use custom root, record, metadata, and attribute fields."}),e(c,{language:"typescript",filename:"src/server/import-accounts.ts",code:h})]}),t(a,{className:"space-y-4",children:[e(i,{className:"font-bold text-2xl",children:"3) Let users review the mapping"}),e(p,{className:"text-muted-foreground text-sm leading-7",children:"The shared controller exposes template rows, matched source columns, confidence, required status, formatting summaries, unmatched required rows, and ignored source columns. Actions let users remap columns, select aliases, update field formats, reset to the template, or accept inferred mappings."}),e(c,{language:"tsx",filename:"src/components/ImportMappingReview.tsx",code:f})]}),t(a,{className:"space-y-4",children:[e(i,{className:"font-bold text-2xl",children:"4) Verify the package stack"}),e(c,{language:"bash",filename:"verification",code:v})]}),t(a,{className:"grid gap-4 md:grid-cols-2",children:[t(a,{className:"card-subtle space-y-3 p-6",children:[e(u,{className:"font-bold text-xl",children:"Prompt: build a template"}),e(c,{language:"markdown",filename:"template-authoring.prompt.md",code:b})]}),t(a,{className:"card-subtle space-y-3 p-6",children:[e(u,{className:"font-bold text-xl",children:"Prompt: inspect a partner file"}),e(c,{language:"markdown",filename:"partner-import-review.prompt.md",code:y})]})]}),t(k,{className:"flex flex-wrap items-center gap-4 pt-4",children:[t(w,{href:"/llms/lib.data-exchange-core",className:"btn-primary",children:[e(n,{children:"Core package guide"}),e(D,{size:16})]}),e(w,{href:"/llms/lib.data-exchange-server",className:"btn-ghost",children:e(n,{children:"Server package guide"})})]})]})}export{U as GuideDataExchangeImportTemplatesPage};
