diff --git a/src/csv-loader/fixtures/enemy_intents.csv b/src/csv-loader/fixtures/enemy_intents.csv new file mode 100644 index 0000000..c1a7cf0 --- /dev/null +++ b/src/csv-loader/fixtures/enemy_intents.csv @@ -0,0 +1,7 @@ +# type IntentEffectTarget = 'user' | 'eachEnemy' | 'randomEnemy' | 'player' +# type IntentEffect = [IntentEffectTarget; string; number] +# type IntentEffects = IntentEffect[] + +id,enemy,initialIntent,nextIntents,brokenIntent,effects +string,string,boolean,string[],string[],IntentEffects +仙人掌怪-boost,仙人掌怪,true,仙人掌怪-boost;仙人掌怪-defend,,[user;spike;1];[user;defend;4] diff --git a/src/csv-loader/tests/parseCsv-combinators.test.ts b/src/csv-loader/tests/parseCsv-combinators.test.ts index 02ca286..062684b 100644 --- a/src/csv-loader/tests/parseCsv-combinators.test.ts +++ b/src/csv-loader/tests/parseCsv-combinators.test.ts @@ -207,4 +207,28 @@ describe("parseCsv - references in combinatory schemas", () => { ], ]); }); + + it("should parse enemy_intents fixture with tuple arrays and type aliases", () => { + const enemyIntentsCsv = readFixture("enemy_intents.csv"); + + const result = parseCsv(enemyIntentsCsv, { + emitTypes: false, + currentFilePath: path.join(fixturesDir, "enemy_intents.csv"), + }); + + expect(result.data).toHaveLength(1); + + expect(result.data[0]).toMatchObject({ + id: "仙人掌怪-boost", + enemy: "仙人掌怪", + initialIntent: true, + nextIntents: ["仙人掌怪-boost", "仙人掌怪-defend"], + brokenIntent: [], + }); + + const effects = result.data[0].effects as unknown[][]; + expect(effects).toHaveLength(2); + expect(effects[0]).toEqual(["user", "spike", 1]); + expect(effects[1]).toEqual(["user", "defend", 4]); + }); }); diff --git a/src/csv-loader/type-declarations.ts b/src/csv-loader/type-declarations.ts index a17e202..731c27e 100644 --- a/src/csv-loader/type-declarations.ts +++ b/src/csv-loader/type-declarations.ts @@ -85,6 +85,14 @@ function expandSchemaInString( return expanded; } + // Handle array suffix: TypeName[] or [tuple][] + const trimmed = schemaString.trim(); + if (trimmed.endsWith("[]")) { + const inner = trimmed.slice(0, -2); + const expandedInner = expandSchemaInString(inner, declaredTypes); + return `${expandedInner}[]`; + } + // Handle union types (recursively expand each member) if (schemaString.includes("|")) { // Split by | but respect quotes