{
  "schema": "leumas.docs.page/1",
  "id": "adapter:domain/vcard",
  "slug": "adapters/domain/vcard",
  "kind": "capabilities",
  "bucket": "package",
  "title": "vcard (adapter system)",
  "name": "vcard",
  "eyebrow": "adapter system",
  "chip": null,
  "summary": "vCard / contact data-model pack (CRM primitive): build, parse, convert and validate electronic business cards. create(): a contact JSON (name, org, phones, emails, addresses, urls, birthday, note...",
  "keywords": [
    "vcard",
    "data-model",
    "fromjson",
    "tomecard",
    "tohcard",
    "vcard api",
    "h-card",
    "multi-card"
  ],
  "audience": "both",
  "funnel": {
    "product": null,
    "cta": null
  },
  "body": "# vcard (adapter system)\n\nThe **contact data-model** pack — a CRM primitive. It turns structured contact JSON into the\ninterchange formats real address books speak, and parses them back:\n\n- **vCard 3.0 / 4.0** (RFC 2426 / RFC 6350) — the `.vcf` electronic business card, with correct\n  CRLF line endings, 75-octet line folding, and value escaping (`\\` `,` `;` newline).\n- **MECARD** — the compact single-line `MECARD:...;;` string embedded inside contact QR codes.\n- **h-card** — microformats2 HTML for putting a machine-readable contact on a web page (SEO/parsers).\n\n`parse()` round-trips `create()`. **Pure JavaScript — Node built-ins only, zero npm deps.**\n\n## Tools (`adapters`)\n\n| tool | args | result |\n|------|------|--------|\n| `create` | `{ contact, version? }` | `{ version, vcard, mimeType, extension }` — one .vcf card |\n| `parse` | `{ vcard }` | `{ count, contacts[], contact }` — JSON from .vcf text |\n| `fromJson` | `{ contact }` | `{ contact }` — loose payload normalized to the canonical shape |\n| `toMeCard` | `{ contact }` | `{ mecard, length, note }` — compact QR payload string |\n| `toHCard` | `{ contact }` | `{ html, format, spec }` — h-card microformat HTML |\n| `validate` | `{ contact }` | `{ valid, errors[], warnings[], summary }` |\n| `batch` | `{ contacts[], version? }` | `{ count, skipped, errors[], vcard, ... }` — one multi-card book |\n| `fields` | — | `{ count, fields[] }` — every supported field, its type + aliases |\n\n`version` is `\"3.0\"` (default) or `\"4.0\"`.\n\n### Contact shape\n\nCanonical keys (see `fields()` for the full list + accepted aliases):\n`firstName`, `lastName`, `middleName`, `prefix`, `suffix`, `fullName`, `nickname`, `org`, `title`,\n`phones[]`, `emails[]`, `urls[]` (each `{ type, value }` or a bare string), `addresses[]`\n(`{ type, street, city, region, postalCode, country }`), `birthday`, `note`, `photo`, `geo{lat,lng}`,\n`categories[]`. Input is aliased generously — `name`, `company`, `mobile`, `e-mail`, `website`, `zip`,\netc. all fold into the canonical keys via `fromJson`.\n\n## Usage\n\n```js\nimport vcard from './index.js';\n\nconst { vcard: vcf } = vcard.adapters.create({\n  contact: {\n    firstName: 'Ada', lastName: 'Lovelace', org: 'Analytical Engines',\n    emails: ['ada@example.com'], phones: [{ type: 'cell', value: '+1-555-0100' }],\n    urls: ['https://example.com'],\n  },\n  version: '3.0',\n});\n\nconst { contact } = vcard.adapters.parse({ vcard: vcf }); // round-trips\nconst { mecard } = vcard.adapters.toMeCard({ contact });   // -> feed to a QR encoder\n```\n\n## DRY boundary\n\nThis pack is the **contact data model**; it does **not** rasterize anything. The sibling **`qr`**\npack *encodes* a payload string into a QR image — `toMeCard()` here produces exactly the string you\nwould hand to `qr.render` (`type: \"text\"`). Keep encoding/rendering in `qr`; keep the vCard/MECARD/\nh-card contact model here.\n",
  "source": {
    "path": "shared/engines/adapters/domain/vcard/README.md",
    "blobSha": "",
    "commit": "",
    "committedAt": "",
    "provenance": "no-git",
    "bytes": 3097,
    "hash": "f88f03beee9c8e4bc238a87f6ece6f031e8154f3"
  },
  "urls": {
    "html": "/p/adapters/domain/vcard",
    "json": "/docs/adapters/domain/vcard.json",
    "md": "/docs/adapters/domain/vcard.md"
  },
  "links": {
    "composes": [],
    "usedBy": [],
    "product": [],
    "howTo": [],
    "skills": []
  }
}
