Skip to content

Commit c02b6e2

Browse files
ad-worldAnsh Chaturvedi
authored andcommitted
feat(openapi-generator): make node_module resolving more generic by removing @BitGo prefix
1 parent de2c6c6 commit c02b6e2

File tree

3 files changed

+53
-65
lines changed

3 files changed

+53
-65
lines changed

packages/openapi-generator/src/project.ts

Lines changed: 43 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,23 @@ export class Project {
5454
this.add(path, sourceFile);
5555

5656
for (const sym of Object.values(sourceFile.symbols.imports)) {
57-
const filePath = p.dirname(path);
58-
const absImportPathE = this.resolve(filePath, sym.from);
59-
if (E.isLeft(absImportPathE)) {
60-
return absImportPathE;
61-
} else if (!this.has(absImportPathE.right)) {
62-
queue.push(absImportPathE.right);
57+
if (!sym.from.startsWith('.')) {
58+
// If we are not resolving a relative path, we need to resolve the entry point
59+
const baseDir = p.dirname(sourceFile.path);
60+
let entryPoint = this.resolveEntryPoint(baseDir, sym.from);
61+
if (E.isLeft(entryPoint)) {
62+
continue;
63+
} else if (!this.has(entryPoint.right)) {
64+
queue.push(entryPoint.right);
65+
}
66+
} else {
67+
const filePath = p.dirname(path);
68+
const absImportPathE = this.resolve(filePath, sym.from);
69+
if (E.isLeft(absImportPathE)) {
70+
return absImportPathE;
71+
} else if (!this.has(absImportPathE.right)) {
72+
queue.push(absImportPathE.right);
73+
}
6374
}
6475
}
6576
for (const starExport of sourceFile.symbols.exportStarFiles) {
@@ -80,66 +91,45 @@ export class Project {
8091
return await readFile(filename, 'utf8');
8192
}
8293

83-
private resolvePath(path: string, basedir: string): E.Either<string, string> {
94+
resolveEntryPoint(basedir: string, library: string): E.Either<string, string> {
8495
try {
85-
const result = resolve.sync(path, {
96+
const packageJson = resolve.sync(`${library}/package.json`, {
8697
basedir,
87-
extensions: ['.ts', '.js', '.d.ts'],
98+
extensions: ['.json'],
8899
});
100+
const packageInfo = JSON.parse(fs.readFileSync(packageJson, 'utf8'));
89101

90-
return E.right(result);
91-
} catch (e: unknown) {
92-
if (e instanceof Error && e.message) {
93-
return E.left(e.message);
102+
let typesEntryPoint = '';
103+
104+
if (packageInfo['types']) {
105+
typesEntryPoint = packageInfo['types'];
94106
}
95107

96-
return E.left(JSON.stringify(e));
97-
}
98-
}
108+
if (packageInfo['typings']) {
109+
typesEntryPoint = packageInfo['typings'];
110+
}
99111

100-
private findSourceFileFromPackage(path: string): E.Either<string, string> {
101-
const mapName = path.replace('.js', '.js.map');
112+
if (!typesEntryPoint) {
113+
return E.left(`Could not find types entry point for ${library}`);
114+
}
102115

103-
if (fs.existsSync(mapName)) {
104-
const mapJson = JSON.parse(fs.readFileSync(mapName, 'utf8'));
105-
const dirName = p.dirname(path);
106-
const source = mapJson.sources[0];
107-
const response = resolve.sync(source, { basedir: dirName });
108-
return E.right(response);
116+
const entryPoint = resolve.sync(`${library}/${typesEntryPoint}`, {
117+
basedir,
118+
extensions: ['.ts', '.js'],
119+
});
120+
return E.right(entryPoint);
121+
} catch (err) {
122+
return E.left(`Could not resolve entry point for ${library}: ${err}`);
109123
}
110-
111-
return E.left('Map file not found for ' + path);
112124
}
113125

114126
resolve(basedir: string, path: string): E.Either<string, string> {
115-
const BITGO_PREFIX = '@bitgo';
116127
try {
117-
let resolved = this.resolvePath(path, basedir);
118-
if (E.isLeft(resolved)) {
119-
// Could not resolve the path, try resolving in the types package
120-
resolved = this.resolvePath('@types/' + path, basedir);
121-
}
122-
123-
// Types package wasn't found, return an error
124-
if (E.isLeft(resolved)) {
125-
return E.left('Could not resolve ' + path + ' from ' + basedir);
126-
}
127-
128-
const result = resolved.right;
129-
130-
// If we are parsing an internal type package, we want to return the path to the source TS file
131-
if (path.startsWith(BITGO_PREFIX)) {
132-
return this.findSourceFileFromPackage(result);
133-
} else {
134-
// Else - find the declaration file and return it if it exists
135-
const dTsName = result.replace('.js', '.d.ts');
136-
137-
if (fs.existsSync(dTsName)) {
138-
return E.right(dTsName);
139-
}
140-
141-
return E.right(result);
142-
}
128+
const result = resolve.sync(path, {
129+
basedir,
130+
extensions: ['.ts', '.js'],
131+
});
132+
return E.right(result);
143133
} catch (e: unknown) {
144134
if (e instanceof Error && e.message) {
145135
return E.left(e.message);

packages/openapi-generator/src/resolveInit.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,13 @@ function resolveImportPath(
1313
sourceFile: SourceFile,
1414
path: string,
1515
): E.Either<string, SourceFile> {
16-
const importPathE = project.resolve(dirname(sourceFile.path), path);
16+
let importPathE;
17+
if (path.startsWith('.')) {
18+
importPathE = project.resolve(dirname(sourceFile.path), path);
19+
} else {
20+
importPathE = project.resolveEntryPoint(dirname(sourceFile.path), path);
21+
}
22+
1723
if (E.isLeft(importPathE)) {
1824
return importPathE;
1925
}

packages/openapi-generator/test/externalModule.test.ts

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import * as p from 'path';
55

66
import { parsePlainInitializer, Project, type Schema } from '../src';
77
import { KNOWN_IMPORTS } from '../src/knownImports';
8+
// import { resolve } from 'node:path';
89

910
/** External library parsing test case
1011
*
@@ -18,23 +19,16 @@ async function testCase(
1819
entryPoint: string,
1920
expected: Record<string, Record<string, Schema>>,
2021
expectedErrors: Record<string, string[]> = {},
21-
parseErrorRegex: RegExp | undefined = undefined,
2222
) {
2323
test(description, async () => {
2424
const project = new Project({}, KNOWN_IMPORTS);
2525
const entryPointPath = p.resolve(entryPoint);
26-
const parsed = await project.parseEntryPoint(entryPointPath);
27-
28-
if (parseErrorRegex !== undefined) {
29-
assert(E.isLeft(parsed));
30-
assert(parseErrorRegex.test(parsed.left));
31-
return;
32-
}
26+
await project.parseEntryPoint(entryPointPath);
3327

3428
for (const path of Object.keys(expected)) {
3529
const resolvedPath = p.resolve(path);
3630
const sourceFile = project.get(resolvedPath);
37-
31+
3832
if (sourceFile === undefined) {
3933
throw new Error(`Source file ${path} not found`);
4034
}
@@ -193,13 +187,11 @@ testCase(
193187
'test/sample-types/importPathError.ts',
194188
{},
195189
{},
196-
/Could not resolve io-tsg from .*\/test\/sample-types\/node_modules\/@bitgo\/foobar3\/src/,
197190
);
198191

199192
testCase(
200193
'type from external library with export path error',
201194
'test/sample-types/exportPathError.ts',
202195
{},
203196
{},
204-
/Could not resolve .\/foobart from .*\/test\/sample-types\/node_modules\/@bitgo\/foobar6\/src/,
205197
);

0 commit comments

Comments
 (0)