Compare commits

..

No commits in common. "16d88d610827b5df7f77d7bc22f66b0a8a802dd7" and "cf55295ce79a2dcf3114e2910cc6a28ce872be90" have entirely different histories.

6 changed files with 58 additions and 233 deletions

View File

@ -14,41 +14,6 @@ interface CsvLoaderOptions {
/** Write .d.ts files to disk (useful for dev server) */ /** Write .d.ts files to disk (useful for dev server) */
writeToDisk?: boolean; writeToDisk?: boolean;
} }
interface CsvParseResult {
/** Parsed CSV data as array of objects */
data: Record<string, unknown>[];
/** Generated TypeScript type definition string (if emitTypes is true) */
typeDefinition?: string;
/** Property configurations for the CSV columns */
propertyConfigs: PropertyConfig[];
}
interface PropertyConfig {
name: string;
schema: any;
validator: (value: unknown) => boolean;
parser: (valueString: string) => unknown;
}
/**
* Parse CSV content string into structured data with schema validation.
* This is a standalone function that doesn't depend on webpack/rspack LoaderContext.
*
* @param content - CSV content string (must have at least headers + schema row + 1 data row)
* @param options - Parsing options
* @returns CsvParseResult containing parsed data and optional type definitions
*/
declare function parseCsv(content: string, options?: CsvLoaderOptions): CsvParseResult;
/**
* Generate JavaScript module code from CSV content.
* Returns a string that can be used as a module export.
*
* @param content - CSV content string
* @param options - Parsing options
* @returns JavaScript module code string
*/
declare function csvToModule(content: string, options?: CsvLoaderOptions): {
js: string;
dts?: string;
};
declare function csvLoader(this: LoaderContext<CsvLoaderOptions>, content: string): string | Buffer; declare function csvLoader(this: LoaderContext<CsvLoaderOptions>, content: string): string | Buffer;
export { type CsvLoaderOptions, type CsvParseResult, csvToModule, csvLoader as default, parseCsv }; export { type CsvLoaderOptions, csvLoader as default };

View File

@ -14,41 +14,6 @@ interface CsvLoaderOptions {
/** Write .d.ts files to disk (useful for dev server) */ /** Write .d.ts files to disk (useful for dev server) */
writeToDisk?: boolean; writeToDisk?: boolean;
} }
interface CsvParseResult {
/** Parsed CSV data as array of objects */
data: Record<string, unknown>[];
/** Generated TypeScript type definition string (if emitTypes is true) */
typeDefinition?: string;
/** Property configurations for the CSV columns */
propertyConfigs: PropertyConfig[];
}
interface PropertyConfig {
name: string;
schema: any;
validator: (value: unknown) => boolean;
parser: (valueString: string) => unknown;
}
/**
* Parse CSV content string into structured data with schema validation.
* This is a standalone function that doesn't depend on webpack/rspack LoaderContext.
*
* @param content - CSV content string (must have at least headers + schema row + 1 data row)
* @param options - Parsing options
* @returns CsvParseResult containing parsed data and optional type definitions
*/
declare function parseCsv(content: string, options?: CsvLoaderOptions): CsvParseResult;
/**
* Generate JavaScript module code from CSV content.
* Returns a string that can be used as a module export.
*
* @param content - CSV content string
* @param options - Parsing options
* @returns JavaScript module code string
*/
declare function csvToModule(content: string, options?: CsvLoaderOptions): {
js: string;
dts?: string;
};
declare function csvLoader(this: LoaderContext<CsvLoaderOptions>, content: string): string | Buffer; declare function csvLoader(this: LoaderContext<CsvLoaderOptions>, content: string): string | Buffer;
export { type CsvLoaderOptions, type CsvParseResult, csvToModule, csvLoader as default, parseCsv }; export { type CsvLoaderOptions, csvLoader as default };

View File

@ -30,9 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
// src/csv-loader/loader.ts // src/csv-loader/loader.ts
var loader_exports = {}; var loader_exports = {};
__export(loader_exports, { __export(loader_exports, {
csvToModule: () => csvToModule, default: () => csvLoader
default: () => csvLoader,
parseCsv: () => parseCsv
}); });
module.exports = __toCommonJS(loader_exports); module.exports = __toCommonJS(loader_exports);
var import_sync = require("csv-parse/sync"); var import_sync = require("csv-parse/sync");
@ -437,14 +435,17 @@ declare const data: Table;
export default data; export default data;
`; `;
} }
function parseCsv(content, options = {}) { function csvLoader(content) {
const delimiter = options.delimiter ?? ","; const options = this.getOptions();
const quote = options.quote ?? '"'; const delimiter = options?.delimiter ?? ",";
const escape = options.escape ?? "\\"; const quote = options?.quote ?? '"';
const bom = options.bom ?? true; const escape = options?.escape ?? "\\";
const comment = options.comment === false ? void 0 : options.comment ?? "#"; const bom = options?.bom ?? true;
const trim = options.trim ?? true; const comment = options?.comment === false ? void 0 : options?.comment ?? "#";
const emitTypes = options.emitTypes ?? true; 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, { const records = (0, import_sync.parse)(content, {
delimiter, delimiter,
quote, quote,
@ -498,31 +499,8 @@ function parseCsv(content, options = {}) {
}); });
return obj; return obj;
}); });
const result = { const json = JSON.stringify(objects, null, 2);
data: objects,
propertyConfigs
};
if (emitTypes) { if (emitTypes) {
result.typeDefinition = generateTypeDefinition("", propertyConfigs);
}
return result;
}
function csvToModule(content, options = {}) {
const result = parseCsv(content, options);
const json = JSON.stringify(result.data, null, 2);
const js = `export default ${json};`;
return {
js,
dts: result.typeDefinition
};
}
function csvLoader(content) {
const options = this.getOptions();
const emitTypes = options?.emitTypes ?? true;
const typesOutputDir = options?.typesOutputDir ?? "";
const writeToDisk = options?.writeToDisk ?? false;
const result = parseCsv(content, options);
if (emitTypes && result.typeDefinition) {
const context = this.context || ""; const context = this.context || "";
let relativePath = this.resourcePath.replace(context, ""); let relativePath = this.resourcePath.replace(context, "");
if (relativePath.startsWith("\\") || relativePath.startsWith("/")) { if (relativePath.startsWith("\\") || relativePath.startsWith("/")) {
@ -531,18 +509,14 @@ function csvLoader(content) {
relativePath = relativePath.replace(/\\/g, "/"); relativePath = relativePath.replace(/\\/g, "/");
const dtsFileName = `${relativePath}.d.ts`; const dtsFileName = `${relativePath}.d.ts`;
const outputPath = typesOutputDir ? path.join(typesOutputDir, dtsFileName) : dtsFileName; const outputPath = typesOutputDir ? path.join(typesOutputDir, dtsFileName) : dtsFileName;
const dtsContent = generateTypeDefinition(this.resourcePath, propertyConfigs);
if (writeToDisk) { if (writeToDisk) {
const absolutePath = path.join(this.context || process.cwd(), typesOutputDir || "", dtsFileName); const absolutePath = path.join(this.context || process.cwd(), typesOutputDir || "", dtsFileName);
fs.mkdirSync(path.dirname(absolutePath), { recursive: true }); fs.mkdirSync(path.dirname(absolutePath), { recursive: true });
fs.writeFileSync(absolutePath, result.typeDefinition); fs.writeFileSync(absolutePath, dtsContent);
} else { } else {
this.emitFile?.(outputPath, result.typeDefinition); this.emitFile?.(outputPath, dtsContent);
} }
} }
return `export default ${JSON.stringify(result.data, null, 2)};`; return `export default ${json};`;
} }
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
csvToModule,
parseCsv
});

View File

@ -401,14 +401,17 @@ declare const data: Table;
export default data; export default data;
`; `;
} }
function parseCsv(content, options = {}) { function csvLoader(content) {
const delimiter = options.delimiter ?? ","; const options = this.getOptions();
const quote = options.quote ?? '"'; const delimiter = options?.delimiter ?? ",";
const escape = options.escape ?? "\\"; const quote = options?.quote ?? '"';
const bom = options.bom ?? true; const escape = options?.escape ?? "\\";
const comment = options.comment === false ? void 0 : options.comment ?? "#"; const bom = options?.bom ?? true;
const trim = options.trim ?? true; const comment = options?.comment === false ? void 0 : options?.comment ?? "#";
const emitTypes = options.emitTypes ?? true; const trim = options?.trim ?? true;
const emitTypes = options?.emitTypes ?? true;
const typesOutputDir = options?.typesOutputDir ?? "";
const writeToDisk = options?.writeToDisk ?? false;
const records = parse(content, { const records = parse(content, {
delimiter, delimiter,
quote, quote,
@ -462,31 +465,8 @@ function parseCsv(content, options = {}) {
}); });
return obj; return obj;
}); });
const result = { const json = JSON.stringify(objects, null, 2);
data: objects,
propertyConfigs
};
if (emitTypes) { if (emitTypes) {
result.typeDefinition = generateTypeDefinition("", propertyConfigs);
}
return result;
}
function csvToModule(content, options = {}) {
const result = parseCsv(content, options);
const json = JSON.stringify(result.data, null, 2);
const js = `export default ${json};`;
return {
js,
dts: result.typeDefinition
};
}
function csvLoader(content) {
const options = this.getOptions();
const emitTypes = options?.emitTypes ?? true;
const typesOutputDir = options?.typesOutputDir ?? "";
const writeToDisk = options?.writeToDisk ?? false;
const result = parseCsv(content, options);
if (emitTypes && result.typeDefinition) {
const context = this.context || ""; const context = this.context || "";
let relativePath = this.resourcePath.replace(context, ""); let relativePath = this.resourcePath.replace(context, "");
if (relativePath.startsWith("\\") || relativePath.startsWith("/")) { if (relativePath.startsWith("\\") || relativePath.startsWith("/")) {
@ -495,18 +475,17 @@ function csvLoader(content) {
relativePath = relativePath.replace(/\\/g, "/"); relativePath = relativePath.replace(/\\/g, "/");
const dtsFileName = `${relativePath}.d.ts`; const dtsFileName = `${relativePath}.d.ts`;
const outputPath = typesOutputDir ? path.join(typesOutputDir, dtsFileName) : dtsFileName; const outputPath = typesOutputDir ? path.join(typesOutputDir, dtsFileName) : dtsFileName;
const dtsContent = generateTypeDefinition(this.resourcePath, propertyConfigs);
if (writeToDisk) { if (writeToDisk) {
const absolutePath = path.join(this.context || process.cwd(), typesOutputDir || "", dtsFileName); const absolutePath = path.join(this.context || process.cwd(), typesOutputDir || "", dtsFileName);
fs.mkdirSync(path.dirname(absolutePath), { recursive: true }); fs.mkdirSync(path.dirname(absolutePath), { recursive: true });
fs.writeFileSync(absolutePath, result.typeDefinition); fs.writeFileSync(absolutePath, dtsContent);
} else { } else {
this.emitFile?.(outputPath, result.typeDefinition); this.emitFile?.(outputPath, dtsContent);
} }
} }
return `export default ${JSON.stringify(result.data, null, 2)};`; return `export default ${json};`;
} }
export { export {
csvToModule, csvLoader as default
csvLoader as default,
parseCsv
}; };

View File

@ -20,15 +20,6 @@ export interface CsvLoaderOptions {
writeToDisk?: boolean; writeToDisk?: boolean;
} }
export interface CsvParseResult {
/** Parsed CSV data as array of objects */
data: Record<string, unknown>[];
/** Generated TypeScript type definition string (if emitTypes is true) */
typeDefinition?: string;
/** Property configurations for the CSV columns */
propertyConfigs: PropertyConfig[];
}
interface PropertyConfig { interface PropertyConfig {
name: string; name: string;
schema: any; schema: any;
@ -87,25 +78,20 @@ export default data;
`; `;
} }
/** export default function csvLoader(
* Parse CSV content string into structured data with schema validation. this: LoaderContext<CsvLoaderOptions>,
* This is a standalone function that doesn't depend on webpack/rspack LoaderContext. content: string
* ): string | Buffer {
* @param content - CSV content string (must have at least headers + schema row + 1 data row) const options = this.getOptions() as CsvLoaderOptions | undefined;
* @param options - Parsing options const delimiter = options?.delimiter ?? ',';
* @returns CsvParseResult containing parsed data and optional type definitions const quote = options?.quote ?? '"';
*/ const escape = options?.escape ?? '\\';
export function parseCsv( const bom = options?.bom ?? true;
content: string, const comment = options?.comment === false ? undefined : (options?.comment ?? '#');
options: CsvLoaderOptions = {} const trim = options?.trim ?? true;
): CsvParseResult { const emitTypes = options?.emitTypes ?? true;
const delimiter = options.delimiter ?? ','; const typesOutputDir = options?.typesOutputDir ?? '';
const quote = options.quote ?? '"'; const writeToDisk = options?.writeToDisk ?? false;
const escape = options.escape ?? '\\';
const bom = options.bom ?? true;
const comment = options.comment === false ? undefined : (options.comment ?? '#');
const trim = options.trim ?? true;
const emitTypes = options.emitTypes ?? true;
const records = parse(content, { const records = parse(content, {
delimiter, delimiter,
@ -166,54 +152,10 @@ export function parseCsv(
return obj; return obj;
}); });
const result: CsvParseResult = { const json = JSON.stringify(objects, null, 2);
data: objects,
propertyConfigs,
};
if (emitTypes) {
result.typeDefinition = generateTypeDefinition('', propertyConfigs);
}
return result;
}
/**
* Generate JavaScript module code from CSV content.
* Returns a string that can be used as a module export.
*
* @param content - CSV content string
* @param options - Parsing options
* @returns JavaScript module code string
*/
export function csvToModule(
content: string,
options: CsvLoaderOptions = {}
): { js: string; dts?: string } {
const result = parseCsv(content, options);
const json = JSON.stringify(result.data, null, 2);
const js = `export default ${json};`;
return {
js,
dts: result.typeDefinition,
};
}
export default function csvLoader(
this: LoaderContext<CsvLoaderOptions>,
content: string
): string | Buffer {
const options = this.getOptions() as CsvLoaderOptions | undefined;
const emitTypes = options?.emitTypes ?? true;
const typesOutputDir = options?.typesOutputDir ?? '';
const writeToDisk = options?.writeToDisk ?? false;
const result = parseCsv(content, options);
// Emit type definition file if enabled // Emit type definition file if enabled
if (emitTypes && result.typeDefinition) { if (emitTypes) {
const context = this.context || ''; const context = this.context || '';
// Get relative path from context, normalize to forward slashes // Get relative path from context, normalize to forward slashes
let relativePath = this.resourcePath.replace(context, ''); let relativePath = this.resourcePath.replace(context, '');
@ -227,17 +169,18 @@ export default function csvLoader(
const outputPath = typesOutputDir const outputPath = typesOutputDir
? path.join(typesOutputDir, dtsFileName) ? path.join(typesOutputDir, dtsFileName)
: dtsFileName; : dtsFileName;
const dtsContent = generateTypeDefinition(this.resourcePath, propertyConfigs);
if (writeToDisk) { if (writeToDisk) {
// Write directly to disk (useful for dev server) // Write directly to disk (useful for dev server)
const absolutePath = path.join(this.context || process.cwd(), typesOutputDir || '', dtsFileName); const absolutePath = path.join(this.context || process.cwd(), typesOutputDir || '', dtsFileName);
fs.mkdirSync(path.dirname(absolutePath), { recursive: true }); fs.mkdirSync(path.dirname(absolutePath), { recursive: true });
fs.writeFileSync(absolutePath, result.typeDefinition); fs.writeFileSync(absolutePath, dtsContent);
} else { } else {
// Emit to in-memory filesystem (for production build) // Emit to in-memory filesystem (for production build)
this.emitFile?.(outputPath, result.typeDefinition); this.emitFile?.(outputPath, dtsContent);
} }
} }
return `export default ${JSON.stringify(result.data, null, 2)};`; return `export default ${json};`;
} }

View File

@ -12,9 +12,8 @@
"declarationMap": true, "declarationMap": true,
"sourceMap": true, "sourceMap": true,
"outDir": "./dist", "outDir": "./dist",
"rootDir": "./src", "rootDir": "./src"
"types": ["node"]
}, },
"include": ["src/**/*"], "include": ["src/**/*"],
"exclude": ["node_modules", "dist"] "exclude": ["node_modules", "dist", "src/csv-loader"]
} }