Paul Gschwendtner 56bd21de6f feat(dev-infra): introduce shared tool for validating API signature (#42688)
For the last years the Angular repositories relied on `ts-api-guardian`
for testing the public API signature. This project worked well in
general but its another inconvenience to maintain if we could rely on
Microsoft's `api-extractor` tool.

Especially since with TypeScript 4.3 issues with export aliases appeared
that would require us to extend TS API guardian to support such exports.
This is not as straightforward as it sounds, given it requires rewriting
of declarations to show-case the proper name in the API golden. Microsoft's
API extractor has integrated support for this.

As of TypeScript 4.3, we want to start using the new `override` keyword.
We are not able to use that keyword currently because an old version of
API extractor is used in the `ng_module` rule to flatten the types into
a single file. To fix this, we need to update `api-extractor`, but this
unveils the issue with TS API guardian because the most recent version
of api-extractor uses alias exports to avoid potential conflicts
with globals available through the TypeScript default libraries (e.g.
`dom.d.ts`).

PR Close #42688
2021-06-30 11:43:48 -07:00

84 lines
2.8 KiB
Python

load("@build_bazel_rules_nodejs//:index.bzl", "nodejs_binary", "nodejs_test")
nodejs_test_args = [
# Needed so that node doesn't walk back to the source directory.
# From there, the relative imports would point to .ts files.
"--node_options=--preserve-symlinks",
# TODO(josephperrott): update dependency usages to no longer need bazel patch module resolver
# See: https://github.com/bazelbuild/rules_nodejs/wiki#--bazel_patch_module_resolver-now-defaults-to-false-2324
"--bazel_patch_module_resolver",
]
default_strip_export_pattern = "^ɵ(?!ɵdefineInjectable|ɵinject|ɵInjectableDef)"
"""Escapes a Regular expression so that it can be passed as process argument."""
def _escape_regex_for_arg(value):
return "\"%s\"" % value
"""
Builds an API report for the specified entry-point and compares it against the
specified golden
"""
def api_golden_test(
name,
golden,
entry_point,
data = [],
strip_export_pattern = default_strip_export_pattern,
**kwargs):
quoted_export_pattern = _escape_regex_for_arg(strip_export_pattern)
kwargs["tags"] = kwargs.get("tags", []) + ["api_guard"]
nodejs_test(
name = name,
data = ["//dev-infra/bazel/api-golden", "//:package.json"] + data,
entry_point = "//dev-infra/bazel/api-golden:index.ts",
templated_args = nodejs_test_args + [golden, entry_point, "false", quoted_export_pattern],
**kwargs
)
nodejs_binary(
name = name + ".accept",
testonly = True,
data = ["//dev-infra/bazel/api-golden", "//:package.json"] + data,
entry_point = "//dev-infra/bazel/api-golden:index.ts",
templated_args = nodejs_test_args + [golden, entry_point, "true", quoted_export_pattern],
**kwargs
)
"""
Builds an API report for all entrypoints within the given NPM package and compares it
against goldens within the specified directory.
"""
def api_golden_test_npm_package(
name,
golden_dir,
npm_package,
data = [],
strip_export_pattern = default_strip_export_pattern,
**kwargs):
quoted_export_pattern = _escape_regex_for_arg(strip_export_pattern)
kwargs["tags"] = kwargs.get("tags", []) + ["api_guard"]
nodejs_test(
name = name,
data = ["//dev-infra/bazel/api-golden"] + data,
entry_point = "//dev-infra/bazel/api-golden:index_npm_packages.ts",
templated_args = nodejs_test_args + [golden_dir, npm_package, "false", quoted_export_pattern],
**kwargs
)
nodejs_binary(
name = name + ".accept",
testonly = True,
data = ["//dev-infra/bazel/api-golden"] + data,
entry_point = "//dev-infra/bazel/api-golden:index_npm_packages.ts",
templated_args = nodejs_test_args + [golden_dir, npm_package, "true", quoted_export_pattern],
**kwargs
)