public emit()

in src/assembler.ts [137:285]


  public emit(): ts.EmitResult {
    if (!this.projectInfo.description) {
      this._diagnostics.push(JsiiDiagnostic.JSII_0001_PKG_MISSING_DESCRIPTION.createDetached());
    }
    if (!this.projectInfo.homepage) {
      this._diagnostics.push(JsiiDiagnostic.JSII_0002_PKG_MISSING_HOMEPAGE.createDetached());
    }
    const readme = _loadReadme.call(this);
    if (readme == null) {
      this._diagnostics.push(JsiiDiagnostic.JSII_0003_MISSING_README.createDetached());
    }
    const docs = _loadDocs.call(this);

    const sourceFile = this.program.getSourceFile(this.mainFile);

    if (sourceFile == null) {
      this._diagnostics.push(JsiiDiagnostic.JSII_0004_COULD_NOT_FIND_ENTRYPOINT.createDetached(this.mainFile));
    } else {
      this._registerDependenciesNamespaces(sourceFile);

      if (LOG.isTraceEnabled()) {
        LOG.trace(
          `Processing source file: ${chalk.blue(path.relative(this.projectInfo.projectRoot, sourceFile.fileName))}`,
        );
      }
      const symbol = this._typeChecker.getSymbolAtLocation(sourceFile);
      if (symbol) {
        const moduleExports = this._typeChecker.getExportsOfModule(symbol);
        moduleExports.map((item) => this._registerNamespaces(item, this.projectInfo.projectRoot));
        for (const node of moduleExports) {
          const decl = node.declarations?.[0];
          if (decl == null) {
            continue;
          }
          this._visitNode(decl, new EmitContext([], this.projectInfo.stability));
        }
      }
    }

    this.callDeferredsInOrder();

    // Skip emitting if any diagnostic message is an error
    if (this._diagnostics.find((diag) => diag.category === ts.DiagnosticCategory.Error) != null) {
      LOG.debug('Skipping emit due to errors.');
      try {
        return { diagnostics: this._diagnostics, emitSkipped: true };
      } finally {
        // Clearing ``this._diagnostics`` to allow contents to be garbage-collected.
        this._afterEmit();
      }
    }

    const jsiiVersion = this.projectInfo.jsiiVersionFormat === 'short' ? SHORT_VERSION : VERSION;

    const assembly: spec.Assembly = {
      schema: spec.SchemaVersion.LATEST,
      name: this.projectInfo.name,
      version: this.projectInfo.version,
      description: this.projectInfo.description ?? this.projectInfo.name,
      license: this.projectInfo.license,
      keywords: this.projectInfo.keywords && Array.from(this.projectInfo.keywords),
      homepage: this.projectInfo.homepage ?? this.projectInfo.repository.url,
      author: this.projectInfo.author,
      contributors: this.projectInfo.contributors && [...this.projectInfo.contributors],
      repository: this.projectInfo.repository,
      dependencies: noEmptyDict({
        ...this.projectInfo.dependencies,
        ...this.projectInfo.peerDependencies,
      }),
      dependencyClosure: noEmptyDict(toDependencyClosure(this.projectInfo.dependencyClosure)),
      bundled: this.projectInfo.bundleDependencies,
      types: Object.fromEntries(this._types),
      submodules: noEmptyDict(toSubmoduleDeclarations(this.mySubmodules())),
      targets: this.projectInfo.targets,
      metadata: {
        ...this.projectInfo.metadata,

        // Downstream consumers need this to map a symbolId in the outDir to a
        // symbolId in the rootDir.
        tscRootDir: this.tscRootDir,
      },
      docs,
      readme,
      jsiiVersion,
      bin: this.projectInfo.bin,
      fingerprint: '<TBD>',
    };

    if (this.deprecatedRemover) {
      this._diagnostics.push(...this.deprecatedRemover.removeFrom(assembly));
    }

    if (this.warningsInjector) {
      const jsiiMetadata = {
        ...(assembly.metadata?.jsii ?? {}),
        ...{ compiledWithDeprecationWarnings: true },
      };

      if (assembly.metadata) {
        assembly.metadata.jsii = jsiiMetadata;
      } else {
        assembly.metadata = { jsii: jsiiMetadata };
      }
      this.warningsInjector.process(assembly, this.projectInfo);
    }

    const validator = new Validator(this.projectInfo, assembly);
    const validationResult = validator.emit();
    if (!validationResult.emitSkipped) {
      const zipped = writeAssembly(this.projectInfo.projectRoot, _fingerprint(assembly), {
        compress: this.compressAssembly ?? false,
      });
      LOG.trace(
        `${zipped ? 'Zipping' : 'Emitting'} assembly: ${chalk.blue(
          path.join(this.projectInfo.projectRoot, SPEC_FILE_NAME),
        )}`,
      );
    }

    try {
      return {
        diagnostics: [...this._diagnostics, ...validationResult.diagnostics],
        emitSkipped: validationResult.emitSkipped,
      };
    } finally {
      this._afterEmit();
    }

    function _loadReadme(this: Assembler) {
      // Search for `README.md` in a case-insensitive way
      const fileName = fs
        .readdirSync(this.projectInfo.projectRoot)
        .find((file) => file.toLocaleLowerCase() === 'readme.md');
      if (fileName == null) {
        return undefined;
      }
      const readmePath = path.join(this.projectInfo.projectRoot, fileName);
      return loadAndRenderReadme(readmePath, this.projectInfo.projectRoot);
    }

    function _loadDocs(this: Assembler): spec.Docs | undefined {
      if (!this.projectInfo.stability && !this.projectInfo.deprecated) {
        return undefined;
      }
      const deprecated = this.projectInfo.deprecated;
      const stability = this.projectInfo.stability;
      return { deprecated, stability };
    }
  }