Initial Commit

This commit is contained in:
2026-05-27 23:29:53 +01:00
commit fbc70f96e6
10000 changed files with 1102152 additions and 0 deletions

View File

@@ -0,0 +1,59 @@
# `parsers/json` — JSON parsers
## Purpose
Parses JSON-array input documents into the same `Record<string, unknown>[]`
row shape produced by the CSV / XLSX parsers, so the canonical
`ImportService` can branch on `format` and call a uniform parse function.
The strict `parseJson` rejects non-array input with a deterministic error
string; the high-level `parseJsonWithHeaders` wraps `parseJson` to
produce the `{ headers, rows, totalRows }` shape consumed by the route
preview pipeline.
Scalar elements in the input array (numbers, strings, `null`) are
wrapped as `{ value: scalar }` rather than dropped, so the row count
agrees with the input array length and the resulting rows still satisfy
`Record<string, unknown>`.
## Features
- `parseJson` — strict array parsing; throws on non-array input.
- `parseJsonWithHeaders` — header-aware result shape; tolerant of
single-object inputs (wraps them in a one-element array).
- Header inference unions keys across heterogeneous rows.
## Usage: Basic Example
```ts
import { parseJson } from "@suaveplan/api-plugin-import";
const rows = parseJson('[{"a":1},{"a":2}]'); // [{ a: 1 }, { a: 2 }]
```
## Usage: Advanced Example
```ts
import { parseJsonWithHeaders } from "@suaveplan/api-plugin-import";
const { headers, rows, totalRows } = parseJsonWithHeaders(
'[{"a":1,"b":2},{"a":3,"c":4}]'
);
// headers: ["a","b","c"]
// rows: [{ a: 1, b: 2 }, { a: 3, c: 4 }]
// totalRows: 2
```
## API Reference
- `parseJson(data: string): Record<string, unknown>[]` — throws `Error("JSON data must be an array")` on non-array input.
- `parseJsonWithHeaders(content: string): CsvParseResult` — header-aware variant.
## Implementation Notes
- `parseJson` uses `JSON.parse` directly — invalid JSON syntax surfaces
as the native `SyntaxError` from the runtime, which is what the
service catches and re-throws as `IMPORT.PROCESSING_FAILED`.
- `parseJsonWithHeaders` wraps single-object inputs in a one-element
array so the route's `format: "json"` branch never has to special-case
shape — the field is always `rows[]`.
- Scalar wrapping uses the literal key `value`; consumers that need a
different key can map the result post-parse.