-
-
Notifications
You must be signed in to change notification settings - Fork 197
/
Copy pathpacote-service.ts
96 lines (78 loc) · 3.83 KB
/
pacote-service.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import * as pacote from "pacote";
import * as tar from "tar";
import * as path from "path";
import { cache } from "../common/decorators";
export class PacoteService implements IPacoteService {
constructor(private $fs: IFileSystem,
private $injector: IInjector,
private $logger: ILogger,
private $npmConfigService: INpmConfigService,
private $proxyService: IProxyService) {
}
@cache()
public get $packageManager(): INodePackageManager {
// need to be resolved here due to cyclic dependency
return this.$injector.resolve("packageManager");
}
public async manifest(packageName: string, options?: IPacoteManifestOptions): Promise<any> {
this.$logger.trace(`Calling pacoteService.manifest for packageName: '${packageName}' and options: ${options}`);
const manifestOptions: IPacoteBaseOptions = await this.getPacoteBaseOptions();
if (options) {
_.extend(manifestOptions, options);
}
packageName = this.getRealPackageName(packageName);
this.$logger.trace(`Calling pacote.manifest for packageName: ${packageName} and options: ${JSON.stringify(manifestOptions, null, 2)}`);
const result = pacote.manifest(packageName, manifestOptions);
return result;
}
public async extractPackage(packageName: string, destinationDirectory: string, options?: IPacoteExtractOptions): Promise<void> {
// strip: Remove the specified number of leading path elements. Pathnames with fewer elements will be silently skipped. More info: https://github.com/npm/node-tar/blob/e89c4d37519b1c20133a9f49d5f6b85fa34c203b/README.md
// C: Create an archive
this.$logger.trace(`Calling pacoteService.extractPackage for packageName: '${packageName}', destinationDir: '${destinationDirectory}' and options: ${options}`);
const extractOptions = { strip: 1, C: destinationDirectory };
if (options) {
_.extend(extractOptions, options);
}
packageName = this.getRealPackageName(packageName);
const pacoteOptions = await this.getPacoteBaseOptions();
return new Promise<void>((resolve, reject) => {
this.$logger.trace(`Calling pacoteService.extractPackage for packageName: '${packageName}', destinationDir: '${destinationDirectory}' and options: ${options}`);
const source = pacote.tarball.stream(packageName, pacoteOptions);
source.on("error", (err: Error) => {
this.$logger.trace(`Error in source while trying to extract stream from ${packageName}. Error is ${err}`);
reject(err);
});
this.$logger.trace(`Creating extract tar stream with options: ${JSON.stringify(extractOptions, null, 2)}`);
const destination = tar.x(extractOptions);
source.pipe(destination);
destination.on("error", (err: Error) => {
this.$logger.trace(`Error in destination while trying to extract stream from ${packageName}. Error is ${err}`);
reject(err);
});
destination.on("finish", () => {
this.$logger.trace(`Successfully extracted '${packageName}' to ${destinationDirectory}`);
resolve();
});
});
}
private async getPacoteBaseOptions(): Promise<IPacoteBaseOptions> {
// In case `tns create myapp --template https://github.com/NativeScript/template-hello-world.git` command is executed, pacote module throws an error if cache option is not provided.
const cachePath = await this.$packageManager.getCachePath();
// Add NPM Configuration to our Manifest options
const npmConfig = this.$npmConfigService.getConfig();
const pacoteOptions = _.extend(npmConfig, { cache: cachePath });
const proxySettings = await this.$proxyService.getCache();
if (proxySettings) {
_.extend(pacoteOptions, proxySettings);
}
return pacoteOptions;
}
private getRealPackageName(packageName: string): string {
if (this.$fs.exists(packageName)) {
this.$logger.trace(`Will resolve the full path to package ${packageName}.`);
packageName = path.resolve(packageName);
}
return packageName;
}
}
$injector.register("pacoteService", PacoteService);