Alan Agius d133ba68c0 feat(@angular/cli): add support for ng-add packages that should not be saved as dependencies
With this change the CLI offers a way for a package authors to specify if during `ng add` the package should be saved as a `dependencies`, `devDependencies` or not saved at all.

Such config needs to be specified in `package.json`

Example:
```json
  "ng-add": {
    "save": false
  }
```

Possible values are;
- false - Don't add the package to `package.json`
- true - Add the package to the `dependencies`
- `dependencies` - Add the package to the `dependencies`
- `devDependencies` - Add the package to the `devDependencies`

Closes #12003 , closes #15764 and closes #13237
2019-10-14 13:40:31 -07:00

94 lines
2.2 KiB
TypeScript

/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import { NgAddSaveDepedency } from './package-metadata';
export interface PackageTreeNodeBase {
name: string;
path: string;
realpath: string;
error?: Error;
id: number;
isLink: boolean;
package: {
name: string;
version: string;
dependencies?: Record<string, string>;
devDependencies?: Record<string, string>;
peerDependencies?: Record<string, string>;
optionalDependencies?: Record<string, string>;
'ng-update'?: {
migrations?: string;
};
'ng-add'?: {
save?: NgAddSaveDepedency;
};
};
parent?: PackageTreeNode;
children: PackageTreeNode[];
}
export interface PackageTreeActual extends PackageTreeNodeBase {
isLink: false;
}
export interface PackageTreeLink extends PackageTreeNodeBase {
isLink: true;
target: PackageTreeActual;
}
export type PackageTreeNode = PackageTreeActual | PackageTreeLink;
export function readPackageTree(path: string): Promise<PackageTreeNode> {
const rpt = require('read-package-tree');
return new Promise((resolve, reject) => {
rpt(path, (e: Error | undefined, data: PackageTreeNode) => {
if (e) {
reject(e);
} else {
resolve(data);
}
});
});
}
export interface NodeDependency {
version: string;
node?: PackageTreeNode;
}
export function findNodeDependencies(node: PackageTreeNode) {
const rawDeps: Record<string, string> = {
...node.package.dependencies,
...node.package.devDependencies,
...node.package.peerDependencies,
...node.package.optionalDependencies,
};
return Object.entries(rawDeps).reduce(
(deps, [name, version]) => {
let dependencyNode;
let parent: PackageTreeNode | undefined | null = node;
while (!dependencyNode && parent) {
dependencyNode = parent.children.find(child => child.name === name);
parent = parent.parent;
}
deps[name] = {
node: dependencyNode,
version,
};
return deps;
},
Object.create(null) as Record<string, NodeDependency>,
);
}