From da1e3b2dacefee99cb76206111bac2e84477f90b Mon Sep 17 00:00:00 2001 From: hyper Date: Thu, 2 Apr 2026 21:03:57 +0800 Subject: [PATCH] refactor: remove dist/ from git --- .gitignore | 4 +- dist/csv-loader/loader.d.mts | 19 -- dist/csv-loader/loader.d.ts | 19 -- dist/csv-loader/loader.js | 522 ----------------------------------- dist/csv-loader/loader.mjs | 491 -------------------------------- dist/index.d.mts | 35 --- dist/index.d.ts | 35 --- dist/index.js | 408 --------------------------- dist/index.mjs | 377 ------------------------- 9 files changed, 2 insertions(+), 1908 deletions(-) delete mode 100644 dist/csv-loader/loader.d.mts delete mode 100644 dist/csv-loader/loader.d.ts delete mode 100644 dist/csv-loader/loader.js delete mode 100644 dist/csv-loader/loader.mjs delete mode 100644 dist/index.d.mts delete mode 100644 dist/index.d.ts delete mode 100644 dist/index.js delete mode 100644 dist/index.mjs diff --git a/.gitignore b/.gitignore index d785c1d..f4e62ad 100644 --- a/.gitignore +++ b/.gitignore @@ -4,8 +4,8 @@ package-lock.json pnpm-lock.yaml yarn.lock -# Build output (kept in git for npm distribution) -# dist/ +# Build output +dist/ # TypeScript Cache *.tsbuildinfo diff --git a/dist/csv-loader/loader.d.mts b/dist/csv-loader/loader.d.mts deleted file mode 100644 index 607e045..0000000 --- a/dist/csv-loader/loader.d.mts +++ /dev/null @@ -1,19 +0,0 @@ -import { LoaderContext } from '@rspack/core'; - -interface CsvLoaderOptions { - delimiter?: string; - quote?: string; - escape?: string; - bom?: boolean; - comment?: string | false; - trim?: boolean; - /** Generate TypeScript declaration file (.d.ts) */ - emitTypes?: boolean; - /** Output directory for generated type files (relative to output path) */ - typesOutputDir?: string; - /** Write .d.ts files to disk (useful for dev server) */ - writeToDisk?: boolean; -} -declare function csvLoader(this: LoaderContext, content: string): string | Buffer; - -export { type CsvLoaderOptions, csvLoader as default }; diff --git a/dist/csv-loader/loader.d.ts b/dist/csv-loader/loader.d.ts deleted file mode 100644 index 607e045..0000000 --- a/dist/csv-loader/loader.d.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { LoaderContext } from '@rspack/core'; - -interface CsvLoaderOptions { - delimiter?: string; - quote?: string; - escape?: string; - bom?: boolean; - comment?: string | false; - trim?: boolean; - /** Generate TypeScript declaration file (.d.ts) */ - emitTypes?: boolean; - /** Output directory for generated type files (relative to output path) */ - typesOutputDir?: string; - /** Write .d.ts files to disk (useful for dev server) */ - writeToDisk?: boolean; -} -declare function csvLoader(this: LoaderContext, content: string): string | Buffer; - -export { type CsvLoaderOptions, csvLoader as default }; diff --git a/dist/csv-loader/loader.js b/dist/csv-loader/loader.js deleted file mode 100644 index b5fd892..0000000 --- a/dist/csv-loader/loader.js +++ /dev/null @@ -1,522 +0,0 @@ -"use strict"; -var __create = Object.create; -var __defProp = Object.defineProperty; -var __getOwnPropDesc = Object.getOwnPropertyDescriptor; -var __getOwnPropNames = Object.getOwnPropertyNames; -var __getProtoOf = Object.getPrototypeOf; -var __hasOwnProp = Object.prototype.hasOwnProperty; -var __export = (target, all) => { - for (var name in all) - __defProp(target, name, { get: all[name], enumerable: true }); -}; -var __copyProps = (to, from, except, desc) => { - if (from && typeof from === "object" || typeof from === "function") { - for (let key of __getOwnPropNames(from)) - if (!__hasOwnProp.call(to, key) && key !== except) - __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); - } - return to; -}; -var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( - // If the importer is in node compatibility mode or this is not an ESM - // file that has been converted to a CommonJS file using a Babel- - // compatible transform (i.e. "__esModule" has not been set), then set - // "default" to the CommonJS "module.exports" for node compatibility. - isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, - mod -)); -var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); - -// src/csv-loader/loader.ts -var loader_exports = {}; -__export(loader_exports, { - default: () => csvLoader -}); -module.exports = __toCommonJS(loader_exports); -var import_sync = require("csv-parse/sync"); - -// src/parser.ts -var ParseError = class extends Error { - constructor(message, position) { - super(position !== void 0 ? `${message} at position ${position}` : message); - this.position = position; - this.name = "ParseError"; - } -}; -var Parser = class { - constructor(input) { - this.pos = 0; - this.input = input; - } - peek() { - return this.input[this.pos] || ""; - } - consume() { - return this.input[this.pos++] || ""; - } - skipWhitespace() { - while (this.pos < this.input.length && /\s/.test(this.input[this.pos])) { - this.pos++; - } - } - match(str) { - return this.input.slice(this.pos, this.pos + str.length) === str; - } - consumeStr(str) { - if (this.match(str)) { - this.pos += str.length; - return true; - } - return false; - } - getPosition() { - return this.pos; - } - getInputLength() { - return this.input.length; - } - parseSchema() { - this.skipWhitespace(); - if (this.consumeStr("string")) { - if (this.consumeStr("[")) { - this.skipWhitespace(); - if (!this.consumeStr("]")) { - throw new ParseError("Expected ]", this.pos); - } - return { type: "array", element: { type: "string" } }; - } - return { type: "string" }; - } - if (this.consumeStr("number")) { - if (this.consumeStr("[")) { - this.skipWhitespace(); - if (!this.consumeStr("]")) { - throw new ParseError("Expected ]", this.pos); - } - return { type: "array", element: { type: "number" } }; - } - return { type: "number" }; - } - if (this.consumeStr("boolean")) { - if (this.consumeStr("[")) { - this.skipWhitespace(); - if (!this.consumeStr("]")) { - throw new ParseError("Expected ]", this.pos); - } - return { type: "array", element: { type: "boolean" } }; - } - return { type: "boolean" }; - } - if (this.consumeStr("[")) { - const elements = []; - this.skipWhitespace(); - if (this.peek() === "]") { - this.consume(); - throw new ParseError("Empty array/tuple not allowed", this.pos); - } - elements.push(this.parseNamedSchema()); - this.skipWhitespace(); - if (this.consumeStr(";")) { - const remainingElements = []; - while (true) { - this.skipWhitespace(); - remainingElements.push(this.parseNamedSchema()); - this.skipWhitespace(); - if (!this.consumeStr(";")) { - break; - } - } - elements.push(...remainingElements); - } - this.skipWhitespace(); - if (!this.consumeStr("]")) { - throw new ParseError("Expected ]", this.pos); - } - if (this.consumeStr("[")) { - this.skipWhitespace(); - if (!this.consumeStr("]")) { - throw new ParseError("Expected ]", this.pos); - } - if (elements.length === 1 && !elements[0].name) { - return { type: "array", element: elements[0].schema }; - } - return { type: "array", element: { type: "tuple", elements } }; - } - if (elements.length === 1 && !elements[0].name) { - return { type: "array", element: elements[0].schema }; - } - return { type: "tuple", elements }; - } - let identifier = ""; - while (this.pos < this.input.length && /[a-zA-Z0-9\-_]/.test(this.peek())) { - identifier += this.consume(); - } - if (identifier.length > 0) { - if (this.consumeStr("[")) { - this.skipWhitespace(); - if (!this.consumeStr("]")) { - throw new ParseError("Expected ]", this.pos); - } - return { type: "array", element: { type: "string" } }; - } - return { type: "string" }; - } - throw new ParseError(`Unexpected character: ${this.peek()}`, this.pos); - } - parseNamedSchema() { - this.skipWhitespace(); - const startpos = this.pos; - let identifier = ""; - while (this.pos < this.input.length && /[a-zA-Z0-9\-_]/.test(this.peek())) { - identifier += this.consume(); - } - if (identifier.length === 0) { - throw new ParseError("Expected schema or named schema", this.pos); - } - this.skipWhitespace(); - if (this.consumeStr(":")) { - this.skipWhitespace(); - const name = identifier; - const schema = this.parseSchema(); - return { name, schema }; - } else { - this.pos = startpos; - const schema = this.parseSchema(); - return { schema }; - } - } -}; -function parseSchema(schemaString) { - const parser = new Parser(schemaString.trim()); - const schema = parser.parseSchema(); - if (parser.getPosition() < parser.getInputLength()) { - throw new ParseError("Unexpected input after schema", parser.getPosition()); - } - return schema; -} - -// src/validator.ts -var ValueParser = class { - constructor(input) { - this.pos = 0; - this.input = input; - } - peek() { - return this.input[this.pos] || ""; - } - consume() { - return this.input[this.pos++] || ""; - } - skipWhitespace() { - while (this.pos < this.input.length && /\s/.test(this.input[this.pos])) { - this.pos++; - } - } - consumeStr(str) { - if (this.input.slice(this.pos, this.pos + str.length) === str) { - this.pos += str.length; - return true; - } - return false; - } - parseValue(schema, allowOmitBrackets = false) { - this.skipWhitespace(); - switch (schema.type) { - case "string": - return this.parseStringValue(); - case "number": - return this.parseNumberValue(); - case "boolean": - return this.parseBooleanValue(); - case "tuple": - return this.parseTupleValue(schema, allowOmitBrackets); - case "array": - return this.parseArrayValue(schema, allowOmitBrackets); - default: - throw new ParseError(`Unknown schema type: ${schema.type}`, this.pos); - } - } - parseStringValue() { - let result = ""; - while (this.pos < this.input.length) { - const char = this.peek(); - if (char === "\\") { - this.consume(); - const nextChar = this.consume(); - if (nextChar === ";" || nextChar === "[" || nextChar === "]" || nextChar === "\\") { - result += nextChar; - } else { - result += "\\" + nextChar; - } - } else if (char === ";" || char === "]") { - break; - } else { - result += this.consume(); - } - } - return result.trim(); - } - parseNumberValue() { - let numStr = ""; - while (this.pos < this.input.length && /[\d.\-+eE]/.test(this.peek())) { - numStr += this.consume(); - } - const num = parseFloat(numStr); - if (isNaN(num)) { - throw new ParseError("Invalid number", this.pos - numStr.length); - } - return num; - } - parseBooleanValue() { - if (this.consumeStr("true")) { - return true; - } - if (this.consumeStr("false")) { - return false; - } - throw new ParseError("Expected true or false", this.pos); - } - parseTupleValue(schema, allowOmitBrackets) { - let hasOpenBracket = false; - if (this.peek() === "[") { - this.consume(); - hasOpenBracket = true; - } else if (!allowOmitBrackets) { - throw new ParseError("Expected [", this.pos); - } - this.skipWhitespace(); - if (this.peek() === "]" && hasOpenBracket) { - this.consume(); - return []; - } - const result = []; - for (let i = 0; i < schema.elements.length; i++) { - this.skipWhitespace(); - const elementSchema = schema.elements[i]; - if (elementSchema.name) { - this.skipWhitespace(); - const savedPos = this.pos; - if (this.consumeStr(`${elementSchema.name}:`)) { - this.skipWhitespace(); - } else { - this.pos = savedPos; - } - } - result.push(this.parseValue(elementSchema.schema, false)); - this.skipWhitespace(); - if (i < schema.elements.length - 1) { - if (!this.consumeStr(";")) { - throw new ParseError("Expected ;", this.pos); - } - } - } - this.skipWhitespace(); - if (hasOpenBracket) { - if (!this.consumeStr("]")) { - throw new ParseError("Expected ]", this.pos); - } - } - return result; - } - parseArrayValue(schema, allowOmitBrackets) { - let hasOpenBracket = false; - const elementIsTupleOrArray = schema.element.type === "tuple" || schema.element.type === "array"; - if (this.peek() === "[") { - if (!elementIsTupleOrArray) { - this.consume(); - hasOpenBracket = true; - } else if (this.input[this.pos + 1] === "[") { - this.consume(); - hasOpenBracket = true; - } - } - if (!hasOpenBracket && !allowOmitBrackets && !elementIsTupleOrArray) { - throw new ParseError("Expected [", this.pos); - } - this.skipWhitespace(); - if (this.peek() === "]" && hasOpenBracket) { - this.consume(); - return []; - } - const result = []; - while (true) { - this.skipWhitespace(); - result.push(this.parseValue(schema.element, false)); - this.skipWhitespace(); - if (!this.consumeStr(";")) { - break; - } - } - this.skipWhitespace(); - if (hasOpenBracket) { - if (!this.consumeStr("]")) { - throw new ParseError("Expected ]", this.pos); - } - } - return result; - } - getPosition() { - return this.pos; - } - getInputLength() { - return this.input.length; - } -}; -function parseValue(schema, valueString) { - const parser = new ValueParser(valueString.trim()); - const allowOmitBrackets = schema.type === "tuple" || schema.type === "array"; - const value = parser.parseValue(schema, allowOmitBrackets); - if (parser.getPosition() < parser.getInputLength()) { - throw new ParseError("Unexpected input after value", parser.getPosition()); - } - return value; -} -function createValidator(schema) { - return function validate(value) { - switch (schema.type) { - case "string": - return typeof value === "string"; - case "number": - return typeof value === "number" && !isNaN(value); - case "boolean": - return typeof value === "boolean"; - case "tuple": - if (!Array.isArray(value)) return false; - if (value.length !== schema.elements.length) return false; - return schema.elements.every( - (elementSchema, index) => createValidator(elementSchema.schema)(value[index]) - ); - case "array": - if (!Array.isArray(value)) return false; - return value.every((item) => createValidator(schema.element)(item)); - default: - return false; - } - }; -} - -// src/csv-loader/loader.ts -var path = __toESM(require("path")); -var fs = __toESM(require("fs")); -function schemaToTypeString(schema) { - switch (schema.type) { - case "string": - return "string"; - case "number": - return "number"; - case "boolean": - return "boolean"; - case "array": - if (schema.element.type === "tuple") { - const tupleElements2 = schema.element.elements.map((el) => { - const typeStr = schemaToTypeString(el.schema); - return el.name ? `${el.name}: ${typeStr}` : typeStr; - }); - return `[${tupleElements2.join(", ")}]`; - } - return `${schemaToTypeString(schema.element)}[]`; - case "tuple": - const tupleElements = schema.elements.map((el) => { - const typeStr = schemaToTypeString(el.schema); - return el.name ? `${el.name}: ${typeStr}` : typeStr; - }); - return `[${tupleElements.join(", ")}]`; - default: - return "unknown"; - } -} -function generateTypeDefinition(resourceName, propertyConfigs) { - const properties = propertyConfigs.map((config) => ` ${config.name}: ${schemaToTypeString(config.schema)};`).join("\n"); - return `type Table = { -${properties} - }[]; - -declare const data: Table; -export default data; -`; -} -function csvLoader(content) { - const options = this.getOptions(); - const delimiter = options?.delimiter ?? ","; - const quote = options?.quote ?? '"'; - const escape = options?.escape ?? "\\"; - const bom = options?.bom ?? true; - const comment = options?.comment === false ? void 0 : options?.comment ?? "#"; - const trim = options?.trim ?? true; - const emitTypes = options?.emitTypes ?? true; - const typesOutputDir = options?.typesOutputDir ?? ""; - const writeToDisk = options?.writeToDisk ?? false; - const records = (0, import_sync.parse)(content, { - delimiter, - quote, - escape, - bom, - comment, - trim, - relax_column_count: true - }); - if (records.length < 2) { - throw new Error("CSV must have at least 2 rows: headers and schemas"); - } - const headers = records[0]; - const schemas = records[1]; - if (headers.length !== schemas.length) { - throw new Error( - `Header count (${headers.length}) does not match schema count (${schemas.length})` - ); - } - const propertyConfigs = headers.map((header, index) => { - const schemaString = schemas[index]; - const schema = parseSchema(schemaString); - return { - name: header, - schema, - validator: createValidator(schema), - parser: (valueString) => parseValue(schema, valueString) - }; - }); - const dataRows = records.slice(2); - const objects = dataRows.map((row, rowIndex) => { - const obj = {}; - propertyConfigs.forEach((config, colIndex) => { - const rawValue = row[colIndex] ?? ""; - try { - const parsed = config.parser(rawValue); - if (!config.validator(parsed)) { - throw new Error( - `Validation failed for property "${config.name}" at row ${rowIndex + 3}: ${rawValue}` - ); - } - obj[config.name] = parsed; - } catch (error) { - if (error instanceof Error) { - throw new Error( - `Failed to parse property "${config.name}" at row ${rowIndex + 3}, column ${colIndex + 1}: ${error.message}` - ); - } - throw error; - } - }); - return obj; - }); - const json = JSON.stringify(objects, null, 2); - if (emitTypes) { - const context = this.context || ""; - let relativePath = this.resourcePath.replace(context, ""); - if (relativePath.startsWith("\\") || relativePath.startsWith("/")) { - relativePath = relativePath.substring(1); - } - relativePath = relativePath.replace(/\\/g, "/"); - const dtsFileName = `${relativePath}.d.ts`; - const outputPath = typesOutputDir ? path.join(typesOutputDir, dtsFileName) : dtsFileName; - const dtsContent = generateTypeDefinition(this.resourcePath, propertyConfigs); - if (writeToDisk) { - const absolutePath = path.join(this.context || process.cwd(), typesOutputDir || "", dtsFileName); - fs.mkdirSync(path.dirname(absolutePath), { recursive: true }); - fs.writeFileSync(absolutePath, dtsContent); - } else { - this.emitFile?.(outputPath, dtsContent); - } - } - return `export default ${json};`; -} diff --git a/dist/csv-loader/loader.mjs b/dist/csv-loader/loader.mjs deleted file mode 100644 index 2800a64..0000000 --- a/dist/csv-loader/loader.mjs +++ /dev/null @@ -1,491 +0,0 @@ -// src/csv-loader/loader.ts -import { parse } from "csv-parse/sync"; - -// src/parser.ts -var ParseError = class extends Error { - constructor(message, position) { - super(position !== void 0 ? `${message} at position ${position}` : message); - this.position = position; - this.name = "ParseError"; - } -}; -var Parser = class { - constructor(input) { - this.pos = 0; - this.input = input; - } - peek() { - return this.input[this.pos] || ""; - } - consume() { - return this.input[this.pos++] || ""; - } - skipWhitespace() { - while (this.pos < this.input.length && /\s/.test(this.input[this.pos])) { - this.pos++; - } - } - match(str) { - return this.input.slice(this.pos, this.pos + str.length) === str; - } - consumeStr(str) { - if (this.match(str)) { - this.pos += str.length; - return true; - } - return false; - } - getPosition() { - return this.pos; - } - getInputLength() { - return this.input.length; - } - parseSchema() { - this.skipWhitespace(); - if (this.consumeStr("string")) { - if (this.consumeStr("[")) { - this.skipWhitespace(); - if (!this.consumeStr("]")) { - throw new ParseError("Expected ]", this.pos); - } - return { type: "array", element: { type: "string" } }; - } - return { type: "string" }; - } - if (this.consumeStr("number")) { - if (this.consumeStr("[")) { - this.skipWhitespace(); - if (!this.consumeStr("]")) { - throw new ParseError("Expected ]", this.pos); - } - return { type: "array", element: { type: "number" } }; - } - return { type: "number" }; - } - if (this.consumeStr("boolean")) { - if (this.consumeStr("[")) { - this.skipWhitespace(); - if (!this.consumeStr("]")) { - throw new ParseError("Expected ]", this.pos); - } - return { type: "array", element: { type: "boolean" } }; - } - return { type: "boolean" }; - } - if (this.consumeStr("[")) { - const elements = []; - this.skipWhitespace(); - if (this.peek() === "]") { - this.consume(); - throw new ParseError("Empty array/tuple not allowed", this.pos); - } - elements.push(this.parseNamedSchema()); - this.skipWhitespace(); - if (this.consumeStr(";")) { - const remainingElements = []; - while (true) { - this.skipWhitespace(); - remainingElements.push(this.parseNamedSchema()); - this.skipWhitespace(); - if (!this.consumeStr(";")) { - break; - } - } - elements.push(...remainingElements); - } - this.skipWhitespace(); - if (!this.consumeStr("]")) { - throw new ParseError("Expected ]", this.pos); - } - if (this.consumeStr("[")) { - this.skipWhitespace(); - if (!this.consumeStr("]")) { - throw new ParseError("Expected ]", this.pos); - } - if (elements.length === 1 && !elements[0].name) { - return { type: "array", element: elements[0].schema }; - } - return { type: "array", element: { type: "tuple", elements } }; - } - if (elements.length === 1 && !elements[0].name) { - return { type: "array", element: elements[0].schema }; - } - return { type: "tuple", elements }; - } - let identifier = ""; - while (this.pos < this.input.length && /[a-zA-Z0-9\-_]/.test(this.peek())) { - identifier += this.consume(); - } - if (identifier.length > 0) { - if (this.consumeStr("[")) { - this.skipWhitespace(); - if (!this.consumeStr("]")) { - throw new ParseError("Expected ]", this.pos); - } - return { type: "array", element: { type: "string" } }; - } - return { type: "string" }; - } - throw new ParseError(`Unexpected character: ${this.peek()}`, this.pos); - } - parseNamedSchema() { - this.skipWhitespace(); - const startpos = this.pos; - let identifier = ""; - while (this.pos < this.input.length && /[a-zA-Z0-9\-_]/.test(this.peek())) { - identifier += this.consume(); - } - if (identifier.length === 0) { - throw new ParseError("Expected schema or named schema", this.pos); - } - this.skipWhitespace(); - if (this.consumeStr(":")) { - this.skipWhitespace(); - const name = identifier; - const schema = this.parseSchema(); - return { name, schema }; - } else { - this.pos = startpos; - const schema = this.parseSchema(); - return { schema }; - } - } -}; -function parseSchema(schemaString) { - const parser = new Parser(schemaString.trim()); - const schema = parser.parseSchema(); - if (parser.getPosition() < parser.getInputLength()) { - throw new ParseError("Unexpected input after schema", parser.getPosition()); - } - return schema; -} - -// src/validator.ts -var ValueParser = class { - constructor(input) { - this.pos = 0; - this.input = input; - } - peek() { - return this.input[this.pos] || ""; - } - consume() { - return this.input[this.pos++] || ""; - } - skipWhitespace() { - while (this.pos < this.input.length && /\s/.test(this.input[this.pos])) { - this.pos++; - } - } - consumeStr(str) { - if (this.input.slice(this.pos, this.pos + str.length) === str) { - this.pos += str.length; - return true; - } - return false; - } - parseValue(schema, allowOmitBrackets = false) { - this.skipWhitespace(); - switch (schema.type) { - case "string": - return this.parseStringValue(); - case "number": - return this.parseNumberValue(); - case "boolean": - return this.parseBooleanValue(); - case "tuple": - return this.parseTupleValue(schema, allowOmitBrackets); - case "array": - return this.parseArrayValue(schema, allowOmitBrackets); - default: - throw new ParseError(`Unknown schema type: ${schema.type}`, this.pos); - } - } - parseStringValue() { - let result = ""; - while (this.pos < this.input.length) { - const char = this.peek(); - if (char === "\\") { - this.consume(); - const nextChar = this.consume(); - if (nextChar === ";" || nextChar === "[" || nextChar === "]" || nextChar === "\\") { - result += nextChar; - } else { - result += "\\" + nextChar; - } - } else if (char === ";" || char === "]") { - break; - } else { - result += this.consume(); - } - } - return result.trim(); - } - parseNumberValue() { - let numStr = ""; - while (this.pos < this.input.length && /[\d.\-+eE]/.test(this.peek())) { - numStr += this.consume(); - } - const num = parseFloat(numStr); - if (isNaN(num)) { - throw new ParseError("Invalid number", this.pos - numStr.length); - } - return num; - } - parseBooleanValue() { - if (this.consumeStr("true")) { - return true; - } - if (this.consumeStr("false")) { - return false; - } - throw new ParseError("Expected true or false", this.pos); - } - parseTupleValue(schema, allowOmitBrackets) { - let hasOpenBracket = false; - if (this.peek() === "[") { - this.consume(); - hasOpenBracket = true; - } else if (!allowOmitBrackets) { - throw new ParseError("Expected [", this.pos); - } - this.skipWhitespace(); - if (this.peek() === "]" && hasOpenBracket) { - this.consume(); - return []; - } - const result = []; - for (let i = 0; i < schema.elements.length; i++) { - this.skipWhitespace(); - const elementSchema = schema.elements[i]; - if (elementSchema.name) { - this.skipWhitespace(); - const savedPos = this.pos; - if (this.consumeStr(`${elementSchema.name}:`)) { - this.skipWhitespace(); - } else { - this.pos = savedPos; - } - } - result.push(this.parseValue(elementSchema.schema, false)); - this.skipWhitespace(); - if (i < schema.elements.length - 1) { - if (!this.consumeStr(";")) { - throw new ParseError("Expected ;", this.pos); - } - } - } - this.skipWhitespace(); - if (hasOpenBracket) { - if (!this.consumeStr("]")) { - throw new ParseError("Expected ]", this.pos); - } - } - return result; - } - parseArrayValue(schema, allowOmitBrackets) { - let hasOpenBracket = false; - const elementIsTupleOrArray = schema.element.type === "tuple" || schema.element.type === "array"; - if (this.peek() === "[") { - if (!elementIsTupleOrArray) { - this.consume(); - hasOpenBracket = true; - } else if (this.input[this.pos + 1] === "[") { - this.consume(); - hasOpenBracket = true; - } - } - if (!hasOpenBracket && !allowOmitBrackets && !elementIsTupleOrArray) { - throw new ParseError("Expected [", this.pos); - } - this.skipWhitespace(); - if (this.peek() === "]" && hasOpenBracket) { - this.consume(); - return []; - } - const result = []; - while (true) { - this.skipWhitespace(); - result.push(this.parseValue(schema.element, false)); - this.skipWhitespace(); - if (!this.consumeStr(";")) { - break; - } - } - this.skipWhitespace(); - if (hasOpenBracket) { - if (!this.consumeStr("]")) { - throw new ParseError("Expected ]", this.pos); - } - } - return result; - } - getPosition() { - return this.pos; - } - getInputLength() { - return this.input.length; - } -}; -function parseValue(schema, valueString) { - const parser = new ValueParser(valueString.trim()); - const allowOmitBrackets = schema.type === "tuple" || schema.type === "array"; - const value = parser.parseValue(schema, allowOmitBrackets); - if (parser.getPosition() < parser.getInputLength()) { - throw new ParseError("Unexpected input after value", parser.getPosition()); - } - return value; -} -function createValidator(schema) { - return function validate(value) { - switch (schema.type) { - case "string": - return typeof value === "string"; - case "number": - return typeof value === "number" && !isNaN(value); - case "boolean": - return typeof value === "boolean"; - case "tuple": - if (!Array.isArray(value)) return false; - if (value.length !== schema.elements.length) return false; - return schema.elements.every( - (elementSchema, index) => createValidator(elementSchema.schema)(value[index]) - ); - case "array": - if (!Array.isArray(value)) return false; - return value.every((item) => createValidator(schema.element)(item)); - default: - return false; - } - }; -} - -// src/csv-loader/loader.ts -import * as path from "path"; -import * as fs from "fs"; -function schemaToTypeString(schema) { - switch (schema.type) { - case "string": - return "string"; - case "number": - return "number"; - case "boolean": - return "boolean"; - case "array": - if (schema.element.type === "tuple") { - const tupleElements2 = schema.element.elements.map((el) => { - const typeStr = schemaToTypeString(el.schema); - return el.name ? `${el.name}: ${typeStr}` : typeStr; - }); - return `[${tupleElements2.join(", ")}]`; - } - return `${schemaToTypeString(schema.element)}[]`; - case "tuple": - const tupleElements = schema.elements.map((el) => { - const typeStr = schemaToTypeString(el.schema); - return el.name ? `${el.name}: ${typeStr}` : typeStr; - }); - return `[${tupleElements.join(", ")}]`; - default: - return "unknown"; - } -} -function generateTypeDefinition(resourceName, propertyConfigs) { - const properties = propertyConfigs.map((config) => ` ${config.name}: ${schemaToTypeString(config.schema)};`).join("\n"); - return `type Table = { -${properties} - }[]; - -declare const data: Table; -export default data; -`; -} -function csvLoader(content) { - const options = this.getOptions(); - const delimiter = options?.delimiter ?? ","; - const quote = options?.quote ?? '"'; - const escape = options?.escape ?? "\\"; - const bom = options?.bom ?? true; - const comment = options?.comment === false ? void 0 : options?.comment ?? "#"; - const trim = options?.trim ?? true; - const emitTypes = options?.emitTypes ?? true; - const typesOutputDir = options?.typesOutputDir ?? ""; - const writeToDisk = options?.writeToDisk ?? false; - const records = parse(content, { - delimiter, - quote, - escape, - bom, - comment, - trim, - relax_column_count: true - }); - if (records.length < 2) { - throw new Error("CSV must have at least 2 rows: headers and schemas"); - } - const headers = records[0]; - const schemas = records[1]; - if (headers.length !== schemas.length) { - throw new Error( - `Header count (${headers.length}) does not match schema count (${schemas.length})` - ); - } - const propertyConfigs = headers.map((header, index) => { - const schemaString = schemas[index]; - const schema = parseSchema(schemaString); - return { - name: header, - schema, - validator: createValidator(schema), - parser: (valueString) => parseValue(schema, valueString) - }; - }); - const dataRows = records.slice(2); - const objects = dataRows.map((row, rowIndex) => { - const obj = {}; - propertyConfigs.forEach((config, colIndex) => { - const rawValue = row[colIndex] ?? ""; - try { - const parsed = config.parser(rawValue); - if (!config.validator(parsed)) { - throw new Error( - `Validation failed for property "${config.name}" at row ${rowIndex + 3}: ${rawValue}` - ); - } - obj[config.name] = parsed; - } catch (error) { - if (error instanceof Error) { - throw new Error( - `Failed to parse property "${config.name}" at row ${rowIndex + 3}, column ${colIndex + 1}: ${error.message}` - ); - } - throw error; - } - }); - return obj; - }); - const json = JSON.stringify(objects, null, 2); - if (emitTypes) { - const context = this.context || ""; - let relativePath = this.resourcePath.replace(context, ""); - if (relativePath.startsWith("\\") || relativePath.startsWith("/")) { - relativePath = relativePath.substring(1); - } - relativePath = relativePath.replace(/\\/g, "/"); - const dtsFileName = `${relativePath}.d.ts`; - const outputPath = typesOutputDir ? path.join(typesOutputDir, dtsFileName) : dtsFileName; - const dtsContent = generateTypeDefinition(this.resourcePath, propertyConfigs); - if (writeToDisk) { - const absolutePath = path.join(this.context || process.cwd(), typesOutputDir || "", dtsFileName); - fs.mkdirSync(path.dirname(absolutePath), { recursive: true }); - fs.writeFileSync(absolutePath, dtsContent); - } else { - this.emitFile?.(outputPath, dtsContent); - } - } - return `export default ${json};`; -} -export { - csvLoader as default -}; diff --git a/dist/index.d.mts b/dist/index.d.mts deleted file mode 100644 index 74b9215..0000000 --- a/dist/index.d.mts +++ /dev/null @@ -1,35 +0,0 @@ -type SchemaType = 'string' | 'number' | 'boolean'; -interface PrimitiveSchema { - type: SchemaType; -} -interface NamedSchema { - name?: string; - schema: Schema; -} -interface TupleSchema { - type: 'tuple'; - elements: NamedSchema[]; -} -interface ArraySchema { - type: 'array'; - element: Schema; -} -type Schema = PrimitiveSchema | TupleSchema | ArraySchema; -interface ParsedSchema { - schema: Schema; - validator: (value: unknown) => boolean; - parse: (valueString: string) => unknown; -} - -declare class ParseError extends Error { - position?: number | undefined; - constructor(message: string, position?: number | undefined); -} -declare function parseSchema(schemaString: string): Schema; - -declare function parseValue(schema: Schema, valueString: string): unknown; -declare function createValidator(schema: Schema): (value: unknown) => boolean; - -declare function defineSchema(schemaString: string): ParsedSchema; - -export { type ArraySchema, ParseError, type ParsedSchema, type PrimitiveSchema, type Schema, type TupleSchema, createValidator, defineSchema, parseSchema, parseValue }; diff --git a/dist/index.d.ts b/dist/index.d.ts deleted file mode 100644 index 74b9215..0000000 --- a/dist/index.d.ts +++ /dev/null @@ -1,35 +0,0 @@ -type SchemaType = 'string' | 'number' | 'boolean'; -interface PrimitiveSchema { - type: SchemaType; -} -interface NamedSchema { - name?: string; - schema: Schema; -} -interface TupleSchema { - type: 'tuple'; - elements: NamedSchema[]; -} -interface ArraySchema { - type: 'array'; - element: Schema; -} -type Schema = PrimitiveSchema | TupleSchema | ArraySchema; -interface ParsedSchema { - schema: Schema; - validator: (value: unknown) => boolean; - parse: (valueString: string) => unknown; -} - -declare class ParseError extends Error { - position?: number | undefined; - constructor(message: string, position?: number | undefined); -} -declare function parseSchema(schemaString: string): Schema; - -declare function parseValue(schema: Schema, valueString: string): unknown; -declare function createValidator(schema: Schema): (value: unknown) => boolean; - -declare function defineSchema(schemaString: string): ParsedSchema; - -export { type ArraySchema, ParseError, type ParsedSchema, type PrimitiveSchema, type Schema, type TupleSchema, createValidator, defineSchema, parseSchema, parseValue }; diff --git a/dist/index.js b/dist/index.js deleted file mode 100644 index 6905d8c..0000000 --- a/dist/index.js +++ /dev/null @@ -1,408 +0,0 @@ -"use strict"; -var __defProp = Object.defineProperty; -var __getOwnPropDesc = Object.getOwnPropertyDescriptor; -var __getOwnPropNames = Object.getOwnPropertyNames; -var __hasOwnProp = Object.prototype.hasOwnProperty; -var __export = (target, all) => { - for (var name in all) - __defProp(target, name, { get: all[name], enumerable: true }); -}; -var __copyProps = (to, from, except, desc) => { - if (from && typeof from === "object" || typeof from === "function") { - for (let key of __getOwnPropNames(from)) - if (!__hasOwnProp.call(to, key) && key !== except) - __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); - } - return to; -}; -var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); - -// src/index.ts -var index_exports = {}; -__export(index_exports, { - ParseError: () => ParseError, - createValidator: () => createValidator, - defineSchema: () => defineSchema, - parseSchema: () => parseSchema, - parseValue: () => parseValue -}); -module.exports = __toCommonJS(index_exports); - -// src/parser.ts -var ParseError = class extends Error { - constructor(message, position) { - super(position !== void 0 ? `${message} at position ${position}` : message); - this.position = position; - this.name = "ParseError"; - } -}; -var Parser = class { - constructor(input) { - this.pos = 0; - this.input = input; - } - peek() { - return this.input[this.pos] || ""; - } - consume() { - return this.input[this.pos++] || ""; - } - skipWhitespace() { - while (this.pos < this.input.length && /\s/.test(this.input[this.pos])) { - this.pos++; - } - } - match(str) { - return this.input.slice(this.pos, this.pos + str.length) === str; - } - consumeStr(str) { - if (this.match(str)) { - this.pos += str.length; - return true; - } - return false; - } - getPosition() { - return this.pos; - } - getInputLength() { - return this.input.length; - } - parseSchema() { - this.skipWhitespace(); - if (this.consumeStr("string")) { - if (this.consumeStr("[")) { - this.skipWhitespace(); - if (!this.consumeStr("]")) { - throw new ParseError("Expected ]", this.pos); - } - return { type: "array", element: { type: "string" } }; - } - return { type: "string" }; - } - if (this.consumeStr("number")) { - if (this.consumeStr("[")) { - this.skipWhitespace(); - if (!this.consumeStr("]")) { - throw new ParseError("Expected ]", this.pos); - } - return { type: "array", element: { type: "number" } }; - } - return { type: "number" }; - } - if (this.consumeStr("boolean")) { - if (this.consumeStr("[")) { - this.skipWhitespace(); - if (!this.consumeStr("]")) { - throw new ParseError("Expected ]", this.pos); - } - return { type: "array", element: { type: "boolean" } }; - } - return { type: "boolean" }; - } - if (this.consumeStr("[")) { - const elements = []; - this.skipWhitespace(); - if (this.peek() === "]") { - this.consume(); - throw new ParseError("Empty array/tuple not allowed", this.pos); - } - elements.push(this.parseNamedSchema()); - this.skipWhitespace(); - if (this.consumeStr(";")) { - const remainingElements = []; - while (true) { - this.skipWhitespace(); - remainingElements.push(this.parseNamedSchema()); - this.skipWhitespace(); - if (!this.consumeStr(";")) { - break; - } - } - elements.push(...remainingElements); - } - this.skipWhitespace(); - if (!this.consumeStr("]")) { - throw new ParseError("Expected ]", this.pos); - } - if (this.consumeStr("[")) { - this.skipWhitespace(); - if (!this.consumeStr("]")) { - throw new ParseError("Expected ]", this.pos); - } - if (elements.length === 1 && !elements[0].name) { - return { type: "array", element: elements[0].schema }; - } - return { type: "array", element: { type: "tuple", elements } }; - } - if (elements.length === 1 && !elements[0].name) { - return { type: "array", element: elements[0].schema }; - } - return { type: "tuple", elements }; - } - let identifier = ""; - while (this.pos < this.input.length && /[a-zA-Z0-9\-_]/.test(this.peek())) { - identifier += this.consume(); - } - if (identifier.length > 0) { - if (this.consumeStr("[")) { - this.skipWhitespace(); - if (!this.consumeStr("]")) { - throw new ParseError("Expected ]", this.pos); - } - return { type: "array", element: { type: "string" } }; - } - return { type: "string" }; - } - throw new ParseError(`Unexpected character: ${this.peek()}`, this.pos); - } - parseNamedSchema() { - this.skipWhitespace(); - const startpos = this.pos; - let identifier = ""; - while (this.pos < this.input.length && /[a-zA-Z0-9\-_]/.test(this.peek())) { - identifier += this.consume(); - } - if (identifier.length === 0) { - throw new ParseError("Expected schema or named schema", this.pos); - } - this.skipWhitespace(); - if (this.consumeStr(":")) { - this.skipWhitespace(); - const name = identifier; - const schema = this.parseSchema(); - return { name, schema }; - } else { - this.pos = startpos; - const schema = this.parseSchema(); - return { schema }; - } - } -}; -function parseSchema(schemaString) { - const parser = new Parser(schemaString.trim()); - const schema = parser.parseSchema(); - if (parser.getPosition() < parser.getInputLength()) { - throw new ParseError("Unexpected input after schema", parser.getPosition()); - } - return schema; -} - -// src/validator.ts -var ValueParser = class { - constructor(input) { - this.pos = 0; - this.input = input; - } - peek() { - return this.input[this.pos] || ""; - } - consume() { - return this.input[this.pos++] || ""; - } - skipWhitespace() { - while (this.pos < this.input.length && /\s/.test(this.input[this.pos])) { - this.pos++; - } - } - consumeStr(str) { - if (this.input.slice(this.pos, this.pos + str.length) === str) { - this.pos += str.length; - return true; - } - return false; - } - parseValue(schema, allowOmitBrackets = false) { - this.skipWhitespace(); - switch (schema.type) { - case "string": - return this.parseStringValue(); - case "number": - return this.parseNumberValue(); - case "boolean": - return this.parseBooleanValue(); - case "tuple": - return this.parseTupleValue(schema, allowOmitBrackets); - case "array": - return this.parseArrayValue(schema, allowOmitBrackets); - default: - throw new ParseError(`Unknown schema type: ${schema.type}`, this.pos); - } - } - parseStringValue() { - let result = ""; - while (this.pos < this.input.length) { - const char = this.peek(); - if (char === "\\") { - this.consume(); - const nextChar = this.consume(); - if (nextChar === ";" || nextChar === "[" || nextChar === "]" || nextChar === "\\") { - result += nextChar; - } else { - result += "\\" + nextChar; - } - } else if (char === ";" || char === "]") { - break; - } else { - result += this.consume(); - } - } - return result.trim(); - } - parseNumberValue() { - let numStr = ""; - while (this.pos < this.input.length && /[\d.\-+eE]/.test(this.peek())) { - numStr += this.consume(); - } - const num = parseFloat(numStr); - if (isNaN(num)) { - throw new ParseError("Invalid number", this.pos - numStr.length); - } - return num; - } - parseBooleanValue() { - if (this.consumeStr("true")) { - return true; - } - if (this.consumeStr("false")) { - return false; - } - throw new ParseError("Expected true or false", this.pos); - } - parseTupleValue(schema, allowOmitBrackets) { - let hasOpenBracket = false; - if (this.peek() === "[") { - this.consume(); - hasOpenBracket = true; - } else if (!allowOmitBrackets) { - throw new ParseError("Expected [", this.pos); - } - this.skipWhitespace(); - if (this.peek() === "]" && hasOpenBracket) { - this.consume(); - return []; - } - const result = []; - for (let i = 0; i < schema.elements.length; i++) { - this.skipWhitespace(); - const elementSchema = schema.elements[i]; - if (elementSchema.name) { - this.skipWhitespace(); - const savedPos = this.pos; - if (this.consumeStr(`${elementSchema.name}:`)) { - this.skipWhitespace(); - } else { - this.pos = savedPos; - } - } - result.push(this.parseValue(elementSchema.schema, false)); - this.skipWhitespace(); - if (i < schema.elements.length - 1) { - if (!this.consumeStr(";")) { - throw new ParseError("Expected ;", this.pos); - } - } - } - this.skipWhitespace(); - if (hasOpenBracket) { - if (!this.consumeStr("]")) { - throw new ParseError("Expected ]", this.pos); - } - } - return result; - } - parseArrayValue(schema, allowOmitBrackets) { - let hasOpenBracket = false; - const elementIsTupleOrArray = schema.element.type === "tuple" || schema.element.type === "array"; - if (this.peek() === "[") { - if (!elementIsTupleOrArray) { - this.consume(); - hasOpenBracket = true; - } else if (this.input[this.pos + 1] === "[") { - this.consume(); - hasOpenBracket = true; - } - } - if (!hasOpenBracket && !allowOmitBrackets && !elementIsTupleOrArray) { - throw new ParseError("Expected [", this.pos); - } - this.skipWhitespace(); - if (this.peek() === "]" && hasOpenBracket) { - this.consume(); - return []; - } - const result = []; - while (true) { - this.skipWhitespace(); - result.push(this.parseValue(schema.element, false)); - this.skipWhitespace(); - if (!this.consumeStr(";")) { - break; - } - } - this.skipWhitespace(); - if (hasOpenBracket) { - if (!this.consumeStr("]")) { - throw new ParseError("Expected ]", this.pos); - } - } - return result; - } - getPosition() { - return this.pos; - } - getInputLength() { - return this.input.length; - } -}; -function parseValue(schema, valueString) { - const parser = new ValueParser(valueString.trim()); - const allowOmitBrackets = schema.type === "tuple" || schema.type === "array"; - const value = parser.parseValue(schema, allowOmitBrackets); - if (parser.getPosition() < parser.getInputLength()) { - throw new ParseError("Unexpected input after value", parser.getPosition()); - } - return value; -} -function createValidator(schema) { - return function validate(value) { - switch (schema.type) { - case "string": - return typeof value === "string"; - case "number": - return typeof value === "number" && !isNaN(value); - case "boolean": - return typeof value === "boolean"; - case "tuple": - if (!Array.isArray(value)) return false; - if (value.length !== schema.elements.length) return false; - return schema.elements.every( - (elementSchema, index) => createValidator(elementSchema.schema)(value[index]) - ); - case "array": - if (!Array.isArray(value)) return false; - return value.every((item) => createValidator(schema.element)(item)); - default: - return false; - } - }; -} - -// src/index.ts -function defineSchema(schemaString) { - const schema = parseSchema(schemaString); - const validator = createValidator(schema); - return { - schema, - validator, - parse: (valueString) => parseValue(schema, valueString) - }; -} -// Annotate the CommonJS export names for ESM import in node: -0 && (module.exports = { - ParseError, - createValidator, - defineSchema, - parseSchema, - parseValue -}); diff --git a/dist/index.mjs b/dist/index.mjs deleted file mode 100644 index 19bc3de..0000000 --- a/dist/index.mjs +++ /dev/null @@ -1,377 +0,0 @@ -// src/parser.ts -var ParseError = class extends Error { - constructor(message, position) { - super(position !== void 0 ? `${message} at position ${position}` : message); - this.position = position; - this.name = "ParseError"; - } -}; -var Parser = class { - constructor(input) { - this.pos = 0; - this.input = input; - } - peek() { - return this.input[this.pos] || ""; - } - consume() { - return this.input[this.pos++] || ""; - } - skipWhitespace() { - while (this.pos < this.input.length && /\s/.test(this.input[this.pos])) { - this.pos++; - } - } - match(str) { - return this.input.slice(this.pos, this.pos + str.length) === str; - } - consumeStr(str) { - if (this.match(str)) { - this.pos += str.length; - return true; - } - return false; - } - getPosition() { - return this.pos; - } - getInputLength() { - return this.input.length; - } - parseSchema() { - this.skipWhitespace(); - if (this.consumeStr("string")) { - if (this.consumeStr("[")) { - this.skipWhitespace(); - if (!this.consumeStr("]")) { - throw new ParseError("Expected ]", this.pos); - } - return { type: "array", element: { type: "string" } }; - } - return { type: "string" }; - } - if (this.consumeStr("number")) { - if (this.consumeStr("[")) { - this.skipWhitespace(); - if (!this.consumeStr("]")) { - throw new ParseError("Expected ]", this.pos); - } - return { type: "array", element: { type: "number" } }; - } - return { type: "number" }; - } - if (this.consumeStr("boolean")) { - if (this.consumeStr("[")) { - this.skipWhitespace(); - if (!this.consumeStr("]")) { - throw new ParseError("Expected ]", this.pos); - } - return { type: "array", element: { type: "boolean" } }; - } - return { type: "boolean" }; - } - if (this.consumeStr("[")) { - const elements = []; - this.skipWhitespace(); - if (this.peek() === "]") { - this.consume(); - throw new ParseError("Empty array/tuple not allowed", this.pos); - } - elements.push(this.parseNamedSchema()); - this.skipWhitespace(); - if (this.consumeStr(";")) { - const remainingElements = []; - while (true) { - this.skipWhitespace(); - remainingElements.push(this.parseNamedSchema()); - this.skipWhitespace(); - if (!this.consumeStr(";")) { - break; - } - } - elements.push(...remainingElements); - } - this.skipWhitespace(); - if (!this.consumeStr("]")) { - throw new ParseError("Expected ]", this.pos); - } - if (this.consumeStr("[")) { - this.skipWhitespace(); - if (!this.consumeStr("]")) { - throw new ParseError("Expected ]", this.pos); - } - if (elements.length === 1 && !elements[0].name) { - return { type: "array", element: elements[0].schema }; - } - return { type: "array", element: { type: "tuple", elements } }; - } - if (elements.length === 1 && !elements[0].name) { - return { type: "array", element: elements[0].schema }; - } - return { type: "tuple", elements }; - } - let identifier = ""; - while (this.pos < this.input.length && /[a-zA-Z0-9\-_]/.test(this.peek())) { - identifier += this.consume(); - } - if (identifier.length > 0) { - if (this.consumeStr("[")) { - this.skipWhitespace(); - if (!this.consumeStr("]")) { - throw new ParseError("Expected ]", this.pos); - } - return { type: "array", element: { type: "string" } }; - } - return { type: "string" }; - } - throw new ParseError(`Unexpected character: ${this.peek()}`, this.pos); - } - parseNamedSchema() { - this.skipWhitespace(); - const startpos = this.pos; - let identifier = ""; - while (this.pos < this.input.length && /[a-zA-Z0-9\-_]/.test(this.peek())) { - identifier += this.consume(); - } - if (identifier.length === 0) { - throw new ParseError("Expected schema or named schema", this.pos); - } - this.skipWhitespace(); - if (this.consumeStr(":")) { - this.skipWhitespace(); - const name = identifier; - const schema = this.parseSchema(); - return { name, schema }; - } else { - this.pos = startpos; - const schema = this.parseSchema(); - return { schema }; - } - } -}; -function parseSchema(schemaString) { - const parser = new Parser(schemaString.trim()); - const schema = parser.parseSchema(); - if (parser.getPosition() < parser.getInputLength()) { - throw new ParseError("Unexpected input after schema", parser.getPosition()); - } - return schema; -} - -// src/validator.ts -var ValueParser = class { - constructor(input) { - this.pos = 0; - this.input = input; - } - peek() { - return this.input[this.pos] || ""; - } - consume() { - return this.input[this.pos++] || ""; - } - skipWhitespace() { - while (this.pos < this.input.length && /\s/.test(this.input[this.pos])) { - this.pos++; - } - } - consumeStr(str) { - if (this.input.slice(this.pos, this.pos + str.length) === str) { - this.pos += str.length; - return true; - } - return false; - } - parseValue(schema, allowOmitBrackets = false) { - this.skipWhitespace(); - switch (schema.type) { - case "string": - return this.parseStringValue(); - case "number": - return this.parseNumberValue(); - case "boolean": - return this.parseBooleanValue(); - case "tuple": - return this.parseTupleValue(schema, allowOmitBrackets); - case "array": - return this.parseArrayValue(schema, allowOmitBrackets); - default: - throw new ParseError(`Unknown schema type: ${schema.type}`, this.pos); - } - } - parseStringValue() { - let result = ""; - while (this.pos < this.input.length) { - const char = this.peek(); - if (char === "\\") { - this.consume(); - const nextChar = this.consume(); - if (nextChar === ";" || nextChar === "[" || nextChar === "]" || nextChar === "\\") { - result += nextChar; - } else { - result += "\\" + nextChar; - } - } else if (char === ";" || char === "]") { - break; - } else { - result += this.consume(); - } - } - return result.trim(); - } - parseNumberValue() { - let numStr = ""; - while (this.pos < this.input.length && /[\d.\-+eE]/.test(this.peek())) { - numStr += this.consume(); - } - const num = parseFloat(numStr); - if (isNaN(num)) { - throw new ParseError("Invalid number", this.pos - numStr.length); - } - return num; - } - parseBooleanValue() { - if (this.consumeStr("true")) { - return true; - } - if (this.consumeStr("false")) { - return false; - } - throw new ParseError("Expected true or false", this.pos); - } - parseTupleValue(schema, allowOmitBrackets) { - let hasOpenBracket = false; - if (this.peek() === "[") { - this.consume(); - hasOpenBracket = true; - } else if (!allowOmitBrackets) { - throw new ParseError("Expected [", this.pos); - } - this.skipWhitespace(); - if (this.peek() === "]" && hasOpenBracket) { - this.consume(); - return []; - } - const result = []; - for (let i = 0; i < schema.elements.length; i++) { - this.skipWhitespace(); - const elementSchema = schema.elements[i]; - if (elementSchema.name) { - this.skipWhitespace(); - const savedPos = this.pos; - if (this.consumeStr(`${elementSchema.name}:`)) { - this.skipWhitespace(); - } else { - this.pos = savedPos; - } - } - result.push(this.parseValue(elementSchema.schema, false)); - this.skipWhitespace(); - if (i < schema.elements.length - 1) { - if (!this.consumeStr(";")) { - throw new ParseError("Expected ;", this.pos); - } - } - } - this.skipWhitespace(); - if (hasOpenBracket) { - if (!this.consumeStr("]")) { - throw new ParseError("Expected ]", this.pos); - } - } - return result; - } - parseArrayValue(schema, allowOmitBrackets) { - let hasOpenBracket = false; - const elementIsTupleOrArray = schema.element.type === "tuple" || schema.element.type === "array"; - if (this.peek() === "[") { - if (!elementIsTupleOrArray) { - this.consume(); - hasOpenBracket = true; - } else if (this.input[this.pos + 1] === "[") { - this.consume(); - hasOpenBracket = true; - } - } - if (!hasOpenBracket && !allowOmitBrackets && !elementIsTupleOrArray) { - throw new ParseError("Expected [", this.pos); - } - this.skipWhitespace(); - if (this.peek() === "]" && hasOpenBracket) { - this.consume(); - return []; - } - const result = []; - while (true) { - this.skipWhitespace(); - result.push(this.parseValue(schema.element, false)); - this.skipWhitespace(); - if (!this.consumeStr(";")) { - break; - } - } - this.skipWhitespace(); - if (hasOpenBracket) { - if (!this.consumeStr("]")) { - throw new ParseError("Expected ]", this.pos); - } - } - return result; - } - getPosition() { - return this.pos; - } - getInputLength() { - return this.input.length; - } -}; -function parseValue(schema, valueString) { - const parser = new ValueParser(valueString.trim()); - const allowOmitBrackets = schema.type === "tuple" || schema.type === "array"; - const value = parser.parseValue(schema, allowOmitBrackets); - if (parser.getPosition() < parser.getInputLength()) { - throw new ParseError("Unexpected input after value", parser.getPosition()); - } - return value; -} -function createValidator(schema) { - return function validate(value) { - switch (schema.type) { - case "string": - return typeof value === "string"; - case "number": - return typeof value === "number" && !isNaN(value); - case "boolean": - return typeof value === "boolean"; - case "tuple": - if (!Array.isArray(value)) return false; - if (value.length !== schema.elements.length) return false; - return schema.elements.every( - (elementSchema, index) => createValidator(elementSchema.schema)(value[index]) - ); - case "array": - if (!Array.isArray(value)) return false; - return value.every((item) => createValidator(schema.element)(item)); - default: - return false; - } - }; -} - -// src/index.ts -function defineSchema(schemaString) { - const schema = parseSchema(schemaString); - const validator = createValidator(schema); - return { - schema, - validator, - parse: (valueString) => parseValue(schema, valueString) - }; -} -export { - ParseError, - createValidator, - defineSchema, - parseSchema, - parseValue -};