import { ImportPolicy, ImportPlan, NoydbFormat } from '@noy-db/hub/as'; export { ImportPolicy } from '@noy-db/hub/as'; import { Vault } from '@noy-db/hub'; /** * **@noy-db/as-json** — structured JSON plaintext export for noy-db. * * Decrypts ACL-scoped records from a vault and emits one structured * JSON document grouping records by collection. Sibling to the core * `exportJSON()` helper — same shape, but gated behind * `assertCanExport('plaintext')` and paired with browser-download + * Node file-write helpers. * * **Scope.** Multi-collection per call (unlike `as-csv` which is * single-collection). Whole-vault by default; pass `collections` to * restrict. * * See `docs/patterns/as-exports.md` for the three-tier egress model * (Tier 1 in-memory → Tier 2 browser download → Tier 3 disk write). * * @packageDocumentation */ interface AsJSONOptions { /** * Collection allowlist. When omitted, every collection the caller * can read is included. Collections not in the caller's ACL silently * drop out even when listed here — ACL-scoping runs at the * `exportStream` layer. */ readonly collections?: readonly string[]; /** * Pretty-print with indentation. Default `2` (2-space indent). Pass * `0` or `false` for compact single-line output. */ readonly pretty?: number | boolean; /** * Include envelope metadata (`_v`, `_ts`, `_by`) alongside each * record. Default `false` — stripped so the JSON matches the shape * of the raw records the consumer originally put. */ readonly includeMeta?: boolean; /** * Apply the hub's `applyListProjection` read-projection before * serialising records. `true` redacts only `classifiedFields` (mask / * omit / rider, per the field's preset). The object form additionally * redacts fields carrying a plain `fieldMeta` `sensitivity: 'pii' | * 'secret'` tag, per `sensitivity: 'omit' | 'mask'`. * * Caveat: `describe()` reflects the declarations of *this session's* * collection instance — redaction only takes effect when the * collection was opened (this call or earlier in the session) with * its `classifiedFields` / `fieldMeta` options. This is presentation- * layer redaction; it never affects what's on disk. Sealed handles * are unaffected either way — they always serialize as `'[sealed]'`, * so ciphertext never leaks regardless of this option. Rider companion * fields (e.g. `pan_last4`) remain visible as their own keys — they * are safe write-time projections. */ readonly redact?: boolean | { readonly sensitivity: 'omit' | 'mask'; }; } interface AsJSONDownloadOptions extends AsJSONOptions { /** Filename offered to the browser. Default `'vault-export.json'`. */ readonly filename?: string; } interface AsJSONWriteOptions extends AsJSONOptions { /** Required to write plaintext JSON to disk — Tier 3 risk gate. */ readonly acknowledgeRisks: true; } /** * Shape of the emitted document: one top-level key per collection, * each mapping to an array of record objects. */ type AsJSONDocument = Record[]>; /** * Browser download — wraps `toString()` in a Blob and triggers the * browser's save-as prompt. Requires a DOM — in Node, use `write()`. */ /** Options a JSON format instance carries. Read concerns live on `vault.export`. */ interface AsJSONFormatOptions { /** Indent width, or `false` for compact. Default 2. */ readonly pretty?: number | boolean; /** Keep `_noydb_*` metadata fields. Default false. */ readonly includeMeta?: boolean; } /** * The JSON format — the `as-*` port instance. * * Unlike CSV and XML, JSON carries collection names in the payload, so * `vault.import(asJson(), doc)` needs no `{ collection }`. */ declare function asJson(options?: AsJSONFormatOptions): NoydbFormat; /** * Serialise to a JSON string. * * Kept as a thin wrapper rather than removed, unlike as-csv/as-sql/as-xml: the * gate, the read and the redaction still moved to hub, and this is now three * lines over `vault.export`. Its sibling `toObject` is the reason — a document * is not bytes, so `NoydbFormat` cannot express it, and removing one * while keeping the other would be a worse API than keeping both. */ declare function toString(vault: Vault, options?: AsJSONOptions): Promise; /** * Serialise to the parsed `{ collection: records[] }` document. * * The one export shape the format port does not carry, because a format * produces bytes by definition. Round-tripping through `encode` keeps a single * implementation rather than a second walk of the chunks. */ declare function toObject(vault: Vault, options?: AsJSONOptions): Promise; /** Browser download. Hub gates, reads and redacts; this wraps the bytes. */ declare function download(vault: Vault, options?: AsJSONDownloadOptions): Promise; /** * Node file write. Not in hub because `hub-portable` forbids Node builtins * there. The gate, the read and the redaction all moved. */ declare function write(vault: Vault, path: string, options: AsJSONWriteOptions): Promise; interface AsJSONImportOptions { /** Restrict the diff + apply to a subset of collections. */ readonly collections?: readonly string[]; /** Field on each record that carries its id. Default `'id'`. */ readonly idKey?: string; /** Reconciliation policy. Default `'merge'`. */ readonly policy?: ImportPolicy; } /** * Output of `fromString` / `fromObject` — preview the changes a JSON * import would apply, then commit them with `apply()`. Two-step shape * keeps the diff cheap and lets consumers render review-and-confirm * UIs without a separate dry-run mode. */ type AsJSONImportPlan = ImportPlan; export { type AsJSONDocument, type AsJSONDownloadOptions, type AsJSONFormatOptions, type AsJSONImportOptions, type AsJSONImportPlan, type AsJSONOptions, type AsJSONWriteOptions, asJson, download, toObject, toString, write };