jsii icon indicating copy to clipboard operation
jsii copied to clipboard

JSII3000 (unexported type) error for a type that comes from a submodule of a JSII peer dependency

Open ansgarm opened this issue 4 years ago • 6 comments

:bug: Bug Report

Affected Languages

  • [x] TypeScript or Javascript
  • [ ] Python
  • [ ] Java
  • [ ] .NET (C#, F#, ...)
  • [ ] Go

General Information

  • JSII Version: 1.40.0 (build 9713b9d), typescript 3.9.10
  • Platform: OS X

What is the problem?

With our 0.7 release of CDKTF we switched the provider generation for the AWS provider to use JSII submodules. This change brought up an issue in a custom constructs that makes use of those pre-built provider bindings: Exported APIs cannot use un-exported type "@pahud/cdktf-aws-eks.EKS.EksCluster" (originally reported here: https://github.com/hashicorp/cdktf-provider-aws/issues/465)

When exporting the namespace like this in the pre-built AWS provider:

export { EKS } from './EKS';

instead of

export * from './EKS';

JSII can compile the custom construct. However that also causes JSII to not treat those namespaces as submodules anymore (related comment) – hence I think it does not solve the underlying problem but rather rolls back the change.

So I dug a bit deeper and added a bit of logging to the _allTypeReferencesAreValid validator function. Apparently (and as visible in the error message) the typeRef causing the JSII3000 error is { fqn: '@pahud/cdktf-aws-eks.EKS.EksCluster' }. I also logged all assembly.types known to JSII: (full output)

{
  '@pahud/cdktf-aws-eks.CapacityType': {...},
  '@pahud/cdktf-aws-eks.ScalingConfig': {...},
  '@pahud/cdktf-aws-eks.NodeGroupOptions': {...},
  '@pahud/cdktf-aws-eks.NodeGroupProps': {...},
  '@pahud/cdktf-aws-eks.NodeGroup': {...},
  '@pahud/cdktf-aws-eks.ClusterProps': {...},
  '@pahud/cdktf-aws-eks.NodeGroupBaseOptions': {...},
  '@pahud/cdktf-aws-eks.Cluster': {...},
  '@pahud/cdktf-aws-eks.KubernetesVersion': {...}
}

And it appears that there is no namespace @pahud/cdktf-aws-eks.EKS and JSII somehow must be incorrectly inferring @pahud/cdktf-aws-eks.EKS.EksCluster for the EKS.EksCluster referenced here. It should probably be @cdktf/provider-aws.EKS.EksCluster or similar.

Could you point me to the logic that determines / resolves that name? My current suspicion is that it lacks support for submodules, but I'm only guessing here.

Reproduction example

https://github.com/ansgarm/jsii-namespace-peer-deps

ansgarm avatar Oct 27 '21 09:10 ansgarm

Instead of

export * from './EKS';

Have you tried

export * as EKS from './EKS';

I think what you're trying to do is reasonable and should work. I reckon it fell in an edge case of the submodule traversal logic, somehow... I need to attempt reproduction to understand where things go south...

RomainMuller avatar Nov 02 '21 18:11 RomainMuller

Would you be able to make a small repro repository for me to use? That'd help me get to this faster...

RomainMuller avatar Nov 02 '21 18:11 RomainMuller

Hi @RomainMuller!

Sure! Here you go: https://github.com/ansgarm/jsii-namespace-peer-deps

Have you tried export * as EKS from './EKS';

Just tried it. Works, but is a bit less ideal due to the following reasons:

  1. JSII requires snake case for it. So only export * as eks from './EKS'; would work (this is something we could live with of course)
  2. As we are using namespaces in our submodules (see reproduction example also), usage would look like this:
import { eks } from '@cdktf/provider-aws';
const cluster = new eks.eks.EksCluster(…);

Edit: We are using TS namespaces, because we faced issues with too many exports causing RangeError: Maximum call stack size exceeded with the TypeScript version required by JSII. The AWS Terraform provider is too big 😅

ansgarm avatar Nov 03 '21 07:11 ansgarm

FYI @RomainMuller: We tried a slightly different approach to namespaces today, and it looks like this might solve our immediate issue. Gonna get back to you with more details once I confirmed.

skorfmann avatar Nov 03 '21 20:11 skorfmann

FYI @RomainMuller: We tried a slightly different approach to namespaces today, and it looks like this might solve our immediate issue. Gonna get back to you with more details once I confirmed.

This PR solved our issue around namespaces https://github.com/hashicorp/terraform-cdk/pull/1248

skorfmann avatar Nov 09 '21 20:11 skorfmann

Hey @skorfmann,

I would like to confirm if this is still an issue in JSII or if it was confirmed to be resolved via the namespace change in tcdk?

NGL321 avatar May 25 '22 22:05 NGL321