From b752aabc47c0f2551377a56ed815e96e3ae3a2c1 Mon Sep 17 00:00:00 2001 From: Daniel Chambers Date: Wed, 10 Apr 2024 23:48:40 +1000 Subject: [PATCH] Fixed functions that are imported then re-exported causing a crash (#28) --- CHANGELOG.md | 1 + ndc-lambda-sdk/src/inference.ts | 6 +- .../functions-import-then-export.ts | 8 +++ .../re-exported-functions.test.ts | 63 ++++++++++++++++++- 4 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 ndc-lambda-sdk/test/inference/re-exported-functions/functions-import-then-export.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 044ade2..25a987d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ This changelog documents the changes between release versions. Changes to be included in the next upcoming release - Fixed watch mode not reloading after files with compiler errors are changed [#27](https://github.com/hasura/ndc-nodejs-lambda/pull/27) +- Fixed functions that are imported then re-exported causing a crash [#28](https://github.com/hasura/ndc-nodejs-lambda/pull/28) ## [1.2.0] - 2024-03-18 - Improved error messages when unsupported enum types or unions of literal types are found, and allow these types to be used in relaxed types mode ([#17](https://github.com/hasura/ndc-nodejs-lambda/pull/17)) diff --git a/ndc-lambda-sdk/src/inference.ts b/ndc-lambda-sdk/src/inference.ts index 1887a46..d032d48 100644 --- a/ndc-lambda-sdk/src/inference.ts +++ b/ndc-lambda-sdk/src/inference.ts @@ -171,10 +171,14 @@ function deriveSchemaFromFunctions(sourceFile: ts.SourceFile, projectRootDir: st const declaration = exportedSymbol.getDeclarations()?.[0] ?? throwError("exported symbol does not have a declaration"); // If exported via 'export { name } from "./imported"' + // or 'import { name } from "./imported"; export { name }' if (ts.isExportSpecifier(declaration)) { const identifier = declaration.name ?? throwError("export declaration didn't have an identifier"); const exportTarget = typeChecker.getExportSpecifierLocalTargetSymbol(declaration) ?? throwError("export specifier does not have a local target symbol"); - const exportTargetDeclaration = exportTarget.valueDeclaration ?? throwError("export target symbol does not have a value declaration"); + const exportTargetDeclaration = + exportTarget.valueDeclaration // 'export { name } from "./imported"' + ?? typeChecker.getAliasedSymbol(exportTarget).valueDeclaration // 'import { name } from "./imported"; export { name }' + ?? throwError("export target symbol does not have a value declaration"); if (ts.isFunctionDeclaration(exportTargetDeclaration)) { return [[identifier.text, exportTargetDeclaration]]; } diff --git a/ndc-lambda-sdk/test/inference/re-exported-functions/functions-import-then-export.ts b/ndc-lambda-sdk/test/inference/re-exported-functions/functions-import-then-export.ts new file mode 100644 index 0000000..3d46037 --- /dev/null +++ b/ndc-lambda-sdk/test/inference/re-exported-functions/functions-import-then-export.ts @@ -0,0 +1,8 @@ +import { fileAChildFunction as renamedFileAChildFunction } from "./file-a" +import { fileBChildFunction1, fileBChildFunction2 } from "./file-b" + +export { + renamedFileAChildFunction, + fileBChildFunction1, + fileBChildFunction2 as renamedFileBChildFunction2 +}; diff --git a/ndc-lambda-sdk/test/inference/re-exported-functions/re-exported-functions.test.ts b/ndc-lambda-sdk/test/inference/re-exported-functions/re-exported-functions.test.ts index 0d1246a..da17537 100644 --- a/ndc-lambda-sdk/test/inference/re-exported-functions/re-exported-functions.test.ts +++ b/ndc-lambda-sdk/test/inference/re-exported-functions/re-exported-functions.test.ts @@ -1,7 +1,7 @@ import { describe, it } from "mocha"; import { assert } from "chai"; import { deriveSchema } from "../../../src/inference"; -import { BuiltInScalarTypeName, FunctionNdcKind, NullOrUndefinability } from "../../../src/schema"; +import { FunctionNdcKind } from "../../../src/schema"; describe("re-exported functions", function() { it("supports functions re-exported from other files", function() { @@ -206,4 +206,65 @@ describe("re-exported functions", function() { } }) }); + + it("supports re-exports of functions from other files that are first imported then exported", function() { + const schema = deriveSchema(require.resolve("./functions-import-then-export.ts")); + + assert.deepStrictEqual(schema, { + compilerDiagnostics: [], + functionIssues: {}, + functionsSchema: { + functions: { + "renamedFileAChildFunction": { + ndcKind: FunctionNdcKind.Procedure, + description: null, + parallelDegree: null, + arguments: [], + resultType: { + name: "String", + kind: "scalar", + type: "named", + } + }, + "fileBChildFunction1": { + ndcKind: FunctionNdcKind.Procedure, + description: null, + parallelDegree: null, + arguments: [], + resultType: { + name: "Boolean", + kind: "scalar", + type: "named", + } + }, + "renamedFileBChildFunction2": { + ndcKind: FunctionNdcKind.Function, + description: null, + parallelDegree: null, + arguments: [ + { + argumentName: "input", + description: null, + type: { + name: "String", + kind: "scalar", + type: "named", + } + } + ], + resultType: { + name: "String", + kind: "scalar", + type: "named", + } + }, + }, + scalarTypes: { + Boolean: { type: "built-in" }, + String: { type: "built-in" }, + }, + objectTypes: {}, + } + }) + }); });