in src/transforms/deprecation-warnings.ts [278:341]
function generateWarningsFile(projectRoot: string, functionDeclarations: ts.FunctionDeclaration[]) {
const names = [...functionDeclarations].map((d) => d.name?.text).filter(Boolean);
const exportedSymbols = [WARNING_FUNCTION_NAME, GET_PROPERTY_DESCRIPTOR, DEPRECATION_ERROR, ...names].join(',');
const functionText = `function ${WARNING_FUNCTION_NAME}(name, deprecationMessage) {
const deprecated = process.env.JSII_DEPRECATED;
const deprecationMode = ['warn', 'fail', 'quiet'].includes(deprecated) ? deprecated : 'warn';
const message = \`\${name} is deprecated.\\n \${deprecationMessage.trim()}\\n This API will be removed in the next major release.\`;
switch (deprecationMode) {
case "fail":
throw new ${DEPRECATION_ERROR}(message);
case "warn":
console.warn("[WARNING]", message);
break;
}
}
function ${GET_PROPERTY_DESCRIPTOR}(obj, prop) {
const descriptor = Object.getOwnPropertyDescriptor(obj, prop);
if (descriptor) {
return descriptor;
}
const proto = Object.getPrototypeOf(obj);
const prototypeDescriptor = proto && getPropertyDescriptor(proto, prop);
if (prototypeDescriptor) {
return prototypeDescriptor;
}
return {};
}
const ${VISITED_OBJECTS_SET_NAME} = new Set();
class ${DEPRECATION_ERROR} extends Error {
constructor(...args) {
super(...args);
Object.defineProperty(this, 'name', {
configurable: false,
enumerable: true,
value: '${DEPRECATION_ERROR}',
writable: false,
});
}
}
module.exports = {${exportedSymbols}}
`;
const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });
const resultFile = ts.createSourceFile(
path.join(projectRoot, WARNINGSCODE_FILE_NAME),
functionText,
ts.ScriptTarget.Latest,
false,
ts.ScriptKind.JS,
);
const declarations = functionDeclarations.map((declaration) =>
printer.printNode(ts.EmitHint.Unspecified, declaration, resultFile),
);
const content = declarations.concat(printer.printFile(resultFile)).join('\n');
fs.writeFileSync(path.join(projectRoot, WARNINGSCODE_FILE_NAME), content);
}