{"_id":"@xarf/xarf","_rev":"4-886fc996832e71b6aeb72cf314e475f6","name":"@xarf/xarf","dist-tags":{"latest":"1.1.0"},"versions":{"1.0.0":{"name":"@xarf/xarf","version":"1.0.0","keywords":["xarf","abuse","reporting","parser","security","spam","phishing","ddos"],"author":{"name":"XARF Project"},"license":"MIT","_id":"@xarf/xarf@1.0.0","maintainers":[{"name":"xarf","email":"admin@abusix.com"}],"homepage":"https://xarf.org","bugs":{"url":"https://github.com/xarf/xarf-javascript/issues"},"dist":{"shasum":"ffec06fb8b82455b3eef16228157a490f7ed80d9","tarball":"https://registry.npmjs.org/@xarf/xarf/-/xarf-1.0.0.tgz","fileCount":120,"integrity":"sha512-L4u+3YB5QUikgziHJyJ4e9bZxzEFS7q/jqy5mSYZNxZgbm0B75nB2Dgwni5MXQF/9Df12i2N6ke/DzoyNZ2QJQ==","signatures":[{"sig":"MEUCIArPHfwCIl8GaOwS+DqU3GUOlsOSy9EHXtQrAmSUXLrwAiEA7tTjpqGZ2rr/SPinnLSJW4d4ZwvVnKBXQsIq9RmtrAA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":391955},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=16.0.0"},"gitHead":"648adba3cff9f39065ab4b5b252fe74cf562002c","scripts":{"lint":"eslint src tests --ext .ts","test":"jest","build":"tsc && npm run copy-schemas","jsdoc":"eslint src --ext .ts --no-eslintrc --plugin jsdoc --parser @typescript-eslint/parser --rule 'jsdoc/require-jsdoc: error'","format":"prettier --write \"src/**/*.ts\" \"tests/**/*.ts\"","prepare":"husky","lint:fix":"eslint src tests --ext .ts --fix","dead-code":"ts-prune --error","typecheck":"tsc --noEmit","complexity":"eslint src --ext .ts --no-eslintrc --plugin complexity --rule 'complexity: [error, 10]'","test:watch":"jest --watch","jsdoc:check":"eslint src --ext .ts","lint:strict":"eslint src tests --ext .ts --max-warnings=0","postinstall":"npm run fetch-schemas","copy-schemas":"cp -r schemas dist/","format:check":"prettier --check \"src/**/*.ts\" \"tests/**/*.ts\"","fetch-schemas":"node scripts/fetch-schemas.js","test:coverage":"jest --coverage","prepublishOnly":"npm run build && npm test","dead-code:check":"ts-prune","complexity:check":"eslint src --ext .ts --no-eslintrc --plugin complexity --rule 'complexity: [warn, 10]'","check-schema-updates":"node scripts/check-schema-updates.js"},"_npmUser":{"name":"xarf","email":"admin@abusix.com"},"xarfSpec":{"version":"v4.2.0","repository":"https://github.com/xarf/xarf-spec"},"deprecated":"Broken release due to missing postinstall script. Use v1.0.1","repository":{"url":"git+https://github.com/xarf/xarf-javascript.git","type":"git"},"_npmVersion":"10.8.2","description":"XARF v4 (eXtended Abuse Reporting Format) parser and generator for JavaScript/TypeScript - supports XARF spec v4.2.0 with backward compatibility for v3","directories":{},"lint-staged":{"*.ts":["eslint --fix","prettier --write"],"*.{json,md,yml,yaml}":["prettier --write"]},"_nodeVersion":"20.19.6","dependencies":{"ajv":"^8.17.1","ajv-formats":"^3.0.1"},"_hasShrinkwrap":false,"devDependencies":{"tar":"^7.5.2","jest":"^29.7.0","husky":"^9.1.7","eslint":"^8.56.0","ts-jest":"^29.4.6","prettier":"^3.7.4","ts-prune":"^0.10.3","typescript":"^5.3.3","@types/jest":"^29.5.11","@types/node":"^25.0.3","lint-staged":"^16.2.7","eslint-plugin-jsdoc":"^61.5.0","eslint-plugin-sonarjs":"^3.0.5","eslint-config-prettier":"^10.1.8","eslint-plugin-prettier":"^5.1.2","eslint-plugin-complexity":"^1.0.2","@typescript-eslint/parser":"^8.57.0","@typescript-eslint/eslint-plugin":"^8.57.0"},"_npmOperationalInternal":{"tmp":"tmp/xarf_1.0.0_1774017870397_0.060141320093961115","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@xarf/xarf","version":"1.0.1","keywords":["xarf","abuse","reporting","parser","security","spam","phishing","ddos"],"author":{"name":"XARF Project"},"license":"MIT","_id":"@xarf/xarf@1.0.1","maintainers":[{"name":"xarf","email":"admin@abusix.com"}],"homepage":"https://xarf.org","bugs":{"url":"https://github.com/xarf/xarf-javascript/issues"},"dist":{"shasum":"f75ab6fe98590a0d652064f0f70691d73b6632c9","tarball":"https://registry.npmjs.org/@xarf/xarf/-/xarf-1.0.1.tgz","fileCount":122,"integrity":"sha512-iOy9HyloXLb0NCMkLg4OpTygHmiKFovKUtP+7cp0vew7OKyRa/Q52+DU28vnffVGuk1u28x2a3BAMrKKRwOWzw==","signatures":[{"sig":"MEUCIF37tsJ9Vl6J/TiAkR2ojYLV0O19JGcNnOKd7FbA0zXyAiEAwcBvHFZUsx2l995abR9srREexILn7BtEL1oW6eJnUgQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":406518},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=16.0.0"},"gitHead":"25f39c38161b7147ac5cb88f7e19b9b4eab8c97a","scripts":{"lint":"eslint src tests --ext .ts","test":"jest","build":"tsc && npm run copy-schemas","jsdoc":"eslint src --ext .ts --no-eslintrc --plugin jsdoc --parser @typescript-eslint/parser --rule 'jsdoc/require-jsdoc: error'","format":"prettier --write \"src/**/*.ts\" \"tests/**/*.ts\"","prepare":"husky","lint:fix":"eslint src tests --ext .ts --fix","dead-code":"ts-prune --error","typecheck":"tsc --noEmit","complexity":"eslint src --ext .ts --no-eslintrc --plugin complexity --rule 'complexity: [error, 10]'","test:watch":"jest --watch","jsdoc:check":"eslint src --ext .ts","lint:strict":"eslint src tests --ext .ts --max-warnings=0","postinstall":"npm run fetch-schemas","copy-schemas":"cp -r schemas dist/","format:check":"prettier --check \"src/**/*.ts\" \"tests/**/*.ts\"","fetch-schemas":"node scripts/fetch-schemas.js","test:coverage":"jest --coverage","prepublishOnly":"npm run build && npm test","dead-code:check":"ts-prune","complexity:check":"eslint src --ext .ts --no-eslintrc --plugin complexity --rule 'complexity: [warn, 10]'","check-schema-updates":"node scripts/check-schema-updates.js"},"_npmUser":{"name":"xarf","email":"admin@abusix.com"},"xarfSpec":{"version":"v4.2.0","repository":"https://github.com/xarf/xarf-spec"},"repository":{"url":"git+https://github.com/xarf/xarf-javascript.git","type":"git"},"_npmVersion":"10.8.2","description":"XARF v4 (eXtended Abuse Reporting Format) parser and generator for JavaScript/TypeScript - supports XARF spec v4.2.0 with backward compatibility for v3","directories":{},"lint-staged":{"*.ts":["eslint --fix","prettier --write"],"*.{json,md,yml,yaml}":["prettier --write"]},"_nodeVersion":"20.19.6","dependencies":{"ajv":"^8.17.1","tar":"^7.5.2","ajv-formats":"^3.0.1"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","husky":"^9.1.7","eslint":"^8.56.0","ts-jest":"^29.4.6","prettier":"^3.7.4","ts-prune":"^0.10.3","typescript":"^5.3.3","@types/jest":"^29.5.11","@types/node":"^25.0.3","lint-staged":"^16.2.7","eslint-plugin-jsdoc":"^61.5.0","eslint-plugin-sonarjs":"^3.0.5","eslint-config-prettier":"^10.1.8","eslint-plugin-prettier":"^5.1.2","eslint-plugin-complexity":"^1.0.2","@typescript-eslint/parser":"^8.57.0","@typescript-eslint/eslint-plugin":"^8.57.0"},"_npmOperationalInternal":{"tmp":"tmp/xarf_1.0.1_1774025014291_0.8688994462931858","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@xarf/xarf","version":"1.1.0","description":"XARF v4 (eXtended Abuse Reporting Format) parser and generator for JavaScript/TypeScript - supports XARF spec v4.2.0 with backward compatibility for v3","xarfSpec":{"version":"v4.2.0","repository":"https://github.com/xarf/xarf-spec"},"main":"dist/index.js","module":"dist/index.mjs","types":"dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"require":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"./package.json":"./package.json"},"scripts":{"build":"tsup","fetch-schemas":"node scripts/fetch-schemas.js","generate-schemas":"node scripts/generate-schemas.js","sync-schemas":"npm run fetch-schemas && npm run generate-schemas","check-schema-updates":"node scripts/check-schema-updates.js","test":"jest","test:watch":"jest --watch","test:coverage":"jest --coverage","lint":"eslint src tests --ext .ts","lint:strict":"eslint src tests --ext .ts --max-warnings=0","lint:fix":"eslint src tests --ext .ts --fix","format":"prettier --write \"src/**/*.ts\" \"tests/**/*.ts\"","format:check":"prettier --check \"src/**/*.ts\" \"tests/**/*.ts\"","dead-code":"ts-prune --error","dead-code:check":"ts-prune","prepublishOnly":"npm run build && npm test","typecheck":"tsc --noEmit","prepare":"husky || true"},"keywords":["xarf","abuse","reporting","parser","security","spam","phishing","ddos"],"author":{"name":"XARF Project"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/xarf/xarf-javascript.git"},"bugs":{"url":"https://github.com/xarf/xarf-javascript/issues"},"homepage":"https://xarf.org","lint-staged":{"*.ts":["eslint --fix","prettier --write"],"*.{json,md,yml,yaml}":["prettier --write"]},"devDependencies":{"@types/jest":"^29.5.11","@types/node":"^18.19.0","@typescript-eslint/eslint-plugin":"^8.57.0","@typescript-eslint/parser":"^8.57.0","eslint":"^8.56.0","eslint-config-prettier":"^10.1.8","eslint-plugin-complexity":"^1.0.2","eslint-plugin-jsdoc":"^61.5.0","eslint-plugin-prettier":"^5.1.2","eslint-plugin-sonarjs":"^3.0.5","husky":"^9.1.7","jest":"^29.7.0","lint-staged":"^16.2.7","prettier":"^3.7.4","tar":"^7.5.2","ts-jest":"^29.4.6","ts-prune":"^0.10.3","tsup":"^8.5.1","typescript":"^5.3.3"},"engines":{"node":">=18.0.0"},"dependencies":{"ajv":"^8.20.0","ajv-formats":"^3.0.1"},"overrides":{"fast-uri":"^3.1.2"},"_id":"@xarf/xarf@1.1.0","gitHead":"0774cd7c3cc2bf9cab629ab49de803e284288b4d","_nodeVersion":"20.20.2","_npmVersion":"10.8.2","dist":{"integrity":"sha512-YNFuvcx1GFgeWNfoS0M6IhEzS1NTYLz3A3ZTjpHYhg0OGo01dZL+w3D2AKHqCP9E3yBFmlX0G5SGzvlrVCKglQ==","shasum":"f1c728c2aa3d5d3571a2fdb54170454fe3401746","tarball":"https://registry.npmjs.org/@xarf/xarf/-/xarf-1.1.0.tgz","fileCount":10,"unpackedSize":968112,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@xarf%2fxarf@1.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCT+pg8gIbNAPWLbP1SLZbZfc/VvDAqoESwsO1yHCGrvQIgHEphFWe/A2PHklw+TW88FVA4m3n1g61SkonkQX3AMfQ="}]},"_npmUser":{"name":"xarf","email":"admin@abusix.com"},"directories":{},"maintainers":[{"name":"xarf","email":"admin@abusix.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/xarf_1.1.0_1782223674901_0.028289772172072958"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-20T14:44:30.295Z","modified":"2026-06-23T14:07:55.383Z","1.0.0":"2026-03-20T14:44:30.608Z","1.0.1":"2026-03-20T16:43:34.463Z","1.1.0":"2026-06-23T14:07:55.114Z"},"bugs":{"url":"https://github.com/xarf/xarf-javascript/issues"},"author":{"name":"XARF Project"},"license":"MIT","homepage":"https://xarf.org","keywords":["xarf","abuse","reporting","parser","security","spam","phishing","ddos"],"repository":{"type":"git","url":"git+https://github.com/xarf/xarf-javascript.git"},"description":"XARF v4 (eXtended Abuse Reporting Format) parser and generator for JavaScript/TypeScript - supports XARF spec v4.2.0 with backward compatibility for v3","maintainers":[{"name":"xarf","email":"admin@abusix.com"}],"readme":"# XARF JavaScript/TypeScript Library\n\n![XARF Spec](https://img.shields.io/badge/XARF%20Spec-v4.2.0-blue)\n[![npm version](https://badge.fury.io/js/@xarf%2Fxarf.svg)](https://www.npmjs.com/package/@xarf/xarf)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![CI](https://github.com/xarf/xarf-javascript/actions/workflows/ci.yml/badge.svg)](https://github.com/xarf/xarf-javascript/actions/workflows/ci.yml)\n\nA JavaScript/TypeScript library for parsing, validating, and generating [XARF v4](https://xarf.org) (eXtended Abuse Reporting Format) reports.\n\n## Features\n\n- **Parse** XARF reports from JSON with validation and typed results\n- **Generate** XARF-compliant reports with auto-generated metadata (UUIDs, timestamps)\n- **Validate** reports against the official JSON schemas with detailed errors and warnings\n- **Full TypeScript support** with discriminated union types for all 7 categories\n- **v3 backward compatibility** with automatic detection and conversion\n- **Schema-driven** — validation rules derived from the official [xarf-spec](https://github.com/xarf/xarf-spec) schemas, not hardcoded\n\n## Installation\n\n```bash\nnpm install @xarf/xarf\n```\n\n## Quick Start\n\n### Parsing a Report\n\n```typescript\nimport { parse } from '@xarf/xarf';\n\n// Missing first_seen and source_port produce validation errors.\nconst { report, errors, warnings } = parse({\n  xarf_version: '4.2.0',\n  report_id: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',\n  timestamp: '2024-01-15T10:30:00Z',\n  // first_seen: '2024-01-15T10:00:00Z',\n  reporter: {\n    org: 'Security Team',\n    contact: 'abuse@example.com',\n    domain: 'example.com',\n  },\n  sender: {\n    org: 'Security Team',\n    contact: 'abuse@example.com',\n    domain: 'example.com',\n  },\n  source_identifier: '192.0.2.100',\n  // source_port: 1234,\n  category: 'connection',\n  type: 'ddos',\n  evidence_source: 'honeypot',\n  destination_ip: '203.0.113.10',\n  protocol: 'tcp',\n});\n\nif (errors.length === 0) {\n  console.log(report.category); // 'connection'\n} else {\n  console.log('Validation errors:', errors);\n}\n```\n\n### Creating a Report\n\n```typescript\nimport { createReport, createEvidence } from '@xarf/xarf';\n\n// Returns { content_type, payload (base64), hash, size, description }\nconst evidence = createEvidence('message/rfc822', rawEmailContent, {\n  description: 'Original spam email',\n  hashAlgorithm: 'sha256',\n});\n\n// xarf_version, report_id, and timestamp are auto-generated\nconst { report, errors, warnings } = createReport({\n  category: 'messaging',\n  type: 'spam',\n  source_identifier: '192.0.2.100',\n  reporter: {\n    org: 'Example Security',\n    contact: 'abuse@example.com',\n    domain: 'example.com',\n  },\n  sender: {\n    org: 'Example Security',\n    contact: 'abuse@example.com',\n    domain: 'example.com',\n  },\n  evidence_source: 'spamtrap',\n  description: 'Spam email detected from source',\n  protocol: 'smtp',\n  smtp_from: 'spammer@evil.example.com',\n  evidence: [evidence],\n});\n\nconsole.log(JSON.stringify(report, null, 2));\n```\n\n## API Reference\n\n### `parse(jsonData, options?)`\n\nParse and validate a XARF report from JSON. Supports both v4 and v3 (legacy) formats — v3 reports are automatically converted to v4 with deprecation warnings.\n\n```typescript\nimport { parse } from '@xarf/xarf';\n\nconst { report, errors, warnings, info } = parse(jsonData, options?);\n```\n\n**Parameters:**\n\n- `jsonData: string | Record<string, unknown>` — JSON string or object containing a XARF report\n- `options.strict?: boolean` — Treat warnings (e.g. unknown fields) and `x-recommended` fields as errors (default: `false`)\n- `options.showMissingOptional?: boolean` — Include info about missing optional fields (default: `false`)\n\n> `parse()` does not throw on validation failures — inspect the returned `errors` array. It only throws `XARFParseError` when `jsonData` is a malformed JSON string.\n\n**Returns `ParseResult`:**\n\n- `report: XARFReport` — The parsed report, typed by category\n- `errors: string[]` — Validation errors (empty if valid)\n- `warnings: string[]` — Validation warnings\n- `info?: ValidationInfo[]` — Missing optional field info (only when `showMissingOptional` is `true`)\n\n### `createReport(input, options?)`\n\nCreate a validated XARF report with auto-generated metadata. Automatically fills `xarf_version`, `report_id` (UUID), and `timestamp` (ISO 8601) if not provided.\n\n```typescript\nimport { createReport } from '@xarf/xarf';\n\nconst { report, errors, warnings } = createReport(input, options?);\n```\n\n**Parameters:**\n\n- `input: ReportInput` — Report data. A discriminated union on `category` that narrows type-safe fields per category (e.g., `MessagingReportInput`, `ConnectionReportInput`, etc.)\n- `options.strict?: boolean` — Treat warnings and `x-recommended` fields as errors (default: `false`)\n- `options.showMissingOptional?: boolean` — Include info about missing optional fields (default: `false`)\n\n> Like `parse()`, `createReport()` does not throw on validation failures — the report is always returned alongside any `errors`.\n\n**Returns `CreateReportResult`:**\n\n- `report: XARFReport` — The generated report\n- `errors: ValidationError[]` — Structured validation errors (`{ field, message, value? }`)\n- `warnings: ValidationWarning[]` — Structured validation warnings (`{ field, message, value? }`)\n- `info?: ValidationInfo[]` — Missing optional field info (only when `showMissingOptional` is `true`)\n\n### `createEvidence(contentType, payload, options?)`\n\nCreate an evidence object with automatic base64 encoding, hashing, and size calculation.\n\n```typescript\nimport { createEvidence } from '@xarf/xarf';\n\nconst evidence = createEvidence(contentType, payload, options?);\n```\n\n**Parameters:**\n\n- `contentType: string` — MIME type of the evidence (e.g., `'message/rfc822'`)\n- `payload: string | Buffer` — The evidence data\n- `options.description?: string` — Human-readable description\n- `options.hashAlgorithm?: 'sha256' | 'sha512' | 'sha1' | 'md5'` — Hash algorithm (default: `'sha256'`)\n\n**Returns `XARFEvidence`** with computed `hash`, `size`, and base64-encoded `payload`.\n\n### `schemaRegistry`\n\nAccess schema-derived validation rules and metadata programmatically.\n\n```typescript\nimport { schemaRegistry } from '@xarf/xarf';\n\n// Get all valid categories\nschemaRegistry.getCategories();\n// Set { 'messaging', 'connection', 'content', 'infrastructure', 'copyright', 'vulnerability', 'reputation' }\n\n// Get valid types for a category\nschemaRegistry.getTypesForCategory('connection');\n// Set { 'ddos', 'port_scan', 'login_attack', ... }\n\n// Check if a category/type combination is valid\nschemaRegistry.isValidType('connection', 'ddos'); // true\n\n// Get field metadata including descriptions\nschemaRegistry.getFieldMetadata('confidence');\n// { description: '...', required: false, recommended: true, ... }\n```\n\n### Validation Details\n\nBoth `parse()` and `createReport()` run validation internally. Additional behaviors:\n\n- **Unknown fields** trigger warnings (or errors in strict mode)\n- **Missing optional fields** can be discovered with `showMissingOptional: true`:\n\n```typescript\nconst { info } = parse(report, { showMissingOptional: true });\n\nif (info) {\n  info.forEach(({ field, message }) => {\n    console.log(`${field}: ${message}`);\n    // e.g., \"description: OPTIONAL - Human-readable description of the abuse\"\n    // e.g., \"confidence: RECOMMENDED - Confidence score between 0.0 and 1.0\"\n  });\n}\n```\n\n## v3 Backward Compatibility\n\nThe library automatically detects XARF v3 reports (by the `Version` field) and converts them to v4 during parsing. Converted reports include `legacy_version: '3'` and deprecation warnings.\n\n```typescript\nimport { parse } from '@xarf/xarf';\n\nconst { report, warnings } = parse(v3Report);\n\nconsole.log(report.xarf_version); // '4.2.0'\nconsole.log(report.category); // mapped category (e.g., 'messaging')\nconsole.log(report.legacy_version); // '3'\n// warnings includes deprecation notice + conversion details\n```\n\nYou can also use the low-level utilities directly:\n\n```typescript\nimport { isXARFv3, convertV3toV4, getV3DeprecationWarning } from '@xarf/xarf';\n\nif (isXARFv3(jsonData)) {\n  const warnings: string[] = [];\n  const v4Report = convertV3toV4(v3Report, warnings);\n  console.log(getV3DeprecationWarning());\n}\n```\n\nUnknown v3 report types cause a parse error listing the supported types. See [MIGRATION_V3_TO_V4.md](docs/MIGRATION_V3_TO_V4.md) for the full type mapping and migration strategies.\n\n## Schema Management\n\nThis library validates against the official [xarf-spec](https://github.com/xarf/xarf-spec) JSON schemas. The schemas are **bundled into the package** at build time, so installation requires no network access and the library works in any environment (Node, bundlers, serverless, edge) with zero filesystem dependency. The bundled spec version is exposed as `BUNDLED_SPEC_VERSION`.\n\nThe schema version is configured in `package.json`:\n\n```json\n\"xarfSpec\": {\n  \"version\": \"v4.2.0\"\n}\n```\n\nFor **maintainers**, updating to a newer spec version is a two-step, network-only-at-build-time process:\n\n```bash\n# Check if a newer version of xarf-spec is available\nnpm run check-schema-updates\n\n# Bump \"xarfSpec.version\" in package.json, then refresh the bundled schemas:\nnpm run sync-schemas   # fetch-schemas + generate-schemas (regenerates src/schemas.generated.ts)\n```\n\nConsumers never run these scripts — they receive the pre-bundled schemas with the published package.\n\n## Development\n\n```bash\nnpm test                  # Run tests\nnpm run test:coverage     # Run tests with coverage\nnpm run build             # Build TypeScript to JavaScript\nnpm run typecheck         # Type-check without emitting\nnpm run lint              # Run ESLint\nnpm run format:check      # Check Prettier formatting\n```\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for development guidelines.\n\n## Links\n\n- [XARF Specification](https://xarf.org)\n- [GitHub Repository](https://github.com/xarf/xarf-javascript)\n- [npm Package](https://www.npmjs.com/package/@xarf/xarf)\n- [Issue Tracker](https://github.com/xarf/xarf-javascript/issues)\n- [Migration Guide (v3 → v4)](docs/MIGRATION_V3_TO_V4.md)\n- [License (MIT)](LICENSE)\n","readmeFilename":"README.md"}