diff --git a/CHANGELOG.md b/CHANGELOG.md
index 462023ecf..a4bbaaa4b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,32 @@
+
+# [9.0.0-beta.28](https://github.com/angular/flex-layout/compare/8.0.0-beta.27...9.0.0-beta.28) (2020-01-27)
+
+This release adds compatibility for Angular v9, which removed some private APIs this library depended on.
+
+### Bug Fixes
+
+* **ssr:** reset class counter to zero before each render ([#1153](https://github.com/angular/flex-layout/issues/1153)) ([d062708](https://github.com/angular/flex-layout/commit/d062708))
+
+
+### Features
+
+* **core:** support beforeprint and afterprint hooks ([#1080](https://github.com/angular/flex-layout/issues/1080)) ([8302998](https://github.com/angular/flex-layout/commit/8302998)), closes [#603](https://github.com/angular/flex-layout/issues/603)
+* change tslib from direct dependency to peerDependency ([#1132](https://github.com/angular/flex-layout/issues/1132)) ([06268b8](https://github.com/angular/flex-layout/commit/06268b8))
+
+
+### BREAKING CHANGES
+
+* We no longer directly have a direct depedency on `tslib`. Instead it is now listed a `peerDependency`.
+
+Users not using the CLI will need to manually install `tslib` via;
+```
+yarn add tslib
+```
+or
+```
+npm install tslib --save
+```
+
# [8.0.0-beta.27](https://github.com/angular/flex-layout/compare/8.0.0-beta.26...8.0.0-beta.27) (2019-08-30)
diff --git a/package.json b/package.json
index 6a5168abc..15d5efcaf 100644
--- a/package.json
+++ b/package.json
@@ -27,7 +27,7 @@
"universal:serve": "gulp universal:serve",
"postinstall": "ngcc --properties es2015 browser module main --create-ivy-entry-points"
},
- "version": "8.0.0-beta.27",
+ "version": "9.0.0-beta.28",
"requiredAngularVersion": ">=9.0.0-rc.11",
"dependencies": {
"@angular/cdk": "^9.0.0-rc.8",
diff --git a/src/lib/core/media-observer/media-observer.ts b/src/lib/core/media-observer/media-observer.ts
index 0d11c30b0..810cfd5c0 100644
--- a/src/lib/core/media-observer/media-observer.ts
+++ b/src/lib/core/media-observer/media-observer.ts
@@ -66,7 +66,7 @@ export class MediaObserver implements OnDestroy {
/**
* @deprecated Use `asObservable()` instead.
* @breaking-change 8.0.0-beta.25
- * @deletion-target v8.0.0-beta.26
+ * @deletion-target 10.0.0
*/
readonly media$: Observable;
diff --git a/src/lib/package.json b/src/lib/package.json
index 90036af2c..41cd355c6 100644
--- a/src/lib/package.json
+++ b/src/lib/package.json
@@ -23,7 +23,7 @@
},
"homepage": "https://github.com/angular/flex-layout#readme",
"peerDependencies": {
- "@angular/cdk": "^9.0.0-rc.0",
+ "@angular/cdk": "^9.0.0-rc.8",
"@angular/core": "0.0.0-NG",
"@angular/common": "0.0.0-NG",
"@angular/platform-browser": "0.0.0-NG",
diff --git a/tools/tslint-rules/deletionTargetRule.ts b/tools/tslint-rules/deletionTargetRule.ts
deleted file mode 100644
index f0e11157b..000000000
--- a/tools/tslint-rules/deletionTargetRule.ts
+++ /dev/null
@@ -1,62 +0,0 @@
-import * as ts from 'typescript';
-import * as Lint from 'tslint';
-import * as utils from 'tsutils';
-import * as path from 'path';
-
-/**
- * Rule ensuring that deletion targets have not expired.
- * The current version is taken from the `package.json`.
- */
-export class Rule extends Lint.Rules.AbstractRule {
- apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
- const packageVersion = require(path.join(process.cwd(), 'package.json')).version;
-
- return this.applyWithFunction(sourceFile, (ctx: Lint.WalkContext) => {
- utils.forEachComment(ctx.sourceFile, (file, {pos, end}) => {
- const commentText = file.substring(pos, end);
- const hasDeletionTarget = commentText.indexOf('@deletion-target') > -1;
-
- if (!hasDeletionTarget && commentText.indexOf('@deprecated') > -1) {
- ctx.addFailure(pos, end, '@deprecated marker has to have a @deletion-target.');
- } if (hasDeletionTarget) {
- const version = commentText.match(/\d+\.\d+\.\d+/);
-
- if (!version) {
- ctx.addFailure(pos, end, '@deletion-target must have a version.');
- } else if (this._hasExpired(packageVersion, version[0])) {
- ctx.addFailure(pos, end, `Deletion target at ${version[0]} is due to be deleted. ` +
- `Current version is ${packageVersion}.`);
- }
- }
- });
- });
- }
-
- /**
- * Checks whether a version has expired, based on the current version.
- * @param currentVersion Current version of the package.
- * @param deletionTarget Version that is being checked.
- */
- private _hasExpired(currentVersion: string, deletionTarget: string) {
- if (currentVersion === deletionTarget) {
- return true;
- }
-
- const current = this._parseVersion(currentVersion);
- const target = this._parseVersion(deletionTarget);
-
- return target.major < current.major ||
- (target.major === current.major && target.minor < current.minor) ||
- (
- target.major === current.major &&
- target.minor === current.minor &&
- target.patch < current.patch
- );
- }
-
- /** Converts a version string into an object. */
- private _parseVersion(version: string) {
- const [major = 0, minor = 0, patch = 0] = version.split('.').map(segment => parseInt(segment));
- return {major, minor, patch};
- }
-}
diff --git a/tools/tslint-rules/requireBreakingChangeVersionRule.ts b/tools/tslint-rules/requireBreakingChangeVersionRule.ts
new file mode 100644
index 000000000..8d7f13e50
--- /dev/null
+++ b/tools/tslint-rules/requireBreakingChangeVersionRule.ts
@@ -0,0 +1,38 @@
+import * as ts from 'typescript';
+import * as Lint from 'tslint';
+import * as utils from 'tsutils';
+
+/** Doc tag that can be used to indicate a breaking change. */
+const BREAKING_CHANGE = '@breaking-change';
+
+/** Name of the old doc tag that was being used to indicate a breaking change. */
+const DELETION_TARGET = '@deletion-target';
+
+/**
+ * Rule that ensures that comments, indicating a deprecation
+ * or a breaking change, have a valid version.
+ */
+export class Rule extends Lint.Rules.AbstractRule {
+ apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
+ return this.applyWithFunction(sourceFile, (ctx: Lint.WalkContext) => {
+ utils.forEachComment(ctx.sourceFile, (file, {pos, end}) => {
+ const commentText = file.substring(pos, end);
+
+ // TODO(crisbeto): remove this check once most of the pending
+ // PRs start using `breaking-change`.
+ if (commentText.indexOf(DELETION_TARGET) > -1) {
+ ctx.addFailure(pos, end, `${DELETION_TARGET} has been replaced with ${BREAKING_CHANGE}.`);
+ return;
+ }
+
+ const hasBreakingChange = commentText.indexOf(BREAKING_CHANGE) > -1;
+
+ if (!hasBreakingChange && commentText.indexOf('@deprecated') > -1) {
+ ctx.addFailure(pos, end, `@deprecated marker has to have a ${BREAKING_CHANGE}.`);
+ } if (hasBreakingChange && !/\d+\.\d+\.\d+/.test(commentText)) {
+ ctx.addFailure(pos, end, `${BREAKING_CHANGE} must have a version.`);
+ }
+ });
+ });
+ }
+}