{"_id":"@amdevz/adfc","_rev":"3-245de8b10ed894d8f602edba2a0a4c89","name":"@amdevz/adfc","dist-tags":{"latest":"0.0.1","next":"0.0.1-rc.3"},"versions":{"0.0.1-rc.1":{"name":"@amdevz/adfc","version":"0.0.1-rc.1","keywords":["adf","atlassian","markdown","confluence","jira"],"license":"MIT","_id":"@amdevz/adfc@0.0.1-rc.1","maintainers":[{"name":"amdevz","email":"amir.mohamad.dev@gmail.com"}],"homepage":"https://github.com/amdevz/adfc","bugs":{"url":"https://github.com/amdevz/adfc/issues"},"bin":{"adfc":"bin/adfc.js"},"dist":{"shasum":"9d71a5b4b3748aef4a77dbe882a3d8f7768ebaa6","tarball":"https://registry.npmjs.org/@amdevz/adfc/-/adfc-0.0.1-rc.1.tgz","fileCount":5,"integrity":"sha512-F72TFxzGCJgZc4jdCUBRiIos4D0w0LEQihOb5ZqgmlkL84xR1NWawErO8w+VpDDWh0JZsi5aFeieFDnt8nEPSg==","signatures":[{"sig":"MEQCIEAC/ob1CsSkUgjAqkpYmdrpJtGBV1057rT0n9un4v/8AiBr+vyIKxDiYxhXrIJ383vh57DgXJZDEzei8Qto/c8GPA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":12409},"engines":{"node":">=18"},"gitHead":"5cf2ddadccd5e251de669ec9f83eeda751bd29e6","_npmUser":{"name":"amdevz","email":"amir.mohamad.dev@gmail.com"},"repository":{"url":"git+https://github.com/amdevz/adfc.git","type":"git"},"_npmVersion":"10.9.8","description":"Convert Markdown to Atlassian Document Format (ADF), with JSON Schema validation","directories":{},"_nodeVersion":"22.23.1","_hasShrinkwrap":false,"preferUnplugged":true,"optionalDependencies":{"@amdevz/adfc-linux-x64":"0.0.1-rc.1","@amdevz/adfc-win32-x64":"0.0.1-rc.1","@amdevz/adfc-darwin-x64":"0.0.1-rc.1","@amdevz/adfc-linux-arm64":"0.0.1-rc.1","@amdevz/adfc-win32-arm64":"0.0.1-rc.1","@amdevz/adfc-darwin-arm64":"0.0.1-rc.1"},"_npmOperationalInternal":{"tmp":"tmp/adfc_0.0.1-rc.1_1785836459204_0.4591662444359008","host":"s3://npm-registry-packages-npm-production"}},"0.0.1-rc.3":{"name":"@amdevz/adfc","version":"0.0.1-rc.3","keywords":["adf","atlassian","markdown","confluence","jira"],"license":"MIT","_id":"@amdevz/adfc@0.0.1-rc.3","maintainers":[{"name":"amdevz","email":"amir.mohamad.dev@gmail.com"}],"homepage":"https://github.com/amdevz/adfc","bugs":{"url":"https://github.com/amdevz/adfc/issues"},"bin":{"adfc":"bin/adfc.js"},"dist":{"shasum":"e898188d86af468e803c42ff01727b88537eb7dc","tarball":"https://registry.npmjs.org/@amdevz/adfc/-/adfc-0.0.1-rc.3.tgz","fileCount":5,"integrity":"sha512-oVvnQZ7fBGMNmMumnscwGoqcox72F4zpWo8Zijh2fnYavEyGnAWAQW0PHAj69vLCofAwCOmnuS3EeHOsh2YB+g==","signatures":[{"sig":"MEUCIQDcl7+IIdVbQgR0Pkqoj49TAUDBuzCkXOhg+wCtYBiRdAIgZu+WELm1GjTRa5EpxFrtQsCy8Ut6DYFnteq+vifkmSo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@amdevz%2fadfc@0.0.1-rc.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":12409},"engines":{"node":">=18"},"gitHead":"cc28f8f124c9e2d83285f9cc6397b54828828f32","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1b3b7cde-818e-467b-9ffe-90fd8bbb38d9"}},"repository":{"url":"git+https://github.com/amdevz/adfc.git","type":"git"},"_npmVersion":"11.16.0","description":"Convert Markdown to Atlassian Document Format (ADF), with JSON Schema validation","directories":{},"_nodeVersion":"24.18.0","_hasShrinkwrap":false,"readmeFilename":"README.md","preferUnplugged":true,"optionalDependencies":{"@amdevz/adfc-linux-x64":"0.0.1-rc.3","@amdevz/adfc-win32-x64":"0.0.1-rc.3","@amdevz/adfc-darwin-x64":"0.0.1-rc.3","@amdevz/adfc-linux-arm64":"0.0.1-rc.3","@amdevz/adfc-win32-arm64":"0.0.1-rc.3","@amdevz/adfc-darwin-arm64":"0.0.1-rc.3"},"_npmOperationalInternal":{"tmp":"tmp/adfc_0.0.1-rc.3_1785840540488_0.740108604882473","host":"s3://npm-registry-packages-npm-production"}},"0.0.1":{"name":"@amdevz/adfc","version":"0.0.1","description":"Convert Markdown to Atlassian Document Format (ADF), with JSON Schema validation","keywords":["adf","atlassian","markdown","confluence","jira"],"license":"MIT","repository":{"type":"git","url":"git+https://github.com/amdevz/adfc.git"},"homepage":"https://github.com/amdevz/adfc","bugs":{"url":"https://github.com/amdevz/adfc/issues"},"engines":{"node":">=18"},"preferUnplugged":true,"bin":{"adfc":"bin/adfc.js"},"optionalDependencies":{"@amdevz/adfc-linux-x64":"0.0.1","@amdevz/adfc-linux-arm64":"0.0.1","@amdevz/adfc-darwin-x64":"0.0.1","@amdevz/adfc-darwin-arm64":"0.0.1","@amdevz/adfc-win32-x64":"0.0.1","@amdevz/adfc-win32-arm64":"0.0.1"},"gitHead":"d0b32f2b158e88739132ea4d80d2c4ffc31ecf05","_id":"@amdevz/adfc@0.0.1","_nodeVersion":"24.18.0","_npmVersion":"11.16.0","dist":{"integrity":"sha512-tW47V4PHYlsISfrBq0HSIytAqJcoItm0TX8liZm8M81C81Rh9fQMfvHFaJavZ0X8JcdNqGMnQo59jeBQrP5/Uw==","shasum":"27869935a9ede4483a9f0b3980f9438db2834ae9","tarball":"https://registry.npmjs.org/@amdevz/adfc/-/adfc-0.0.1.tgz","fileCount":5,"unpackedSize":12374,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@amdevz%2fadfc@0.0.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCTuzpd5O4evuDR+6d+Fyk7NhoXBX2amcM4L5V5SXYvXwIhALT7nYRl048ox3PATGE3emLnJJKJWxB3D7j0e2CjPoFH"}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1b3b7cde-818e-467b-9ffe-90fd8bbb38d9"}},"directories":{},"maintainers":[{"name":"amdevz","email":"amir.mohamad.dev@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/adfc_0.0.1_1785849355286_0.5805989538979339"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-04T09:40:58.959Z","modified":"2026-08-04T13:15:55.881Z","0.0.1-rc.1":"2026-08-04T09:40:59.396Z","0.0.1-rc.3":"2026-08-04T10:49:00.642Z","0.0.1":"2026-08-04T13:15:55.460Z"},"bugs":{"url":"https://github.com/amdevz/adfc/issues"},"license":"MIT","homepage":"https://github.com/amdevz/adfc","keywords":["adf","atlassian","markdown","confluence","jira"],"repository":{"type":"git","url":"git+https://github.com/amdevz/adfc.git"},"description":"Convert Markdown to Atlassian Document Format (ADF), with JSON Schema validation","maintainers":[{"name":"amdevz","email":"amir.mohamad.dev@gmail.com"}],"readme":"# adfc\n\nConvert Markdown to [Atlassian Document Format\n(ADF)](https://developer.atlassian.com/cloud/jira/platform/apis/document/structure/) —\nthe JSON that Atlassian Cloud REST APIs accept for rich text, in Jira issues\nand comments, Confluence content, and anywhere else ADF appears.\n\nMarkdown in, schema-valid ADF out. No network access, no configuration.\n\n## Install\n\n**As a command:**\n\n```sh\nnpx @amdevz/adfc --version   # without installing\nnpm i -g @amdevz/adfc        # globally\nnpm i -D @amdevz/adfc        # as a project dev dependency\ncargo install adfc           # from crates.io\n```\n\nThe npm package is scoped, but the command it installs is `adfc`.\n\nThe npm packages ship a prebuilt binary for Linux, macOS and Windows on x64 and\narm64. Nothing is compiled or fetched during install, so `npm ci\n--ignore-scripts`, offline caches and mirrored registries all work. Linux is a\nstatic musl build and runs on Alpine as well as glibc.\n\n**As a library:**\n\n```sh\ncargo add adfc --no-default-features\n```\n\n`--no-default-features` drops the CLI's argument-parsing dependencies, which the\nlibrary does not use.\n\n## Usage\n\n```sh\nadfc ticket.md -o description.json\nadfc ticket.md > description.json     # stdout is the default\ncat ticket.md | adfc | jq .           # stdin too\n```\n\n| Flag | Effect |\n| --- | --- |\n| `-o, --output <FILE>` | Write here instead of stdout |\n| `--no-validate` | Skip schema validation |\n| `--schema <FILE>` | Validate against a different ADF schema revision |\n| `-h, --help` / `-V, --version` | |\n\nOutput is validated against the ADF schema by default. The schema is compiled\ninto the binary, so this needs no files on disk. On a violation, every error\ngoes to stderr and **nothing is written** — a malformed document fails here\nrather than at the Atlassian API, and never reaches a consumer.\n\nValidation is bounded at 128 levels of nesting. The ADF schema is a recursive\nunion of `anyOf` branches, so the cost of checking compounds with depth; past\nthis point a document is refused rather than checked, naming its own depth. The\nbound matches `serde_json`'s default recursion limit, so nothing that could be\nparsed back is turned away. `--no-validate` converts such a document anyway.\n\nExit codes: `0` success, including a downstream pipe closing early; `1` runtime\nfailure; `2` usage error.\n\n## Library\n\n```rust\nlet converted = adfc::markdown_to_adf(\"# Title\\n\\nSome **bold** text.\");\nadfc::validate(&converted)?;\n\n// The document is a serde_json::Value, ready to PUT as an issue description.\nprintln!(\"{}\", converted.doc());\n```\n\n`markdown_to_adf` cannot fail: constructs with no ADF equivalent degrade rather\nthan error. It returns a `Conversion` rather than the document alone, so\nanything the conversion could not honour travels with the document and\n`validate` can refuse it. `validate` checks a conversion against the embedded\nschema, `validate_against` checks it against one you supply, and\n`validate_document` checks an ADF document that came from somewhere else.\n\n## Supported Markdown\n\n| Markdown | ADF |\n| --- | --- |\n| `#`..`######` | `heading`, levels 1-6 |\n| Paragraphs | `paragraph` |\n| Bullet and ordered lists, nested | `bulletList` / `orderedList`, preserving the start number |\n| Fenced and indented code blocks | `codeBlock`, with the fence's language |\n| Blockquotes | `blockquote` |\n| GFM tables | `table` / `tableRow` / `tableHeader` / `tableCell` |\n| `---` | `rule` |\n| Hard breaks | `hardBreak` |\n| `- [ ]` / `- [x]` | `taskList` / `taskItem` |\n| `> [!NOTE]` alerts | `panel` |\n| `![alt](attachment:f.png)` | `mediaSingle` / `media` |\n| `**bold**` `*em*` `` `code` `` `~~strike~~` `[link](url)` | `strong` / `em` / `code` / `strike` / `link` |\n\nGitHub alerts map to panel types: `NOTE` → `note`, `TIP` → `success`,\n`IMPORTANT` → `info`, `WARNING` → `warning`, `CAUTION` → `error`. A blockquote\nwithout a marker stays a `blockquote`.\n\n## Raw ADF embeds\n\nMarkdown cannot spell every ADF node. Where it cannot, write the node itself.\n\nA fenced block with the `adf` info string carries one node, or an array of\nthem, and becomes those nodes in place:\n\n````markdown\n```adf\n{\"type\": \"status\", \"attrs\": {\"text\": \"Done\", \"color\": \"green\"}}\n```\n````\n\nA code span prefixed `adf:` carries exactly one inline node, so a badge can sit\ninside a sentence:\n\n```markdown\nThe build is `adf:{\"type\":\"status\",\"attrs\":{\"text\":\"Done\",\"color\":\"green\"}}`.\n```\n\nAn embed is placed where it was written and never relocated: Markdown-authored\ncontent hoists out of a container ADF forbids it in, because Markdown cannot\nexpress ADF's nesting rules, but an embed names its node explicitly and moving\nit would change what was asked for. A node its container forbids is refused\ninstead.\n\nAn embed that cannot be honoured — malformed JSON, an unknown node type, a node\nthat violates its own schema definition, or a block node in an inline span —\nfails the run, naming the source line and the field at fault. The text stays in\nthe output as visible code, so nothing the author wrote is lost, and\n`--no-validate` emits that form rather than failing.\n\n## Where ADF cannot follow\n\n- **Images** with an `attachment:` URL become media nodes, keeping the scheme as\n  a placeholder for an uploader to rewrite. Every other URL degrades to a link\n  labelled with its alt text, since ADF cannot reference an image this tool\n  cannot upload.\n- **Inline code** loses any surrounding emphasis; ADF forbids combining them.\n- **Raw HTML** is kept as plain text.\n- **Soft line breaks** become spaces, matching how Atlassian renders flowed text.\n\n## Contributing\n\nThe toolchain is pinned in `flake.lock`, so a clone plus\n[nix](https://nixos.org/download/) is the whole setup:\n\n```sh\ndirenv allow    # or: nix develop\njust check      # format, lint, both test suites\n```\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md).\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n","readmeFilename":"README.md"}