Compare commits
No commits in common. "e0317946d5262c434ea65b3662389aaebd2ac048" and "f101c1209715fcf399561d0dbf8d3751071e6bd7" have entirely different histories.
e0317946d5
...
f101c12097
|
|
@ -160,11 +160,7 @@ export function parseCsv(
|
|||
}
|
||||
|
||||
// Parse type declarations with expansion of type name references
|
||||
const typeDeclarationsParsed: {
|
||||
name: string;
|
||||
schema: Schema;
|
||||
schemaString: string;
|
||||
}[] = [];
|
||||
const typeDeclarationsParsed: { name: string; schema: Schema }[] = [];
|
||||
for (const decl of typeDeclarationsRaw) {
|
||||
// Expand any type name references before parsing
|
||||
const expandedSchema = expandSchemaString(
|
||||
|
|
@ -172,11 +168,7 @@ export function parseCsv(
|
|||
declaredSchemaStrings,
|
||||
);
|
||||
const schema = parseSchema(expandedSchema.trim());
|
||||
typeDeclarationsParsed.push({
|
||||
name: decl.typeName,
|
||||
schema,
|
||||
schemaString: decl.schemaString,
|
||||
});
|
||||
typeDeclarationsParsed.push({ name: decl.typeName, schema });
|
||||
}
|
||||
|
||||
// Build declared types map
|
||||
|
|
@ -189,11 +181,7 @@ export function parseCsv(
|
|||
const typeDeclarations: TypeDeclaration[] = [];
|
||||
for (const decl of typeDeclarationsParsed) {
|
||||
const resolvedSchema = resolveTypeReferences(decl.schema, declaredTypes);
|
||||
typeDeclarations.push({
|
||||
name: decl.name,
|
||||
schema: resolvedSchema,
|
||||
schemaString: decl.schemaString,
|
||||
});
|
||||
typeDeclarations.push({ name: decl.name, schema: resolvedSchema });
|
||||
}
|
||||
|
||||
// Update declaredTypes with resolved schemas for column schema lookup
|
||||
|
|
@ -209,21 +197,11 @@ export function parseCsv(
|
|||
// Check if schema string matches a declared type name
|
||||
let schema: Schema;
|
||||
let declaredTypeName: string | undefined;
|
||||
let columnSchemaString: string | undefined;
|
||||
if (declaredTypes.has(schemaString)) {
|
||||
schema = declaredTypes.get(schemaString)!;
|
||||
declaredTypeName = schemaString;
|
||||
} else {
|
||||
// Expand any custom type name references before parsing
|
||||
const expandedSchema = expandSchemaString(
|
||||
schemaString,
|
||||
declaredSchemaStrings,
|
||||
);
|
||||
schema = parseSchema(expandedSchema.trim());
|
||||
// Only preserve the original schema string if expansion actually changed it
|
||||
if (expandedSchema !== schemaString) {
|
||||
columnSchemaString = schemaString;
|
||||
}
|
||||
schema = parseSchema(schemaString);
|
||||
}
|
||||
|
||||
const config: PropertyConfig = {
|
||||
|
|
@ -232,7 +210,6 @@ export function parseCsv(
|
|||
validator: createValidator(schema),
|
||||
parser: (valueString: string) => parseValue(schema, valueString),
|
||||
declaredTypeName,
|
||||
schemaString: columnSchemaString,
|
||||
};
|
||||
|
||||
if (schema.type === "reference") {
|
||||
|
|
|
|||
|
|
@ -56,9 +56,9 @@ describe("parseCsv - type declarations", () => {
|
|||
currentFilePath: path.join(fixturesDir, "card.csv"),
|
||||
});
|
||||
|
||||
expect(result.typeDefinition).toContain("export type Trigger =");
|
||||
expect(result.typeDefinition).toContain("type Trigger =");
|
||||
expect(result.typeDefinition).toContain(
|
||||
"'onPlay' | 'onDraw' | 'onDiscard'",
|
||||
'"onPlay" | "onDraw" | "onDiscard"',
|
||||
);
|
||||
});
|
||||
|
||||
|
|
@ -93,8 +93,8 @@ describe("parseCsv - type declarations", () => {
|
|||
currentFilePath: path.join(fixturesDir, "card.csv"),
|
||||
});
|
||||
|
||||
expect(result.typeDefinition).toContain("export type Trigger =");
|
||||
expect(result.typeDefinition).toContain("export type Status =");
|
||||
expect(result.typeDefinition).toContain("type Trigger =");
|
||||
expect(result.typeDefinition).toContain("type Status =");
|
||||
});
|
||||
|
||||
it("should ignore comment lines that are not type declarations", () => {
|
||||
|
|
@ -196,96 +196,11 @@ describe("parseCsv - type declarations", () => {
|
|||
});
|
||||
|
||||
// Both type declarations should appear
|
||||
expect(result.typeDefinition).toContain("export type Trigger =");
|
||||
expect(result.typeDefinition).toContain("export type Effect =");
|
||||
expect(result.typeDefinition).toContain("type Trigger =");
|
||||
expect(result.typeDefinition).toContain("type Effect =");
|
||||
// Column should use the declared type name, not expanded union
|
||||
expect(result.typeDefinition).toContain("readonly trigger: Trigger;");
|
||||
});
|
||||
|
||||
it("should expand custom type names inside tuples and arrays", () => {
|
||||
const csv = [
|
||||
"# type IntentEffectTarget = 'user' | 'eachEnemy' | 'randomEnemy' | 'player'",
|
||||
"# type IntentEffect = [IntentEffectTarget; string; int]",
|
||||
"# type IntentEffects = IntentEffect[]",
|
||||
"id,effects",
|
||||
"string,IntentEffects",
|
||||
"boost,[user;spike;1];[user;defend;4]",
|
||||
].join("\n");
|
||||
|
||||
const result = parseCsv(csv, { emitTypes: false });
|
||||
|
||||
expect(result.typeDeclarations).toHaveLength(3);
|
||||
const intentEffect = result.typeDeclarations.find(
|
||||
(d) => d.name === "IntentEffect",
|
||||
)!;
|
||||
expect(intentEffect.schema.type).toBe("tuple");
|
||||
// First element should be resolved to union, not a string "IntentEffectTarget"
|
||||
const firstEl = (
|
||||
intentEffect.schema as { elements: { schema: { type: string } }[] }
|
||||
).elements[0].schema;
|
||||
expect(firstEl.type).toBe("union");
|
||||
});
|
||||
|
||||
it("should use declared type names in generated type definition for tuple arrays", () => {
|
||||
const csv = [
|
||||
"# type IntentEffectTarget = 'user' | 'eachEnemy' | 'randomEnemy' | 'player'",
|
||||
"# type IntentEffect = [IntentEffectTarget; string; int]",
|
||||
"# type IntentEffects = IntentEffect[]",
|
||||
"id,effects",
|
||||
"string,IntentEffects",
|
||||
"boost,[user;spike;1];[user;defend;4]",
|
||||
].join("\n");
|
||||
|
||||
const result = parseCsv(csv, {
|
||||
emitTypes: true,
|
||||
resourceName: "intent",
|
||||
currentFilePath: path.join(fixturesDir, "intent.csv"),
|
||||
});
|
||||
|
||||
expect(result.typeDefinition).toContain("export type IntentEffectTarget =");
|
||||
expect(result.typeDefinition).toContain("export type IntentEffect =");
|
||||
expect(result.typeDefinition).toContain("export type IntentEffects =");
|
||||
// IntentEffect should reference IntentEffectTarget, not expand it
|
||||
expect(result.typeDefinition).toContain(
|
||||
"[IntentEffectTarget; string; int]",
|
||||
);
|
||||
// IntentEffects should reference IntentEffect, not expand it
|
||||
expect(result.typeDefinition).toContain("IntentEffect[]");
|
||||
// Column should reference IntentEffects, not inline expansion
|
||||
expect(result.typeDefinition).toContain("readonly effects: IntentEffects;");
|
||||
});
|
||||
|
||||
it("should handle custom type inside a tuple used as an array element", () => {
|
||||
const csv = [
|
||||
'# type Type = "apple" | "orange"',
|
||||
"id,items",
|
||||
"string,[Type; int][]",
|
||||
"001,[apple;2];[orange;3]",
|
||||
].join("\n");
|
||||
|
||||
const result = parseCsv(csv, { emitTypes: false });
|
||||
|
||||
expect(result.data).toHaveLength(1);
|
||||
expect(result.data[0]).toEqual({
|
||||
id: "001",
|
||||
items: [
|
||||
["apple", 2],
|
||||
["orange", 3],
|
||||
],
|
||||
});
|
||||
|
||||
const typeResult = parseCsv(csv, {
|
||||
emitTypes: true,
|
||||
resourceName: "item",
|
||||
currentFilePath: path.join(fixturesDir, "item.csv"),
|
||||
});
|
||||
|
||||
expect(typeResult.typeDefinition).toContain("export type Type =");
|
||||
expect(typeResult.typeDefinition).toContain("[Type; int][]");
|
||||
expect(typeResult.typeDefinition).toContain(
|
||||
"readonly items: [Type; int][];",
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("parseCsv - type declarations with resolveReferences: false", () => {
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ export function generateTypeDefinition(
|
|||
? typeDeclarations
|
||||
.map(
|
||||
(decl) =>
|
||||
`export type ${decl.name} = ${decl.schemaString ?? schemaToTypeString(decl.schema, resourceNames)};`,
|
||||
`export type ${decl.name} = ${schemaToTypeString(decl.schema, resourceNames)};`,
|
||||
)
|
||||
.join("\n") + "\n\n"
|
||||
: "";
|
||||
|
|
@ -60,8 +60,7 @@ export function generateTypeDefinition(
|
|||
.map((config) => {
|
||||
const typeStr = config.declaredTypeName
|
||||
? config.declaredTypeName
|
||||
: (config.schemaString ??
|
||||
schemaToTypeString(config.schema, resourceNames));
|
||||
: schemaToTypeString(config.schema, resourceNames);
|
||||
return ` readonly ${config.name}: ${typeStr};`;
|
||||
})
|
||||
.join("\n");
|
||||
|
|
|
|||
|
|
@ -78,8 +78,6 @@ export interface PropertyConfig {
|
|||
reverseReferenceForeignKey?: string;
|
||||
/** When a column uses a declared type name, this stores that name */
|
||||
declaredTypeName?: string;
|
||||
/** The original schema string for the column (preserves type name references for output) */
|
||||
schemaString?: string;
|
||||
}
|
||||
|
||||
/** Parsed reverse reference declaration from a comment line */
|
||||
|
|
@ -100,8 +98,6 @@ export interface ReverseReferenceDeclaration {
|
|||
export interface TypeDeclaration {
|
||||
/** Name of the type being defined */
|
||||
name: string;
|
||||
/** The original schema string (preserves type name references for output) */
|
||||
schemaString: string;
|
||||
/** The parsed schema for this type */
|
||||
schema: Schema;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue