fix: update type generation
This commit is contained in:
parent
6eba70bb3b
commit
852a108c53
|
|
@ -846,15 +846,15 @@ describe('csvToModule - accessor-based output', () => {
|
|||
});
|
||||
|
||||
describe('csvToModule - circular reference support', () => {
|
||||
it('should emit accessor for self-referencing table', () => {
|
||||
it('should emit accessor for self-referencing table without self-import', () => {
|
||||
const csv = readFixture('self_ref.csv');
|
||||
|
||||
const result = csvToModule(csv, { emitTypes: false, currentFilePath: path.join(fixturesDir, 'self_ref.csv') });
|
||||
|
||||
expect(result.js).toContain("import _self_ref from './self_ref.csv'");
|
||||
expect(result.js).not.toContain("import _self_ref from './self_ref.csv'");
|
||||
expect(result.js).toContain('export default function getData()');
|
||||
expect(result.js).toContain('_self_refLookup');
|
||||
expect(result.js).toContain('_resolved = _raw;');
|
||||
expect(result.js).toContain('_self_refLookup = new Map(_raw.map');
|
||||
expect(result.js).toContain('parent: _self_refLookup.get(String(row.parent))');
|
||||
});
|
||||
|
||||
|
|
@ -878,14 +878,14 @@ describe('csvToModule - circular reference support', () => {
|
|||
|
||||
const result = csvToModule(csv, { emitTypes: false, currentFilePath: path.join(fixturesDir, 'self_ref.csv') });
|
||||
|
||||
expect(result.js).toContain("import _self_ref from './self_ref.csv'");
|
||||
expect(result.js).not.toContain("import _self_ref from './self_ref.csv'");
|
||||
expect(result.js).toContain('_self_refLookup');
|
||||
expect(result.js).toContain('export default function getData()');
|
||||
expect(result.js).toContain('parent_info:');
|
||||
expect(result.js).toContain('_self_refLookup.get(String(row.parent_info[0]))');
|
||||
});
|
||||
|
||||
it('should emit accessor for self-referencing table with nested reference in union', () => {
|
||||
it('should emit accessor for self-referencing table with nested reference in union with fallback', () => {
|
||||
const csv = [
|
||||
'id,name,ref_or_val',
|
||||
'string,string,@self_ref | string',
|
||||
|
|
@ -895,10 +895,11 @@ describe('csvToModule - circular reference support', () => {
|
|||
|
||||
const result = csvToModule(csv, { emitTypes: false, currentFilePath: path.join(fixturesDir, 'self_ref.csv') });
|
||||
|
||||
expect(result.js).toContain("import _self_ref from './self_ref.csv'");
|
||||
expect(result.js).not.toContain("import _self_ref from './self_ref.csv'");
|
||||
expect(result.js).toContain('_self_refLookup');
|
||||
expect(result.js).toContain('export default function getData()');
|
||||
expect(result.js).toContain('ref_or_val:');
|
||||
expect(result.js).toContain('_self_refLookup.get(String(row.ref_or_val)) ?? row.ref_or_val');
|
||||
});
|
||||
|
||||
it('should emit accessor for self-referencing table with nested reference array in tuple', () => {
|
||||
|
|
@ -910,20 +911,21 @@ describe('csvToModule - circular reference support', () => {
|
|||
|
||||
const result = csvToModule(csv, { emitTypes: false, currentFilePath: path.join(fixturesDir, 'self_ref.csv') });
|
||||
|
||||
expect(result.js).toContain("import _self_ref from './self_ref.csv'");
|
||||
expect(result.js).not.toContain("import _self_ref from './self_ref.csv'");
|
||||
expect(result.js).toContain('_self_refLookup');
|
||||
expect(result.js).toContain('export default function getData()');
|
||||
expect(result.js).toContain('children:');
|
||||
});
|
||||
|
||||
it('should generate correct type definition for self-referencing table', () => {
|
||||
it('should generate correct type definition for self-referencing table using local singular type', () => {
|
||||
const csv = readFixture('self_ref.csv');
|
||||
|
||||
const result = csvToModule(csv, { emitTypes: true, resourceName: 'nodes', currentFilePath: path.join(fixturesDir, 'self_ref.csv') });
|
||||
|
||||
expect(result.dts).toContain('declare function getData(): nodesTable');
|
||||
expect(result.dts).toContain('Self_ref');
|
||||
expect(result.dts).toContain("import type { Self_ref } from './self_ref.csv'");
|
||||
expect(result.dts).toContain('readonly parent: Nodes');
|
||||
expect(result.dts).not.toContain("import type { Self_ref } from './self_ref.csv'");
|
||||
expect(result.dts).not.toContain('Self_ref');
|
||||
});
|
||||
|
||||
it('should emit accessor for cross-referencing tables with array references', () => {
|
||||
|
|
@ -950,4 +952,17 @@ describe('csvToModule - circular reference support', () => {
|
|||
expect(result.js).toContain('_circular_bLookup');
|
||||
expect(result.js).toContain('export default function getData()');
|
||||
});
|
||||
|
||||
it('should generate union fallback with ?? for non-reference union members', () => {
|
||||
const csv = [
|
||||
'id,value',
|
||||
'string,@users | string',
|
||||
'1,1',
|
||||
'2,unknown',
|
||||
].join('\n');
|
||||
|
||||
const result = csvToModule(csv, { emitTypes: false });
|
||||
|
||||
expect(result.js).toContain('?? row.value');
|
||||
});
|
||||
});
|
||||
|
|
@ -538,12 +538,22 @@ function generateTypeDefinition(
|
|||
hasRefs?: boolean
|
||||
): string {
|
||||
const typeName = resourceName ? `${resourceName}Table` : 'Table';
|
||||
const currentTableName = currentFilePath
|
||||
? path.basename(currentFilePath, path.extname(currentFilePath))
|
||||
: undefined;
|
||||
const singularType = resourceName
|
||||
? resourceName.charAt(0).toUpperCase() + resourceName.slice(1)
|
||||
: `${typeName}[number]`;
|
||||
|
||||
// Generate import statements for referenced tables
|
||||
const imports: string[] = [];
|
||||
const resourceNames = new Map<string, string>();
|
||||
|
||||
references.forEach(tableName => {
|
||||
if (tableName === currentTableName) {
|
||||
resourceNames.set(tableName, singularType);
|
||||
return;
|
||||
}
|
||||
// Convert table name to type name by capitalizing
|
||||
const typeBase = tableName.charAt(0).toUpperCase() + tableName.slice(1);
|
||||
resourceNames.set(tableName, typeBase);
|
||||
|
|
@ -551,10 +561,8 @@ function generateTypeDefinition(
|
|||
// Generate import path based on current file path
|
||||
let importPath: string;
|
||||
if (currentFilePath) {
|
||||
// Both files are in the same directory, use relative path
|
||||
importPath = `./${tableName}.csv`;
|
||||
} else {
|
||||
// Fallback for unknown path
|
||||
importPath = `../${tableName}.csv`;
|
||||
}
|
||||
imports.push(`import type { ${typeBase} } from '${importPath}';`);
|
||||
|
|
@ -793,15 +801,17 @@ function generateSchemaResolutionCode(
|
|||
case 'union': {
|
||||
const refMembers = schema.members.filter(m => hasNestedReferences(m));
|
||||
const nonRefMembers = schema.members.filter(m => !hasNestedReferences(m));
|
||||
const parts: string[] = [];
|
||||
const resolveParts: string[] = [];
|
||||
for (const member of refMembers) {
|
||||
const resolveCode = generateSchemaResolutionCode(member, valueExpr, lookupVar, pkField);
|
||||
parts.push(resolveCode);
|
||||
resolveParts.push(resolveCode);
|
||||
}
|
||||
if (nonRefMembers.length > 0) {
|
||||
parts.push(valueExpr);
|
||||
resolveParts.push(valueExpr);
|
||||
}
|
||||
return parts[0] || valueExpr;
|
||||
if (resolveParts.length === 0) return valueExpr;
|
||||
if (resolveParts.length === 1) return resolveParts[0];
|
||||
return `(${resolveParts.join(' ?? ')})`;
|
||||
}
|
||||
default:
|
||||
return valueExpr;
|
||||
|
|
@ -834,14 +844,26 @@ export function csvToModule(
|
|||
const lookupInits: string[] = [];
|
||||
const lookupVarMap = new Map<string, string>();
|
||||
|
||||
const currentTableName = options.currentFilePath
|
||||
? path.basename(options.currentFilePath, path.extname(options.currentFilePath))
|
||||
: undefined;
|
||||
|
||||
const uniqueTables = new Set(result.referenceFields.map(f => f.tableName));
|
||||
uniqueTables.forEach(tableName => {
|
||||
const varName = `_${tableName}`;
|
||||
lookupVarMap.set(tableName, `_${tableName}Lookup`);
|
||||
imports.push(`import ${varName} from './${tableName}.csv';`);
|
||||
lookupInits.push(
|
||||
`const _${tableName}Lookup = new Map(${varName}().map(p => [String(p.${defaultPrimaryKey}), p]));`
|
||||
);
|
||||
const lookupVar = `_${tableName}Lookup`;
|
||||
lookupVarMap.set(tableName, lookupVar);
|
||||
|
||||
if (tableName === currentTableName) {
|
||||
lookupInits.push(
|
||||
`const ${lookupVar} = new Map(_raw.map(p => [String(p.${defaultPrimaryKey}), p]));`
|
||||
);
|
||||
} else {
|
||||
const varName = `_${tableName}`;
|
||||
imports.push(`import ${varName} from './${tableName}.csv';`);
|
||||
lookupInits.push(
|
||||
`const ${lookupVar} = new Map(${varName}().map(p => [String(p.${defaultPrimaryKey}), p]));`
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
const lookupVar = (tableName: string) => lookupVarMap.get(tableName)!;
|
||||
|
|
|
|||
Loading…
Reference in New Issue