This document defines the first usable version of the library.
Parse Spanish Cadastre .CAT fixed-width files into typed JavaScript objects
without losing the raw source data.
This version should be useful for scripts, tests, and exploratory data work. It does not need full domain modeling, GeoJSON export, reprojection, or database integration yet.
- No coordinate reprojection.
- No GeoJSON export.
- No CSV writer.
- No high-level parcel/property graph.
- No automatic downloading or unzipping of CAT files.
- No guarantee that every CAT field has a final semantic TypeScript name.
CAT files are plain text files made of fixed-width records.
- Every record is expected to be 1000 characters long, excluding line endings.
- Record type is stored at positions 1-2.
- Field positions from the official spec are 1-indexed.
- Internal slices use
start = position - 1andend = start + length.
v0.0.1 should recognize:
01: header11: parcel/finca13: construction unit14: construction15: property/bien inmueble16: common element share17: crop90: trailer
Unknown record type handling can be added later. The current parser throws for unknown record types.
parseLine(line: string): ParsedRecord
parseText(text: string): ParsedRecord[]
parseFile(path: string): Promise<ParsedRecord[]>
parseStream(
stream: NodeJS.ReadableStream
): AsyncIterable<ParsedRecord>
validateLine(line: string): ValidationIssue[]
validateFile(records: ParsedRecord[]): ValidationIssue[]type RecordType = "01" | "11" | "13" | "14" | "15" | "16" | "17" | "90"
interface ParsedRecord {
type: RecordType
name: string
raw: string
lineNumber?: number
fields: Record<string, ParsedField>
}
interface ParsedField {
spec: FieldSpec
raw: string
value: string | number | null
}
interface ValidationIssue {
level: "warning" | "error"
code: string
message: string
lineNumber?: number
recordType?: string
fieldName?: string
}The parser should be schema-driven.
Record specs are explicit per record type. Shared-looking fields should still be encoded from the official table for that specific record unless we have tests proving a helper preserves the same documented position, length, and format.
interface FieldSpec {
name: string
position: number
length: number
format: "X" | "N"
description?: string
}
interface RecordSpec {
type: RecordType
name: string
length: 1000
officialName: string
fields: FieldSpec[]
}v0.0.1 only needs enough field specs to prove the parser shape:
- common
recordTypefield for all supported records; - key identity fields for records
01,11,15, and90; - raw fallback access for everything else.
Full field coverage can grow incrementally from the official spec.
v0.0.1 validation should check:
- line length is exactly 1000 when
strictLineLengthis true; - record type exists or is reported as unknown;
- file has at most one header record;
- file has at most one trailer record;
- header, if present, is first non-empty record;
- trailer, if present, is last non-empty record.
Trailer count validation can come later once the relevant fields are modeled.
Parsing should be tolerant by default:
- v0.0.1
parseLinethrows for unknown record types. - recoverable problems are exposed as
ValidationIssues. - hard failures should be reserved for invalid API inputs, unreadable files, or strict parsing modes added later.
Initial package exports:
export { parseLine, parseText, parseFile, parseStream }
export { validateLine, validateFile }
export { getRecordSpec, recordSpecs }
export type {
FieldSpec,
ParsedField,
ParsedRecord,
RecordSpec,
RecordType,
ValidationIssue,
}Parse options are not implemented yet. A later version should add:
interface ParseOptions {
trimText?: boolean
emptyTextAsNull?: boolean
parseNumbers?: boolean
zeroNumbersAsNull?: boolean
strictLineLength?: boolean
}Likely defaults:
{
trimText: true,
emptyTextAsNull: true,
parseNumbers: false,
zeroNumbersAsNull: false,
strictLineLength: true
}parseNumbers should default to false because many CAT fields are identifiers
that look numeric but should remain strings.
The CLI is not required for v0.0.1, but the API should make this easy later:
dotcat parse file.CAT --json
dotcat validate file.CAT