[TS] Fix relative paths for exports (#8517)

Fixes an issue where exports were using incorrect relative paths for
>=3 namespace levels. This is fixed by making the starting range of the
namespace components relative to the amount of components.

Co-authored-by: Björn Harrtell <bjornharrtell@users.noreply.github.com>
This commit is contained in:
Truman Mulholland
2025-07-02 03:38:02 +12:00
committed by GitHub
parent b8db3a9a6a
commit 00eec2445b
13 changed files with 255 additions and 11 deletions

View File

@@ -263,14 +263,9 @@ class TsGenerator : public BaseGenerator {
for (const auto &def : it.second.definitions) {
std::vector<std::string> rel_components;
// build path for root level vs child level
if (it.second.ns->components.size() > 1)
std::copy(it.second.ns->components.begin() + 1,
it.second.ns->components.end(),
std::back_inserter(rel_components));
else
std::copy(it.second.ns->components.begin(),
it.second.ns->components.end(),
std::back_inserter(rel_components));
if (it.second.ns->components.size() > 0) {
rel_components.push_back(it.second.ns->components.back());
}
auto base_file_name =
namer_.File(*(def.second), SkipFile::SuffixAndExtension);
auto base_name =
@@ -303,8 +298,12 @@ class TsGenerator : public BaseGenerator {
if (it2.second.ns->components.size() != child_ns_level) continue;
auto ts_file_path = it2.second.path + ".ts";
code += "export * as " + it2.second.symbolic_name + " from './";
std::string rel_path = it2.second.path;
code += rel_path + ".js';\n";
int count = it2.second.ns->components.size() > 1 ? 2 : 1;
std::vector<std::string> rel_path;
std::copy(it2.second.ns->components.end() - count,
it2.second.ns->components.end(),
std::back_inserter(rel_path));
code += namer_.Directories(rel_path, SkipDir::OutputPathAndTrailingPathSeparator) + ".js';\n";
export_counter++;
}

7
tests/long_namespace.fbs Normal file
View File

@@ -0,0 +1,7 @@
namespace com.company.test;
table Person {
name:string;
age:short;
}
root_type Person;

View File

@@ -0,0 +1,7 @@
namespace longer_namespace.a.b.c;
table Person {
name:string;
age:short;
}
root_type Person;

View File

@@ -122,6 +122,9 @@ flatc(
schema="../union_underlying_type_test.fbs"
)
flatc(options=["--ts"], schema="../long_namespace.fbs")
flatc(options=["--ts"], schema="../longer_namespace.fbs")
print("Running TypeScript Compiler...")
check_call(["tsc"])
print("Running TypeScript Compiler in old node resolution mode for no_import_ext...")

View File

@@ -0,0 +1,5 @@
// automatically generated by the FlatBuffers compiler, do not modify
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
export { Person } from './test/person.js';

View File

@@ -0,0 +1,70 @@
// automatically generated by the FlatBuffers compiler, do not modify
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
import * as flatbuffers from 'flatbuffers';
export class Person {
bb: flatbuffers.ByteBuffer|null = null;
bb_pos = 0;
__init(i:number, bb:flatbuffers.ByteBuffer):Person {
this.bb_pos = i;
this.bb = bb;
return this;
}
static getRootAsPerson(bb:flatbuffers.ByteBuffer, obj?:Person):Person {
return (obj || new Person()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
static getSizePrefixedRootAsPerson(bb:flatbuffers.ByteBuffer, obj?:Person):Person {
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
return (obj || new Person()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
name():string|null
name(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
name(optionalEncoding?:any):string|Uint8Array|null {
const offset = this.bb!.__offset(this.bb_pos, 4);
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
}
age():number {
const offset = this.bb!.__offset(this.bb_pos, 6);
return offset ? this.bb!.readInt16(this.bb_pos + offset) : 0;
}
static startPerson(builder:flatbuffers.Builder) {
builder.startObject(2);
}
static addName(builder:flatbuffers.Builder, nameOffset:flatbuffers.Offset) {
builder.addFieldOffset(0, nameOffset, 0);
}
static addAge(builder:flatbuffers.Builder, age:number) {
builder.addFieldInt16(1, age, 0);
}
static endPerson(builder:flatbuffers.Builder):flatbuffers.Offset {
const offset = builder.endObject();
return offset;
}
static finishPersonBuffer(builder:flatbuffers.Builder, offset:flatbuffers.Offset) {
builder.finish(offset);
}
static finishSizePrefixedPersonBuffer(builder:flatbuffers.Builder, offset:flatbuffers.Offset) {
builder.finish(offset, undefined, true);
}
static createPerson(builder:flatbuffers.Builder, nameOffset:flatbuffers.Offset, age:number):flatbuffers.Offset {
Person.startPerson(builder);
Person.addName(builder, nameOffset);
Person.addAge(builder, age);
return Person.endPerson(builder);
}
}

1
tests/ts/longer-namespace/a/b/c.d.ts vendored Normal file
View File

@@ -0,0 +1 @@
export { Person } from './c/person.js';

View File

@@ -0,0 +1,3 @@
// automatically generated by the FlatBuffers compiler, do not modify
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
export { Person } from './c/person.js';

View File

@@ -0,0 +1,5 @@
// automatically generated by the FlatBuffers compiler, do not modify
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
export { Person } from './c/person.js';

View File

@@ -0,0 +1,18 @@
import * as flatbuffers from 'flatbuffers';
export declare class Person {
bb: flatbuffers.ByteBuffer | null;
bb_pos: number;
__init(i: number, bb: flatbuffers.ByteBuffer): Person;
static getRootAsPerson(bb: flatbuffers.ByteBuffer, obj?: Person): Person;
static getSizePrefixedRootAsPerson(bb: flatbuffers.ByteBuffer, obj?: Person): Person;
name(): string | null;
name(optionalEncoding: flatbuffers.Encoding): string | Uint8Array | null;
age(): number;
static startPerson(builder: flatbuffers.Builder): void;
static addName(builder: flatbuffers.Builder, nameOffset: flatbuffers.Offset): void;
static addAge(builder: flatbuffers.Builder, age: number): void;
static endPerson(builder: flatbuffers.Builder): flatbuffers.Offset;
static finishPersonBuffer(builder: flatbuffers.Builder, offset: flatbuffers.Offset): void;
static finishSizePrefixedPersonBuffer(builder: flatbuffers.Builder, offset: flatbuffers.Offset): void;
static createPerson(builder: flatbuffers.Builder, nameOffset: flatbuffers.Offset, age: number): flatbuffers.Offset;
}

View File

@@ -0,0 +1,54 @@
// automatically generated by the FlatBuffers compiler, do not modify
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
import * as flatbuffers from 'flatbuffers';
export class Person {
constructor() {
this.bb = null;
this.bb_pos = 0;
}
__init(i, bb) {
this.bb_pos = i;
this.bb = bb;
return this;
}
static getRootAsPerson(bb, obj) {
return (obj || new Person()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
static getSizePrefixedRootAsPerson(bb, obj) {
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
return (obj || new Person()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
name(optionalEncoding) {
const offset = this.bb.__offset(this.bb_pos, 4);
return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null;
}
age() {
const offset = this.bb.__offset(this.bb_pos, 6);
return offset ? this.bb.readInt16(this.bb_pos + offset) : 0;
}
static startPerson(builder) {
builder.startObject(2);
}
static addName(builder, nameOffset) {
builder.addFieldOffset(0, nameOffset, 0);
}
static addAge(builder, age) {
builder.addFieldInt16(1, age, 0);
}
static endPerson(builder) {
const offset = builder.endObject();
return offset;
}
static finishPersonBuffer(builder, offset) {
builder.finish(offset);
}
static finishSizePrefixedPersonBuffer(builder, offset) {
builder.finish(offset, undefined, true);
}
static createPerson(builder, nameOffset, age) {
Person.startPerson(builder);
Person.addName(builder, nameOffset);
Person.addAge(builder, age);
return Person.endPerson(builder);
}
}

View File

@@ -0,0 +1,70 @@
// automatically generated by the FlatBuffers compiler, do not modify
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
import * as flatbuffers from 'flatbuffers';
export class Person {
bb: flatbuffers.ByteBuffer|null = null;
bb_pos = 0;
__init(i:number, bb:flatbuffers.ByteBuffer):Person {
this.bb_pos = i;
this.bb = bb;
return this;
}
static getRootAsPerson(bb:flatbuffers.ByteBuffer, obj?:Person):Person {
return (obj || new Person()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
static getSizePrefixedRootAsPerson(bb:flatbuffers.ByteBuffer, obj?:Person):Person {
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
return (obj || new Person()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
name():string|null
name(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
name(optionalEncoding?:any):string|Uint8Array|null {
const offset = this.bb!.__offset(this.bb_pos, 4);
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
}
age():number {
const offset = this.bb!.__offset(this.bb_pos, 6);
return offset ? this.bb!.readInt16(this.bb_pos + offset) : 0;
}
static startPerson(builder:flatbuffers.Builder) {
builder.startObject(2);
}
static addName(builder:flatbuffers.Builder, nameOffset:flatbuffers.Offset) {
builder.addFieldOffset(0, nameOffset, 0);
}
static addAge(builder:flatbuffers.Builder, age:number) {
builder.addFieldInt16(1, age, 0);
}
static endPerson(builder:flatbuffers.Builder):flatbuffers.Offset {
const offset = builder.endObject();
return offset;
}
static finishPersonBuffer(builder:flatbuffers.Builder, offset:flatbuffers.Offset) {
builder.finish(offset);
}
static finishSizePrefixedPersonBuffer(builder:flatbuffers.Builder, offset:flatbuffers.Offset) {
builder.finish(offset, undefined, true);
}
static createPerson(builder:flatbuffers.Builder, nameOffset:flatbuffers.Offset, age:number):flatbuffers.Offset {
Person.startPerson(builder);
Person.addName(builder, nameOffset);
Person.addAge(builder, age);
return Person.endPerson(builder);
}
}

View File

@@ -15,6 +15,8 @@
"namespace_test/**/*.ts",
"union_vector/**/*.ts",
"arrays_test_complex/**/*.ts",
"union_underlying_type_test.ts"
"union_underlying_type_test.ts",
"long-namespace/**/*.ts",
"longer-namespace/**/*.ts"
]
}