Skip to content

Commit

Permalink
Merge pull request #12 from KevinEdry/handle-barrel-files
Browse files Browse the repository at this point in the history
[FIX] Handle Barrel File Imports
  • Loading branch information
KevinEdry authored Sep 28, 2024
2 parents 33adf34 + 5be3ac9 commit 758f1c0
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 17 deletions.
76 changes: 64 additions & 12 deletions packages/nestjs-trpc/lib/utils/type.util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import {
ProcedureGeneratorMetadata,
SourceFileImportsMap,
} from '../interfaces/generator.interface';
import * as path from 'node:path';

export function findCtxOutProperty(type: Type): string | undefined {
const typeText = type.getText();
Expand All @@ -17,7 +16,7 @@ export function generateProcedureString(
): string {
const { name, decorators } = procedure;
const decorator = decorators.find(
(d) => d.name === 'Mutation' || d.name === 'Query',
(decorator) => decorator.name === 'Mutation' || decorator.name === 'Query',
);

if (!decorator) {
Expand All @@ -31,6 +30,51 @@ export function generateProcedureString(
return `${name}: publicProcedure${decoratorArgumentsArray}.${decorator.name.toLowerCase()}(async () => "PLACEHOLDER_DO_NOT_REMOVE" as any )`;
}

/**
* https://github.com/dsherret/ts-morph/issues/327
* Note that if the module resolution of the compiler is Classic then it won't resolve those implicit index.ts module specifiers.
* So for example, if the moduleResolution compiler option isn't explicitly set then setting the module
* compiler option to anything but ModuleKind.CommonJS will cause the module resolution kind to resolve to Classic.
* Additionally, if moduleResolution and the module compiler option isn't set,
* then a script target of ES2015 and above will also use Classic module resolution.
*/
function resolveBarrelFileImport(
barrelSourceFile: SourceFile,
name: string,
project: Project,
): SourceFile | undefined {
// Traverse through export declarations to find the actual source of the named import
for (const exportDeclaration of barrelSourceFile.getExportDeclarations()) {
const exportedSourceFile = exportDeclaration.getModuleSpecifierSourceFile();
if (exportedSourceFile == null) continue;

// Check if the named export is explicitly re-exported
const namedExports = exportDeclaration.getNamedExports();
if (namedExports.length > 0) {
const matchingExport = namedExports.find((e) => e.getName() === name);
if (matchingExport) {
return exportedSourceFile;
}
} else {
// Handle `export * from ...` case: recursively resolve the export
const schemaVariable = exportedSourceFile.getVariableDeclaration(name);
if (schemaVariable) {
return exportedSourceFile;
} else {
// Continue resolving if it's another barrel file
const baseSourceFile = resolveBarrelFileImport(
exportedSourceFile,
name,
project,
);
if (baseSourceFile) return baseSourceFile;
}
}
}

return undefined;
}

function buildSourceFileImportsMap(
sourceFile: SourceFile,
project: Project,
Expand All @@ -42,22 +86,30 @@ function buildSourceFileImportsMap(
const namedImports = importDeclaration.getNamedImports();
for (const namedImport of namedImports) {
const name = namedImport.getName();
const moduleSpecifier = importDeclaration.getModuleSpecifierValue();
const resolvedPath = path.resolve(
path.dirname(sourceFile.getFilePath()),
moduleSpecifier + '.ts',
);
const importedSourceFile =
project.addSourceFileAtPathIfExists(resolvedPath);
if (!importedSourceFile) continue;
importDeclaration.getModuleSpecifierSourceFile();

const schemaVariable = importedSourceFile.getVariableDeclaration(name);
if (schemaVariable) {
if (importedSourceFile == null) {
continue;
}

const resolvedSourceFile =
importedSourceFile.getFilePath().endsWith('index.ts') &&
importedSourceFile.getVariableDeclaration(name) == null
? resolveBarrelFileImport(importedSourceFile, name, project)
: importedSourceFile;

if (resolvedSourceFile == null) {
continue;
}

const schemaVariable = resolvedSourceFile.getVariableDeclaration(name);
if (schemaVariable != null) {
const initializer = schemaVariable.getInitializer();
if (initializer) {
sourceFileImportsMap.set(name, {
initializer,
sourceFile: importedSourceFile,
sourceFile: resolvedSourceFile,
});
}
}
Expand Down
4 changes: 2 additions & 2 deletions packages/nestjs-trpc/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"peerDependencies": {
"@nestjs/common": "^9.3.8 || ^10.0.0",
"@nestjs/core": "^9.3.8 || ^10.0.0",
"@trpc/server": "^10.18.0",
"@trpc/server": "^10.0.0",
"reflect-metadata": "^0.1.13 || ^0.2.0",
"rxjs": "7.8.1",
"zod": "^3.14.0"
Expand All @@ -64,7 +64,7 @@
"tsconfig-paths": "^4.2.0",
"type-fest": "^4.21.0",
"typescript": "5.5.3",
"zod": "^3.14.0"
"zod": "^3.14.4"
},
"dependencies": {
"func-loc": "^0.1.16",
Expand Down
6 changes: 3 additions & 3 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -13290,11 +13290,11 @@ __metadata:
tslib: "npm:^2.5.0"
type-fest: "npm:^4.21.0"
typescript: "npm:5.5.3"
zod: "npm:^3.14.0"
zod: "npm:^3.14.4"
peerDependencies:
"@nestjs/common": ^9.3.8 || ^10.0.0
"@nestjs/core": ^9.3.8 || ^10.0.0
"@trpc/server": ^10.18.0
"@trpc/server": ^10.0.0
reflect-metadata: ^0.1.13 || ^0.2.0
rxjs: 7.8.1
zod: ^3.14.0
Expand Down Expand Up @@ -18288,7 +18288,7 @@ __metadata:
languageName: node
linkType: hard

"zod@npm:^3.14.0, zod@npm:^3.21.4, zod@npm:^3.22.3":
"zod@npm:^3.14.4, zod@npm:^3.21.4, zod@npm:^3.22.3":
version: 3.23.8
resolution: "zod@npm:3.23.8"
checksum: 10c0/8f14c87d6b1b53c944c25ce7a28616896319d95bc46a9660fe441adc0ed0a81253b02b5abdaeffedbeb23bdd25a0bf1c29d2c12dd919aef6447652dd295e3e69
Expand Down

0 comments on commit 758f1c0

Please sign in to comment.