jest-preset-angular 9.0.6 → 10.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,51 @@
1
+ ## [10.1.0](https://github.com/thymikee/jest-preset-angular/compare/v10.0.1...v10.1.0) (2021-10-26)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **config:** set tsconfig `target` to ES2015 when `target` > ES2016 ([#1118](https://github.com/thymikee/jest-preset-angular/issues/1118)) ([64229a8](https://github.com/thymikee/jest-preset-angular/commit/64229a80f7a4833263e99950a42e8a618745115f)), closes [#1058](https://github.com/thymikee/jest-preset-angular/issues/1058)
7
+
8
+
9
+ ### Code Refactoring
10
+
11
+ * **transformers** use Angular `downlevel-ctor` transformer ([#1099](https://github.com/thymikee/jest-preset-angular/issues/1099)) ([3c26aba](https://github.com/thymikee/jest-preset-angular/commit/3c26abacf3a2f841330a7bc34aed172111c1e334))
12
+ * **transformers** remove workaround for ts < 4.0 in `replace-resource` transformer ([#1100](https://github.com/thymikee/jest-preset-angular/issues/1100)) ([ce68298](https://github.com/thymikee/jest-preset-angular/commit/ce682983bf4212a1f6fd71349af0d06c520812d6))
13
+ * **transformers** migrate `html-comment` to new Jest serializer ([#1114](https://github.com/thymikee/jest-preset-angular/issues/1114)) ([3005330](https://github.com/thymikee/jest-preset-angular/commit/3005330034f5db5d943764d406256f6c06d72823))
14
+
15
+
16
+
17
+ ## [10.0.1](https://github.com/thymikee/jest-preset-angular/compare/10.0.0...10.0.1) (2021-09-27)
18
+
19
+
20
+ ### Bug Fixes
21
+
22
+ * **utils:** allow skipping `ngcc-jest-processor` via some Jest args ([#1013](https://github.com/thymikee/jest-preset-angular/issues/1013)) ([7d3a712](https://github.com/thymikee/jest-preset-angular/commit/7d3a712a05ca3d032f942e59ba7d2b6f5f096334))
23
+
24
+
25
+
26
+ # [10.0.0](https://github.com/thymikee/jest-preset-angular/compare/v9.0.7...v10.0.0) (2021-09-16)
27
+
28
+
29
+ ### Build
30
+
31
+ * drop support for Angular 9 ([#998](https://github.com/thymikee/jest-preset-angular/issues/998)) ([1bbcc01](https://github.com/thymikee/jest-preset-angular/commit/1bbcc01ed4c098cd30871162a5e82fac4819a2d0))
32
+
33
+
34
+ ## BREAKING CHANGES
35
+
36
+ Angular 9 is no longer supported, see https://angular.io/guide/releases#support-policy-and-schedule The minimum support Angular version now is 10
37
+
38
+
39
+
40
+ ## [9.0.7](https://github.com/thymikee/jest-preset-angular/compare/v9.0.6...v9.0.7) (2021-08-20)
41
+
42
+
43
+ ### Bug Fixes
44
+
45
+ * **utils:** support Yarn workspace for `ngcc-jest-processor` ([#991](https://github.com/thymikee/jest-preset-angular/issues/991)) ([4735f90](https://github.com/thymikee/jest-preset-angular/commit/4735f90f6c54a9ce8de3c7d5a42d7f4628d19a5f)), closes [#990](https://github.com/thymikee/jest-preset-angular/issues/990)
46
+
47
+
48
+
1
49
  ## [9.0.6](https://github.com/thymikee/jest-preset-angular/compare/v9.0.5...v9.0.6) (2021-08-17)
2
50
 
3
51
 
package/README.md CHANGED
@@ -3,9 +3,9 @@
3
3
  <p align="center">A preset of Jest configuration for Angular projects.</p>
4
4
 
5
5
  <p align="center">
6
- <a href="https://actions-badge.atrox.dev/thymikee/jest-preset-angular/goto?ref=master"><img alt="Build Status" src="https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2Fthymikee%2Fjest-preset-angular%2Fbadge%3Fref%3Dmaster&style=flat-square" /></a>
6
+ <a href="https://actions-badge.atrox.dev/thymikee/jest-preset-angular/goto?ref=main"><img alt="Build Status" src="https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2Fthymikee%2Fjest-preset-angular%2Fbadge%3Fref%3Dmain&style=flat-square" /></a>
7
7
  <a href="https://www.npmjs.com/package/jest-preset-angular"><img src="https://img.shields.io/npm/v/jest-preset-angular/latest.svg?style=flat-square" alt="NPM Version" /></a>
8
- <a href="https://github.com/thymikee/jest-preset-angular/blob/master/LICENSE"><img src="https://img.shields.io/npm/l/jest-preset-angular.svg?style=flat-square" alt="GitHub license" /></a>
8
+ <a href="https://github.com/thymikee/jest-preset-angular/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/jest-preset-angular.svg?style=flat-square" alt="GitHub license" /></a>
9
9
  </p>
10
10
 
11
11
  This is a part of the article: [Testing Angular faster with Jest](https://www.xfive.co/blog/testing-angular-faster-jest/).
@@ -77,7 +77,7 @@ Check out our [Angular Ivy guidance](https://thymikee.github.io/jest-preset-angu
77
77
 
78
78
  ## Example apps
79
79
 
80
- We have [example apps](https://github.com/thymikee/jest-preset-angular/tree/master/examples) to provide a basic setup to use Jest in an Angular project.
80
+ We have [example apps](https://github.com/thymikee/jest-preset-angular/tree/main/examples) to provide a basic setup to use Jest in an Angular project.
81
81
 
82
82
  ## Built With
83
83
 
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.NgJestCompiler = void 0;
4
+ const compiler_cli_1 = require("@angular/compiler-cli");
4
5
  const ts_compiler_1 = require("ts-jest/dist/compiler/ts-compiler");
5
- const downlevel_ctor_1 = require("../transformers/downlevel-ctor");
6
6
  const replace_resources_1 = require("../transformers/replace-resources");
7
7
  class NgJestCompiler extends ts_compiler_1.TsCompiler {
8
8
  constructor(configSet, jestCacheFS) {
@@ -70,7 +70,7 @@ class NgJestCompiler extends ts_compiler_1.TsCompiler {
70
70
  return Object.assign(Object.assign(Object.assign({}, super._makeTransformers(customTransformers).after), super._makeTransformers(customTransformers).afterDeclarations), { before: [
71
71
  ...customTransformers.before.map((beforeTransformer) => beforeTransformer.factory(this, beforeTransformer.options)),
72
72
  replace_resources_1.replaceResources(this),
73
- downlevel_ctor_1.constructorDownlevelCtor(this),
73
+ compiler_cli_1.constructorParametersDownlevelTransform(this.program),
74
74
  ] });
75
75
  }
76
76
  }
@@ -4,6 +4,7 @@ exports.NgJestConfig = void 0;
4
4
  const config_set_1 = require("ts-jest/dist/config/config-set");
5
5
  class NgJestConfig extends config_set_1.ConfigSet {
6
6
  _resolveTsConfig(compilerOptions, resolvedConfigFile) {
7
+ var _a, _b, _c, _d;
7
8
  const result = super._resolveTsConfig(compilerOptions, resolvedConfigFile);
8
9
  result.options.enableIvy = true;
9
10
  result.options.noEmitOnError = false;
@@ -12,6 +13,11 @@ class NgJestConfig extends config_set_1.ConfigSet {
12
13
  result.options.annotationsAs = 'decorators';
13
14
  result.options.enableResourceInlining = false;
14
15
  result.options.allowJs = true;
16
+ const ts = this.compilerModule;
17
+ const scriptTarget = (_a = result.options.target) !== null && _a !== void 0 ? _a : (_b = ts.ScriptTarget) === null || _b === void 0 ? void 0 : _b.ES2015;
18
+ if (scriptTarget > ((_c = ts.ScriptTarget) === null || _c === void 0 ? void 0 : _c.ES2016)) {
19
+ result.options.target = (_d = ts.ScriptTarget) === null || _d === void 0 ? void 0 : _d.ES2015;
20
+ }
15
21
  return result;
16
22
  }
17
23
  }
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  const HTML_ELEMENT_REGEXP = /Comment/;
3
3
  const test = (value) => (value === null || value === void 0 ? void 0 : value.nodeType) === 8 && value.constructor !== undefined && HTML_ELEMENT_REGEXP.test(value.constructor.name);
4
- const print = () => '';
4
+ const serialize = () => '';
5
5
  module.exports = {
6
- print,
6
+ serialize,
7
7
  test,
8
8
  };
@@ -4,7 +4,6 @@ exports.replaceResources = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const typescript_1 = tslib_1.__importDefault(require("typescript"));
6
6
  const constants_1 = require("../constants");
7
- const useNodeFactory = +typescript_1.default.versionMajorMinor >= 4.0;
8
7
  const shouldTransform = (fileName) => !fileName.endsWith('.ngfactory.ts') && !fileName.endsWith('.ngstyle.ts');
9
8
  function replaceResources({ program }) {
10
9
  return (context) => {
@@ -16,9 +15,7 @@ function replaceResources({ program }) {
16
15
  const decorators = typescript_1.default.visitNodes(node.decorators, (node) => typescript_1.default.isDecorator(node)
17
16
  ? visitDecorator(context.factory, node, typeChecker, resourceImportDeclarations, moduleKind)
18
17
  : node);
19
- return useNodeFactory
20
- ? context.factory.updateClassDeclaration(node, decorators, node.modifiers, node.name, node.typeParameters, node.heritageClauses, node.members)
21
- : typescript_1.default.updateClassDeclaration(node, decorators, node.modifiers, node.name, node.typeParameters, node.heritageClauses, node.members);
18
+ return context.factory.updateClassDeclaration(node, decorators, node.modifiers, node.name, node.typeParameters, node.heritageClauses, node.members);
22
19
  }
23
20
  return typescript_1.default.visitEachChild(node, visitNode, context);
24
21
  };
@@ -28,9 +25,7 @@ function replaceResources({ program }) {
28
25
  }
29
26
  const updatedSourceFile = typescript_1.default.visitNode(sourceFile, visitNode);
30
27
  if (resourceImportDeclarations.length) {
31
- return useNodeFactory
32
- ? context.factory.updateSourceFile(updatedSourceFile, typescript_1.default.setTextRange(context.factory.createNodeArray([...resourceImportDeclarations, ...updatedSourceFile.statements]), updatedSourceFile.statements))
33
- : typescript_1.default.updateSourceFileNode(updatedSourceFile, typescript_1.default.setTextRange(typescript_1.default.createNodeArray([...resourceImportDeclarations, ...updatedSourceFile.statements]), updatedSourceFile.statements));
28
+ return context.factory.updateSourceFile(updatedSourceFile, typescript_1.default.setTextRange(context.factory.createNodeArray([...resourceImportDeclarations, ...updatedSourceFile.statements]), updatedSourceFile.statements));
34
29
  }
35
30
  return updatedSourceFile;
36
31
  };
@@ -55,18 +50,12 @@ function visitDecorator(nodeFactory, node, typeChecker, resourceImportDeclaratio
55
50
  ? visitComponentMetadata(nodeFactory, node, resourceImportDeclarations, moduleKind)
56
51
  : node);
57
52
  if (styleReplacements.length) {
58
- const styleProperty = useNodeFactory
59
- ? nodeFactory.createPropertyAssignment(nodeFactory.createIdentifier(constants_1.STYLES), nodeFactory.createArrayLiteralExpression(styleReplacements))
60
- : typescript_1.default.createPropertyAssignment(typescript_1.default.createIdentifier(constants_1.STYLES), typescript_1.default.createArrayLiteral(styleReplacements));
61
- properties = useNodeFactory
62
- ? nodeFactory.createNodeArray([...properties, styleProperty])
63
- : typescript_1.default.createNodeArray([...properties, styleProperty]);
53
+ const styleProperty = nodeFactory.createPropertyAssignment(nodeFactory.createIdentifier(constants_1.STYLES), nodeFactory.createArrayLiteralExpression(styleReplacements));
54
+ properties = nodeFactory.createNodeArray([...properties, styleProperty]);
64
55
  }
65
- return useNodeFactory
66
- ? nodeFactory.updateDecorator(node, nodeFactory.updateCallExpression(decoratorFactory, decoratorFactory.expression, decoratorFactory.typeArguments, [nodeFactory.updateObjectLiteralExpression(objectExpression, properties)]))
67
- : typescript_1.default.updateDecorator(node, typescript_1.default.updateCall(decoratorFactory, decoratorFactory.expression, decoratorFactory.typeArguments, [
68
- typescript_1.default.updateObjectLiteral(objectExpression, properties),
69
- ]));
56
+ return nodeFactory.updateDecorator(node, nodeFactory.updateCallExpression(decoratorFactory, decoratorFactory.expression, decoratorFactory.typeArguments, [
57
+ nodeFactory.updateObjectLiteralExpression(objectExpression, properties),
58
+ ]));
70
59
  }
71
60
  function visitComponentMetadata(nodeFactory, node, resourceImportDeclarations, moduleKind) {
72
61
  if (!typescript_1.default.isPropertyAssignment(node) || typescript_1.default.isComputedPropertyName(node.name)) {
@@ -85,9 +74,7 @@ function visitComponentMetadata(nodeFactory, node, resourceImportDeclarations, m
85
74
  if (!importName) {
86
75
  return node;
87
76
  }
88
- return useNodeFactory
89
- ? nodeFactory.updatePropertyAssignment(node, nodeFactory.createIdentifier(constants_1.TEMPLATE), importName)
90
- : typescript_1.default.updatePropertyAssignment(node, typescript_1.default.createIdentifier(constants_1.TEMPLATE), importName);
77
+ return nodeFactory.updatePropertyAssignment(node, nodeFactory.createIdentifier(constants_1.TEMPLATE), importName);
91
78
  case constants_1.STYLES:
92
79
  case constants_1.STYLE_URLS:
93
80
  if (!typescript_1.default.isArrayLiteralExpression(node.initializer)) {
@@ -112,17 +99,13 @@ function isComponentDecorator(node, typeChecker) {
112
99
  return !!(origin && origin.module === '@angular/core' && origin.name === constants_1.COMPONENT);
113
100
  }
114
101
  function createResourceImport(nodeFactory, url, resourceImportDeclarations, moduleKind = typescript_1.default.ModuleKind.ES2015) {
115
- const urlLiteral = useNodeFactory ? nodeFactory.createStringLiteral(url) : typescript_1.default.createLiteral(url);
102
+ const urlLiteral = nodeFactory.createStringLiteral(url);
116
103
  if (moduleKind < typescript_1.default.ModuleKind.ES2015) {
117
- return useNodeFactory
118
- ? nodeFactory.createCallExpression(nodeFactory.createIdentifier(constants_1.REQUIRE), [], [urlLiteral])
119
- : typescript_1.default.createCall(typescript_1.default.createIdentifier(constants_1.REQUIRE), undefined, [urlLiteral]);
104
+ return nodeFactory.createCallExpression(nodeFactory.createIdentifier(constants_1.REQUIRE), [], [urlLiteral]);
120
105
  }
121
106
  else {
122
107
  const importName = typescript_1.default.createIdentifier(`__NG_CLI_RESOURCE__${resourceImportDeclarations.length}`);
123
- const importDeclaration = useNodeFactory
124
- ? nodeFactory.createImportDeclaration(undefined, undefined, nodeFactory.createImportClause(false, importName, undefined), urlLiteral)
125
- : typescript_1.default.createImportDeclaration(undefined, undefined, typescript_1.default.createImportClause(importName, undefined), urlLiteral);
108
+ const importDeclaration = nodeFactory.createImportDeclaration(undefined, undefined, nodeFactory.createImportClause(false, importName, undefined), urlLiteral);
126
109
  resourceImportDeclarations.push(importDeclaration);
127
110
  return importName;
128
111
  }
@@ -2,42 +2,42 @@
2
2
  var _a;
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  const child_process_1 = require("child_process");
5
- const fs_1 = require("fs");
6
5
  const path_1 = require("path");
7
6
  const IGNORE_ARGS = ['--clearCache', '--help', '--init', '--listTests', '--showConfig'];
8
- const nodeModuleDirPath = findNodeModulesDirectory(process.cwd());
9
- const angularCorePkgPath = path_1.join(nodeModuleDirPath, '@angular', 'core');
10
- const canRunNgcc = !process.argv.find((arg) => IGNORE_ARGS.includes(arg)) && fs_1.existsSync(angularCorePkgPath);
11
- function findNodeModulesDirectory(startPoint) {
12
- let current = startPoint;
13
- while (path_1.dirname(current) !== current) {
14
- const nodePath = path_1.join(current, 'node_modules');
15
- if (fs_1.existsSync(nodePath)) {
16
- return nodePath;
17
- }
18
- current = path_1.dirname(current);
7
+ const ANGULAR_COMPILER_CLI_PKG_NAME = `@angular${path_1.sep}compiler-cli`;
8
+ const nodeModuleDirPath = findNodeModulesDirectory();
9
+ function findNodeModulesDirectory() {
10
+ let nodeModulesPath = '';
11
+ try {
12
+ const angularCompilerCLIPath = require.resolve(ANGULAR_COMPILER_CLI_PKG_NAME);
13
+ nodeModulesPath = angularCompilerCLIPath.substring(0, angularCompilerCLIPath.indexOf(ANGULAR_COMPILER_CLI_PKG_NAME));
19
14
  }
20
- throw new Error(`Cannot locate the 'node_modules' directory. Please make sure you are running jest from root level of your project`);
15
+ catch (_a) { }
16
+ return nodeModulesPath;
21
17
  }
22
- if (canRunNgcc) {
23
- process.stdout.write('ngcc-jest-processor: running ngcc\n');
24
- const { status, error } = child_process_1.spawnSync(process.execPath, [
25
- require.resolve('@angular/compiler-cli/ngcc/main-ngcc.js'),
26
- '--source',
27
- nodeModuleDirPath,
28
- '--properties',
29
- ...['es2015', 'main'],
30
- '--first-only',
31
- 'false',
32
- '--async',
33
- ], {
34
- stdio: ['inherit', process.stderr, process.stderr],
35
- });
36
- if (status !== 0) {
37
- const errorMessage = (_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : '';
38
- throw new Error(`${errorMessage} NGCC failed ${errorMessage ? ', see above' : ''}.`);
18
+ if (!process.argv.find((arg) => IGNORE_ARGS.includes(arg))) {
19
+ if (nodeModuleDirPath) {
20
+ process.stdout.write('ngcc-jest-processor: running ngcc\n');
21
+ const { status, error } = child_process_1.spawnSync(process.execPath, [
22
+ require.resolve('@angular/compiler-cli/ngcc/main-ngcc.js'),
23
+ '--source',
24
+ nodeModuleDirPath,
25
+ '--properties',
26
+ ...['es2015', 'main'],
27
+ '--first-only',
28
+ 'false',
29
+ '--async',
30
+ ], {
31
+ stdio: ['inherit', process.stderr, process.stderr],
32
+ });
33
+ if (status !== 0) {
34
+ const errorMessage = (_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : '';
35
+ throw new Error(`${errorMessage} NGCC failed ${errorMessage ? ', see above' : ''}.`);
36
+ }
37
+ }
38
+ else {
39
+ console.log(`Warning: Could not locate '@angular/compiler-cli' to run 'ngcc' automatically.` +
40
+ `Please make sure you are running 'ngcc-jest-processor.js' from root level of your project.` +
41
+ `'ngcc' must be run before running Jest`);
39
42
  }
40
- }
41
- else {
42
- throw new Error(`Cannot locate the '@angular/core' directory, resolved as ${angularCorePkgPath}. Please make sure you are running 'ngcc-jest-processor.js' from root level of your project`);
43
43
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jest-preset-angular",
3
- "version": "9.0.6",
3
+ "version": "10.1.0",
4
4
  "description": "Jest preset configuration for Angular projects",
5
5
  "license": "MIT",
6
6
  "main": "build/index.js",
@@ -28,11 +28,13 @@
28
28
  "prebuild": "node scripts/clean.js",
29
29
  "build": "tsc -p tsconfig.build.json",
30
30
  "lint": "eslint --ext .js,.ts .",
31
- "lint:fix": "eslint --fix --ext .js,.ts .",
32
- "lint:prettier": "prettier '**/*.{yml,yaml}' 'website/**/*.{css,js,md}' 'README.md' --write --ignore-path .gitignore",
33
- "lint:prettier-ci": "prettier '**/*.{yml,yaml}' 'website/**/*.{css,js,md}' 'README.md' --check --ignore-path .gitignore",
31
+ "lint-fix": "eslint --fix --ext .js,.ts .",
32
+ "lint-prettier": "prettier '**/*.{yml,yaml}' 'website/**/*.{css,js,md}' 'README.md' --write --ignore-path .gitignore",
33
+ "lint-prettier-ci": "prettier '**/*.{yml,yaml}' 'website/**/*.{css,js,md}' 'README.md' --check --ignore-path .gitignore",
34
34
  "test": "jest",
35
- "test:examples": "node scripts/test-examples.js",
35
+ "e2e-cjs": "jest -c=e2e/jest.config.js",
36
+ "e2e-esm": "cross-env NODE_OPTIONS=--experimental-vm-modules npx jest -c=e2e/jest-esm.config.js",
37
+ "test-examples": "node scripts/test-examples.js",
36
38
  "doc": "cd website && yarn start",
37
39
  "doc:build": "cd website && yarn build",
38
40
  "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 1",
@@ -46,45 +48,54 @@
46
48
  "ts-jest": "^27.0.0"
47
49
  },
48
50
  "peerDependencies": {
49
- "@angular/core": ">=9.0.0",
50
- "@angular/platform-browser-dynamic": ">=9.0.0"
51
+ "@angular/compiler-cli": ">=10.0.0",
52
+ "@angular/core": ">=10.0.0",
53
+ "@angular/platform-browser-dynamic": ">=10.0.0"
51
54
  },
52
55
  "devDependencies": {
53
- "@angular/common": "^11.2.14",
54
- "@angular/compiler": "^11.2.14",
55
- "@angular/compiler-cli": "^11.2.14",
56
- "@angular/core": "^11.2.14",
57
- "@angular/platform-browser": "^11.2.14",
58
- "@angular/platform-browser-dynamic": "^11.2.14",
59
- "@commitlint/cli": "^12.1.4",
60
- "@commitlint/config-angular": "^12.1.4",
61
- "@jest/globals": "^27.0.6",
62
- "@jest/transform": "^27.0.6",
63
- "@jest/types": "^27.0.6",
64
- "@types/jest": "^26.0.24",
65
- "@types/node": "^14.17.5",
66
- "@types/semver": "^7.3.7",
67
- "@typescript-eslint/eslint-plugin": "^4.28.4",
68
- "@typescript-eslint/parser": "^4.28.4",
56
+ "@angular/animations": "^12.2.11",
57
+ "@angular/cdk": "^12.2.11",
58
+ "@angular/common": "^12.2.11",
59
+ "@angular/compiler": "^12.2.11",
60
+ "@angular/compiler-cli": "^12.2.11",
61
+ "@angular/core": "^12.2.11",
62
+ "@angular/forms": "^12.2.11",
63
+ "@angular/material": "^12.2.11",
64
+ "@angular/platform-browser": "^12.2.11",
65
+ "@angular/platform-browser-dynamic": "^12.2.11",
66
+ "@babel/core": "^7.15.5",
67
+ "@babel/preset-env": "^7.15.6",
68
+ "@commitlint/cli": "^13.1.0",
69
+ "@commitlint/config-angular": "^13.1.0",
70
+ "@jest/globals": "^27.3.0",
71
+ "@jest/transform": "^27.3.0",
72
+ "@jest/types": "^27.2.5",
73
+ "@types/jest": "^27.0.2",
74
+ "@types/jquery": "^3.5.6",
75
+ "@types/node": "^16.9.4",
76
+ "@typescript-eslint/eslint-plugin": "^4.31.2",
77
+ "@typescript-eslint/parser": "^4.31.2",
78
+ "babel-jest": "^27.3.1",
69
79
  "conventional-changelog-cli": "^2.1.1",
70
- "eslint": "^7.31.0",
80
+ "cross-env": "^7.0.3",
81
+ "eslint": "^7.32.0",
71
82
  "eslint-config-prettier": "^8.3.0",
72
- "eslint-plugin-import": "^2.23.4",
73
- "eslint-plugin-jest": "^24.4.0",
74
- "eslint-plugin-jsdoc": "^35.5.0",
83
+ "eslint-plugin-import": "^2.25.2",
84
+ "eslint-plugin-jest": "^25.2.2",
85
+ "eslint-plugin-jsdoc": "^37.0.0",
75
86
  "eslint-plugin-prefer-arrow": "^1.2.3",
76
- "eslint-plugin-prettier": "^3.4.0",
87
+ "eslint-plugin-prettier": "^4.0.0",
77
88
  "execa": "^5.1.1",
89
+ "fs-extra": "^10.0.0",
78
90
  "glob": "^7.1.7",
79
- "glob-gitignore": "^1.0.14",
80
- "husky": "^7.0.1",
81
- "jest": "^27.0.6",
91
+ "husky": "^7.0.2",
92
+ "jest": "^27.3.1",
82
93
  "jest-snapshot-serializer-raw": "^1.2.0",
83
94
  "pinst": "^2.1.6",
84
- "prettier": "^2.3.2",
85
- "rxjs": "^6.6.7",
95
+ "prettier": "^2.4.1",
96
+ "rxjs": "^7.3.0",
86
97
  "tslib": "^2.2.0",
87
- "typescript": "~4.1.6",
98
+ "typescript": "~4.3.5",
88
99
  "zone.js": "^0.11.4"
89
100
  },
90
101
  "engines": {
@@ -1,321 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.constructorDownlevelCtor = void 0;
4
- const tslib_1 = require("tslib");
5
- const reflection_1 = require("@angular/compiler-cli/src/ngtsc/reflection");
6
- const typescript_1 = tslib_1.__importDefault(require("typescript"));
7
- const patch_alias_reference_resolution_1 = require("./patch-alias-reference-resolution");
8
- function constructorDownlevelCtor({ program }) {
9
- const typeChecker = program.getTypeChecker();
10
- const reflectionHost = new reflection_1.TypeScriptReflectionHost(typeChecker);
11
- return getDownlevelDecoratorsTransform(typeChecker, reflectionHost, [], false, false, true);
12
- }
13
- exports.constructorDownlevelCtor = constructorDownlevelCtor;
14
- function isAngularDecorator(decorator, isCore) {
15
- return isCore || (decorator.import !== null && decorator.import.from === '@angular/core');
16
- }
17
- function createDecoratorInvocationType() {
18
- const typeElements = [];
19
- typeElements.push(typescript_1.default.createPropertySignature(undefined, 'type', undefined, typescript_1.default.createTypeReferenceNode(typescript_1.default.createIdentifier('Function'), undefined), undefined));
20
- typeElements.push(typescript_1.default.createPropertySignature(undefined, 'args', typescript_1.default.createToken(typescript_1.default.SyntaxKind.QuestionToken), typescript_1.default.createArrayTypeNode(typescript_1.default.createKeywordTypeNode(typescript_1.default.SyntaxKind.AnyKeyword)), undefined));
21
- return typescript_1.default.createArrayTypeNode(typescript_1.default.createTypeLiteralNode(typeElements));
22
- }
23
- function extractMetadataFromSingleDecorator(decorator, diagnostics) {
24
- const metadataProperties = [];
25
- const expr = decorator.expression;
26
- switch (expr.kind) {
27
- case typescript_1.default.SyntaxKind.Identifier:
28
- metadataProperties.push(typescript_1.default.createPropertyAssignment('type', expr));
29
- break;
30
- case typescript_1.default.SyntaxKind.CallExpression:
31
- const call = expr;
32
- metadataProperties.push(typescript_1.default.createPropertyAssignment('type', call.expression));
33
- if (call.arguments.length) {
34
- const args = [];
35
- for (const arg of call.arguments) {
36
- args.push(arg);
37
- }
38
- const argsArrayLiteral = typescript_1.default.createArrayLiteral(args);
39
- argsArrayLiteral.elements.hasTrailingComma = true;
40
- metadataProperties.push(typescript_1.default.createPropertyAssignment('args', argsArrayLiteral));
41
- }
42
- break;
43
- default:
44
- diagnostics.push({
45
- file: decorator.getSourceFile(),
46
- start: decorator.getStart(),
47
- length: decorator.getEnd() - decorator.getStart(),
48
- messageText: `${typescript_1.default.SyntaxKind[decorator.kind]} not implemented in gathering decorator metadata.`,
49
- category: typescript_1.default.DiagnosticCategory.Error,
50
- code: 0,
51
- });
52
- break;
53
- }
54
- return typescript_1.default.createObjectLiteral(metadataProperties);
55
- }
56
- function createDecoratorClassProperty(decoratorList) {
57
- const modifier = typescript_1.default.createToken(typescript_1.default.SyntaxKind.StaticKeyword);
58
- const type = createDecoratorInvocationType();
59
- const initializer = typescript_1.default.createArrayLiteral(decoratorList, true);
60
- return typescript_1.default.createProperty(undefined, [modifier], 'decorators', undefined, type, initializer);
61
- }
62
- function createCtorParametersClassPropertyType() {
63
- const typeElements = [];
64
- typeElements.push(typescript_1.default.createPropertySignature(undefined, 'type', undefined, typescript_1.default.createTypeReferenceNode(typescript_1.default.createIdentifier('any'), undefined), undefined));
65
- typeElements.push(typescript_1.default.createPropertySignature(undefined, 'decorators', typescript_1.default.createToken(typescript_1.default.SyntaxKind.QuestionToken), typescript_1.default.createArrayTypeNode(typescript_1.default.createTypeLiteralNode([
66
- typescript_1.default.createPropertySignature(undefined, 'type', undefined, typescript_1.default.createTypeReferenceNode(typescript_1.default.createIdentifier('Function'), undefined), undefined),
67
- typescript_1.default.createPropertySignature(undefined, 'args', typescript_1.default.createToken(typescript_1.default.SyntaxKind.QuestionToken), typescript_1.default.createArrayTypeNode(typescript_1.default.createTypeReferenceNode(typescript_1.default.createIdentifier('any'), undefined)), undefined),
68
- ])), undefined));
69
- return typescript_1.default.createFunctionTypeNode(undefined, [], typescript_1.default.createArrayTypeNode(typescript_1.default.createUnionTypeNode([typescript_1.default.createTypeLiteralNode(typeElements), typescript_1.default.createLiteralTypeNode(typescript_1.default.createNull())])));
70
- }
71
- function addNoCollapseComment(n) {
72
- typescript_1.default.setSyntheticLeadingComments(n, [
73
- {
74
- kind: typescript_1.default.SyntaxKind.MultiLineCommentTrivia,
75
- text: '* @nocollapse ',
76
- pos: -1,
77
- end: -1,
78
- hasTrailingNewLine: true,
79
- },
80
- ]);
81
- }
82
- function createCtorParametersClassProperty(diagnostics, entityNameToExpression, ctorParameters, isClosureCompilerEnabled) {
83
- const params = [];
84
- for (const ctorParam of ctorParameters) {
85
- if (!ctorParam.type && ctorParam.decorators.length === 0) {
86
- params.push(typescript_1.default.createNull());
87
- continue;
88
- }
89
- const paramType = ctorParam.type ? typeReferenceToExpression(entityNameToExpression, ctorParam.type) : undefined;
90
- const members = [typescript_1.default.createPropertyAssignment('type', paramType || typescript_1.default.createIdentifier('undefined'))];
91
- const decorators = [];
92
- for (const deco of ctorParam.decorators) {
93
- decorators.push(extractMetadataFromSingleDecorator(deco, diagnostics));
94
- }
95
- if (decorators.length) {
96
- members.push(typescript_1.default.createPropertyAssignment('decorators', typescript_1.default.createArrayLiteral(decorators)));
97
- }
98
- params.push(typescript_1.default.createObjectLiteral(members));
99
- }
100
- const initializer = typescript_1.default.createArrowFunction(undefined, undefined, [], undefined, typescript_1.default.createToken(typescript_1.default.SyntaxKind.EqualsGreaterThanToken), typescript_1.default.createArrayLiteral(params, true));
101
- const type = createCtorParametersClassPropertyType();
102
- const ctorProp = typescript_1.default.createProperty(undefined, [typescript_1.default.createToken(typescript_1.default.SyntaxKind.StaticKeyword)], 'ctorParameters', undefined, type, initializer);
103
- if (isClosureCompilerEnabled) {
104
- addNoCollapseComment(ctorProp);
105
- }
106
- return ctorProp;
107
- }
108
- function createPropDecoratorsClassProperty(diagnostics, properties) {
109
- const entries = [];
110
- for (const [name, decorators] of properties.entries()) {
111
- entries.push(typescript_1.default.createPropertyAssignment(name, typescript_1.default.createArrayLiteral(decorators.map((deco) => extractMetadataFromSingleDecorator(deco, diagnostics)))));
112
- }
113
- const initializer = typescript_1.default.createObjectLiteral(entries, true);
114
- const type = typescript_1.default.createTypeLiteralNode([
115
- typescript_1.default.createIndexSignature(undefined, undefined, [
116
- typescript_1.default.createParameter(undefined, undefined, undefined, 'key', undefined, typescript_1.default.createTypeReferenceNode('string', undefined), undefined),
117
- ], createDecoratorInvocationType()),
118
- ]);
119
- return typescript_1.default.createProperty(undefined, [typescript_1.default.createToken(typescript_1.default.SyntaxKind.StaticKeyword)], 'propDecorators', undefined, type, initializer);
120
- }
121
- function typeReferenceToExpression(entityNameToExpression, node) {
122
- let kind = node.kind;
123
- if (typescript_1.default.isLiteralTypeNode(node)) {
124
- kind = node.literal.kind;
125
- }
126
- switch (kind) {
127
- case typescript_1.default.SyntaxKind.FunctionType:
128
- case typescript_1.default.SyntaxKind.ConstructorType:
129
- return typescript_1.default.createIdentifier('Function');
130
- case typescript_1.default.SyntaxKind.ArrayType:
131
- case typescript_1.default.SyntaxKind.TupleType:
132
- return typescript_1.default.createIdentifier('Array');
133
- case typescript_1.default.SyntaxKind.TypePredicate:
134
- case typescript_1.default.SyntaxKind.TrueKeyword:
135
- case typescript_1.default.SyntaxKind.FalseKeyword:
136
- case typescript_1.default.SyntaxKind.BooleanKeyword:
137
- return typescript_1.default.createIdentifier('Boolean');
138
- case typescript_1.default.SyntaxKind.StringLiteral:
139
- case typescript_1.default.SyntaxKind.StringKeyword:
140
- return typescript_1.default.createIdentifier('String');
141
- case typescript_1.default.SyntaxKind.ObjectKeyword:
142
- return typescript_1.default.createIdentifier('Object');
143
- case typescript_1.default.SyntaxKind.NumberKeyword:
144
- case typescript_1.default.SyntaxKind.NumericLiteral:
145
- return typescript_1.default.createIdentifier('Number');
146
- case typescript_1.default.SyntaxKind.TypeReference:
147
- const typeRef = node;
148
- return entityNameToExpression(typeRef.typeName);
149
- case typescript_1.default.SyntaxKind.UnionType:
150
- const childTypeNodes = node.types.filter((t) => !(typescript_1.default.isLiteralTypeNode(t) && t.literal.kind === typescript_1.default.SyntaxKind.NullKeyword));
151
- return childTypeNodes.length === 1
152
- ? typeReferenceToExpression(entityNameToExpression, childTypeNodes[0])
153
- : undefined;
154
- default:
155
- return undefined;
156
- }
157
- }
158
- function symbolIsRuntimeValue(typeChecker, symbol) {
159
- if (symbol.flags & typescript_1.default.SymbolFlags.Alias) {
160
- symbol = typeChecker.getAliasedSymbol(symbol);
161
- }
162
- return (symbol.flags & typescript_1.default.SymbolFlags.Value & typescript_1.default.SymbolFlags.ConstEnumExcludes) !== 0;
163
- }
164
- function getDownlevelDecoratorsTransform(typeChecker, host, diagnostics, isCore, isClosureCompilerEnabled, skipClassDecorators) {
165
- return (context) => {
166
- const referencedParameterTypes = patch_alias_reference_resolution_1.loadIsReferencedAliasDeclarationPatch(context);
167
- function entityNameToExpression(name) {
168
- const symbol = typeChecker.getSymbolAtLocation(name);
169
- if (!symbol ||
170
- !symbolIsRuntimeValue(typeChecker, symbol) ||
171
- !symbol.declarations ||
172
- symbol.declarations.length === 0) {
173
- return undefined;
174
- }
175
- if (typescript_1.default.isQualifiedName(name)) {
176
- const containerExpr = entityNameToExpression(name.left);
177
- if (containerExpr === undefined) {
178
- return undefined;
179
- }
180
- return typescript_1.default.createPropertyAccess(containerExpr, name.right);
181
- }
182
- const decl = symbol.declarations[0];
183
- if (patch_alias_reference_resolution_1.isAliasImportDeclaration(decl)) {
184
- referencedParameterTypes.add(decl);
185
- if (decl.name !== undefined) {
186
- return typescript_1.default.getMutableClone(decl.name);
187
- }
188
- }
189
- return typescript_1.default.getMutableClone(name);
190
- }
191
- function transformClassElement(element) {
192
- element = typescript_1.default.visitEachChild(element, decoratorDownlevelVisitor, context);
193
- const decoratorsToKeep = [];
194
- const toLower = [];
195
- const decorators = host.getDecoratorsOfDeclaration(element) || [];
196
- for (const decorator of decorators) {
197
- const decoratorNode = decorator.node;
198
- if (!isAngularDecorator(decorator, isCore)) {
199
- decoratorsToKeep.push(decoratorNode);
200
- continue;
201
- }
202
- toLower.push(decoratorNode);
203
- }
204
- if (!toLower.length)
205
- return [undefined, element, []];
206
- if (!element.name || !typescript_1.default.isIdentifier(element.name)) {
207
- diagnostics.push({
208
- file: element.getSourceFile(),
209
- start: element.getStart(),
210
- length: element.getEnd() - element.getStart(),
211
- messageText: `Cannot process decorators for class element with non-analyzable name.`,
212
- category: typescript_1.default.DiagnosticCategory.Error,
213
- code: 0,
214
- });
215
- return [undefined, element, []];
216
- }
217
- const name = element.name.text;
218
- const mutable = typescript_1.default.getMutableClone(element);
219
- mutable.decorators = decoratorsToKeep.length
220
- ? typescript_1.default.setTextRange(typescript_1.default.createNodeArray(decoratorsToKeep), mutable.decorators)
221
- : undefined;
222
- return [name, mutable, toLower];
223
- }
224
- function transformConstructor(ctor) {
225
- ctor = typescript_1.default.visitEachChild(ctor, decoratorDownlevelVisitor, context);
226
- const newParameters = [];
227
- const oldParameters = typescript_1.default.visitParameterList(ctor.parameters, decoratorDownlevelVisitor, context);
228
- const parametersInfo = [];
229
- for (const param of oldParameters) {
230
- const decoratorsToKeep = [];
231
- const paramInfo = { decorators: [], type: null };
232
- const decorators = host.getDecoratorsOfDeclaration(param) || [];
233
- for (const decorator of decorators) {
234
- const decoratorNode = decorator.node;
235
- if (!isAngularDecorator(decorator, isCore)) {
236
- decoratorsToKeep.push(decoratorNode);
237
- continue;
238
- }
239
- paramInfo.decorators.push(decoratorNode);
240
- }
241
- if (param.type) {
242
- paramInfo.type = param.type;
243
- }
244
- parametersInfo.push(paramInfo);
245
- const newParam = typescript_1.default.updateParameter(param, decoratorsToKeep.length ? decoratorsToKeep : undefined, param.modifiers, param.dotDotDotToken, param.name, param.questionToken, param.type, param.initializer);
246
- newParameters.push(newParam);
247
- }
248
- const updated = typescript_1.default.updateConstructor(ctor, ctor.decorators, ctor.modifiers, newParameters, typescript_1.default.visitFunctionBody(ctor.body, decoratorDownlevelVisitor, context));
249
- return [updated, parametersInfo];
250
- }
251
- function transformClassDeclaration(classDecl) {
252
- classDecl = typescript_1.default.getMutableClone(classDecl);
253
- const newMembers = [];
254
- const decoratedProperties = new Map();
255
- let classParameters = null;
256
- for (const member of classDecl.members) {
257
- switch (member.kind) {
258
- case typescript_1.default.SyntaxKind.PropertyDeclaration:
259
- case typescript_1.default.SyntaxKind.GetAccessor:
260
- case typescript_1.default.SyntaxKind.SetAccessor:
261
- case typescript_1.default.SyntaxKind.MethodDeclaration: {
262
- const [name, newMember, decorators] = transformClassElement(member);
263
- newMembers.push(newMember);
264
- if (name)
265
- decoratedProperties.set(name, decorators);
266
- continue;
267
- }
268
- case typescript_1.default.SyntaxKind.Constructor: {
269
- const ctor = member;
270
- if (!ctor.body)
271
- break;
272
- const [newMember, parametersInfo] = transformConstructor(member);
273
- classParameters = parametersInfo;
274
- newMembers.push(newMember);
275
- continue;
276
- }
277
- default:
278
- break;
279
- }
280
- newMembers.push(typescript_1.default.visitEachChild(member, decoratorDownlevelVisitor, context));
281
- }
282
- const decoratorsToKeep = new Set(classDecl.decorators);
283
- const possibleAngularDecorators = host.getDecoratorsOfDeclaration(classDecl) || [];
284
- let hasAngularDecorator = false;
285
- const decoratorsToLower = [];
286
- for (const decorator of possibleAngularDecorators) {
287
- const decoratorNode = decorator.node;
288
- const isNgDecorator = isAngularDecorator(decorator, isCore);
289
- if (isNgDecorator) {
290
- hasAngularDecorator = true;
291
- }
292
- if (isNgDecorator && !skipClassDecorators) {
293
- decoratorsToLower.push(extractMetadataFromSingleDecorator(decoratorNode, diagnostics));
294
- decoratorsToKeep.delete(decoratorNode);
295
- }
296
- }
297
- if (decoratorsToLower.length) {
298
- newMembers.push(createDecoratorClassProperty(decoratorsToLower));
299
- }
300
- if (classParameters) {
301
- if (hasAngularDecorator || classParameters.some((p) => !!p.decorators.length)) {
302
- newMembers.push(createCtorParametersClassProperty(diagnostics, entityNameToExpression, classParameters, isClosureCompilerEnabled));
303
- }
304
- }
305
- if (decoratedProperties.size) {
306
- newMembers.push(createPropDecoratorsClassProperty(diagnostics, decoratedProperties));
307
- }
308
- const members = typescript_1.default.setTextRange(typescript_1.default.createNodeArray(newMembers, classDecl.members.hasTrailingComma), classDecl.members);
309
- return typescript_1.default.updateClassDeclaration(classDecl, decoratorsToKeep.size ? Array.from(decoratorsToKeep) : undefined, classDecl.modifiers, classDecl.name, classDecl.typeParameters, classDecl.heritageClauses, members);
310
- }
311
- function decoratorDownlevelVisitor(node) {
312
- if (typescript_1.default.isClassDeclaration(node)) {
313
- return transformClassDeclaration(node);
314
- }
315
- return typescript_1.default.visitEachChild(node, decoratorDownlevelVisitor, context);
316
- }
317
- return (sf) => {
318
- return typescript_1.default.visitEachChild(sf, decoratorDownlevelVisitor, context);
319
- };
320
- };
321
- }
@@ -1,43 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isAliasImportDeclaration = exports.loadIsReferencedAliasDeclarationPatch = void 0;
4
- const tslib_1 = require("tslib");
5
- const typescript_1 = tslib_1.__importDefault(require("typescript"));
6
- const patchedReferencedAliasesSymbol = Symbol('patchedReferencedAliases');
7
- function loadIsReferencedAliasDeclarationPatch(context) {
8
- if (!isTransformationContextWithEmitResolver(context)) {
9
- throwIncompatibleTransformationContextError();
10
- }
11
- const emitResolver = context.getEmitResolver();
12
- const existingReferencedAliases = emitResolver[patchedReferencedAliasesSymbol];
13
- if (existingReferencedAliases !== undefined) {
14
- return existingReferencedAliases;
15
- }
16
- const originalIsReferencedAliasDeclaration = emitResolver.isReferencedAliasDeclaration;
17
- if (originalIsReferencedAliasDeclaration === undefined) {
18
- throwIncompatibleTransformationContextError();
19
- }
20
- const referencedAliases = new Set();
21
- emitResolver.isReferencedAliasDeclaration = function (node, ...args) {
22
- if (isAliasImportDeclaration(node) && referencedAliases.has(node)) {
23
- return true;
24
- }
25
- return originalIsReferencedAliasDeclaration.call(emitResolver, node, ...args);
26
- };
27
- return (emitResolver[patchedReferencedAliasesSymbol] = referencedAliases);
28
- }
29
- exports.loadIsReferencedAliasDeclarationPatch = loadIsReferencedAliasDeclarationPatch;
30
- function isAliasImportDeclaration(node) {
31
- return typescript_1.default.isImportSpecifier(node) || typescript_1.default.isNamespaceImport(node) || typescript_1.default.isImportClause(node);
32
- }
33
- exports.isAliasImportDeclaration = isAliasImportDeclaration;
34
- function isTransformationContextWithEmitResolver(context) {
35
- return context.getEmitResolver !== undefined;
36
- }
37
- function throwIncompatibleTransformationContextError() {
38
- throw Error('Unable to downlevel Angular decorators due to an incompatible TypeScript ' +
39
- 'version.\nIf you recently updated TypeScript and this issue surfaces now, consider ' +
40
- 'downgrading.\n\n' +
41
- 'Please report an issue on the Angular repositories when this issue ' +
42
- 'surfaces and you are using a supposedly compatible TypeScript version.');
43
- }