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 };
}
}