diff --git a/src/csv-loader/loader.ts b/src/csv-loader/loader.ts index 9dfa32b..a41074e 100644 --- a/src/csv-loader/loader.ts +++ b/src/csv-loader/loader.ts @@ -1,5 +1,5 @@ import { parse } from 'csv-parse/sync'; -import { parseSchema, createValidator, parseValue } from '../index.js'; +import { parseSchema, createValidator, parseValue, schemaToTypeString } from '../index.js'; import type { Schema, ReferenceSchema } from '../types.js'; import * as fs from 'fs'; import * as path from 'path'; @@ -403,7 +403,7 @@ function parseReferenceValue( } /** - * Parser for reference values (extracts IDs from value string) + * Generate TypeScript interface for the CSV data */ class ReferenceValueParser { private input: string; @@ -490,54 +490,6 @@ class ReferenceValueParser { } } -/** - * Convert a schema to TypeScript type string - */ -export function schemaToTypeString(schema: Schema, resourceNames?: Map): string { - switch (schema.type) { - case 'string': - return 'string'; - case 'number': - case 'int': - case 'float': - return 'number'; - case 'boolean': - return 'boolean'; - case 'stringLiteral': - return `"${schema.value}"`; - case 'union': - return schema.members.map(m => schemaToTypeString(m, resourceNames)).join(' | '); - case 'reference': { - const typeName = resourceNames?.get(schema.tableName) || - schema.tableName.charAt(0).toUpperCase() + schema.tableName.slice(1); - const baseType = schema.isArray ? `${typeName}[]` : typeName; - return schema.isOptional ? `${baseType} | null` : baseType; - } - case 'array': - if (schema.element.type === 'tuple') { - const tupleElements = schema.element.elements.map((el) => { - const typeStr = schemaToTypeString(el.schema, resourceNames); - return el.name ? `${el.name}: ${typeStr}` : typeStr; - }); - return `[${tupleElements.join(', ')}][]`; - } - // Wrap union types in parentheses to maintain correct precedence - const elementType = schemaToTypeString(schema.element, resourceNames); - if (schema.element.type === 'union') { - return `(${elementType})[]`; - } - return `${elementType}[]`; - case 'tuple': - const tupleElements = schema.elements.map((el) => { - const typeStr = schemaToTypeString(el.schema, resourceNames); - return el.name ? `${el.name}: ${typeStr}` : typeStr; - }); - return `[${tupleElements.join(', ')}]`; - default: - return 'unknown'; - } -} - /** * Generate TypeScript interface for the CSV data */ diff --git a/src/index.ts b/src/index.ts index 78ff52b..616a37f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,5 @@ import { parseSchema } from './parser'; -import { parseValue, createValidator } from './validator'; +import { parseValue, createValidator, schemaToTypeString } from './validator'; import type { Schema, PrimitiveSchema, TupleSchema, ArraySchema, ReferenceSchema, StringLiteralSchema, UnionSchema, ParsedSchema } from './types'; import { ParseError } from './parser'; @@ -14,6 +14,5 @@ export function defineSchema(schemaString: string): ParsedSchema { }; } -export { parseSchema, parseValue, createValidator, ParseError }; -export { schemaToTypeString } from './csv-loader/loader.js'; +export { parseSchema, parseValue, createValidator, ParseError, schemaToTypeString }; export type { Schema, PrimitiveSchema, TupleSchema, ArraySchema, ReferenceSchema, StringLiteralSchema, UnionSchema, ParsedSchema }; diff --git a/src/validator.ts b/src/validator.ts index 1380f60..6775d09 100644 --- a/src/validator.ts +++ b/src/validator.ts @@ -393,6 +393,50 @@ export function parseValue(schema: Schema, valueString: string): unknown { return value; } +export function schemaToTypeString(schema: Schema, resourceNames?: Map): string { + switch (schema.type) { + case 'string': + return 'string'; + case 'number': + case 'int': + case 'float': + return 'number'; + case 'boolean': + return 'boolean'; + case 'stringLiteral': + return `"${schema.value}"`; + case 'union': + return schema.members.map(m => schemaToTypeString(m, resourceNames)).join(' | '); + case 'reference': { + const typeName = resourceNames?.get(schema.tableName) || + schema.tableName.charAt(0).toUpperCase() + schema.tableName.slice(1); + const baseType = schema.isArray ? `${typeName}[]` : typeName; + return schema.isOptional ? `${baseType} | null` : baseType; + } + case 'array': + if (schema.element.type === 'tuple') { + const tupleElements = schema.element.elements.map((el) => { + const typeStr = schemaToTypeString(el.schema, resourceNames); + return el.name ? `${el.name}: ${typeStr}` : typeStr; + }); + return `[${tupleElements.join(', ')}][]`; + } + const elementType = schemaToTypeString(schema.element, resourceNames); + if (schema.element.type === 'union') { + return `(${elementType})[]`; + } + return `${elementType}[]`; + case 'tuple': + const tupleElements = schema.elements.map((el) => { + const typeStr = schemaToTypeString(el.schema, resourceNames); + return el.name ? `${el.name}: ${typeStr}` : typeStr; + }); + return `[${tupleElements.join(', ')}]`; + default: + return 'unknown'; + } +} + export function createValidator(schema: Schema): (value: unknown) => boolean { return function validate(value: unknown): boolean { switch (schema.type) {