jspm 2.0.0-beta.7 → 3.0.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/LICENSE +201 -201
- package/README.md +26 -32
- package/dist/cli.js +1391 -0
- package/jspm.js +10 -0
- package/package.json +32 -60
- package/CHANGELOG.md +0 -25
- package/bin/jspm +0 -46
- package/lib/api.d.ts +0 -10
- package/lib/api.js +0 -71
- package/lib/api.js.map +0 -1
- package/lib/build/index.d.ts +0 -24
- package/lib/build/index.js +0 -163
- package/lib/build/index.js.map +0 -1
- package/lib/cli.d.ts +0 -1
- package/lib/cli.js +0 -701
- package/lib/cli.js.map +0 -1
- package/lib/compile/cjs-convert.d.ts +0 -7
- package/lib/compile/cjs-convert.js +0 -375
- package/lib/compile/cjs-convert.js.map +0 -1
- package/lib/compile/dew-resolve.d.ts +0 -9
- package/lib/compile/dew-resolve.js +0 -117
- package/lib/compile/dew-resolve.js.map +0 -1
- package/lib/compile/dew-worker.d.ts +0 -1
- package/lib/compile/dew-worker.js +0 -302
- package/lib/compile/dew-worker.js.map +0 -1
- package/lib/config/config-file.d.ts +0 -67
- package/lib/config/config-file.js +0 -591
- package/lib/config/config-file.js.map +0 -1
- package/lib/config/global-config-file.d.ts +0 -8
- package/lib/config/global-config-file.js +0 -89
- package/lib/config/global-config-file.js.map +0 -1
- package/lib/config/index.d.ts +0 -15
- package/lib/config/index.js +0 -59
- package/lib/config/index.js.map +0 -1
- package/lib/config/jspm-file.d.ts +0 -8
- package/lib/config/jspm-file.js +0 -84
- package/lib/config/jspm-file.js.map +0 -1
- package/lib/config/package-json-file.d.ts +0 -49
- package/lib/config/package-json-file.js +0 -332
- package/lib/config/package-json-file.js.map +0 -1
- package/lib/exec/index.d.ts +0 -12
- package/lib/exec/index.js +0 -117
- package/lib/exec/index.js.map +0 -1
- package/lib/install/bin.d.ts +0 -2
- package/lib/install/bin.js +0 -85
- package/lib/install/bin.js.map +0 -1
- package/lib/install/binary-build.d.ts +0 -2
- package/lib/install/binary-build.js +0 -89
- package/lib/install/binary-build.js.map +0 -1
- package/lib/install/fetch.d.ts +0 -53
- package/lib/install/fetch.js +0 -270
- package/lib/install/fetch.js.map +0 -1
- package/lib/install/index.d.ts +0 -66
- package/lib/install/index.js +0 -1164
- package/lib/install/index.js.map +0 -1
- package/lib/install/package.d.ts +0 -142
- package/lib/install/package.js +0 -625
- package/lib/install/package.js.map +0 -1
- package/lib/install/publish.d.ts +0 -14
- package/lib/install/publish.js +0 -186
- package/lib/install/publish.js.map +0 -1
- package/lib/install/registry-manager.d.ts +0 -134
- package/lib/install/registry-manager.js +0 -521
- package/lib/install/registry-manager.js.map +0 -1
- package/lib/install/source.d.ts +0 -10
- package/lib/install/source.js +0 -378
- package/lib/install/source.js.map +0 -1
- package/lib/map/common.d.ts +0 -12
- package/lib/map/common.js +0 -182
- package/lib/map/common.js.map +0 -1
- package/lib/map/esm-lexer.d.ts +0 -17
- package/lib/map/esm-lexer.js +0 -506
- package/lib/map/esm-lexer.js.map +0 -1
- package/lib/map/index.d.ts +0 -15
- package/lib/map/index.js +0 -336
- package/lib/map/index.js.map +0 -1
- package/lib/map/utils.d.ts +0 -10
- package/lib/map/utils.js +0 -169
- package/lib/map/utils.js.map +0 -1
- package/lib/overrides.d.ts +0 -3
- package/lib/overrides.js +0 -29
- package/lib/overrides.js.map +0 -1
- package/lib/project.d.ts +0 -71
- package/lib/project.js +0 -434
- package/lib/project.js.map +0 -1
- package/lib/utils/cache.d.ts +0 -11
- package/lib/utils/cache.js +0 -121
- package/lib/utils/cache.js.map +0 -1
- package/lib/utils/common.d.ts +0 -55
- package/lib/utils/common.js +0 -267
- package/lib/utils/common.js.map +0 -1
- package/lib/utils/opts.d.ts +0 -6
- package/lib/utils/opts.js +0 -200
- package/lib/utils/opts.js.map +0 -1
- package/lib/utils/run-cmd.d.ts +0 -4
- package/lib/utils/run-cmd.js +0 -39
- package/lib/utils/run-cmd.js.map +0 -1
- package/lib/utils/ui.d.ts +0 -38
- package/lib/utils/ui.js +0 -496
- package/lib/utils/ui.js.map +0 -1
package/lib/install/index.js
DELETED
|
@@ -1,1164 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/*
|
|
3
|
-
* Copyright 2014-2019 Guy Bedford (http://guybedford.com)
|
|
4
|
-
*
|
|
5
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
-
* you may not use this file except in compliance with the License.
|
|
7
|
-
* You may obtain a copy of the License at
|
|
8
|
-
*
|
|
9
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
-
*
|
|
11
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
-
* See the License for the specific language governing permissions and
|
|
15
|
-
* limitations under the License.
|
|
16
|
-
*/
|
|
17
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
-
const sver_1 = require("sver");
|
|
19
|
-
const path = require("path");
|
|
20
|
-
const package_1 = require("./package");
|
|
21
|
-
const common_1 = require("../utils/common");
|
|
22
|
-
const fs = require("graceful-fs");
|
|
23
|
-
const ncp = require("ncp");
|
|
24
|
-
const rimraf = require("rimraf");
|
|
25
|
-
const mkdirp = require("mkdirp");
|
|
26
|
-
const bin_1 = require("./bin");
|
|
27
|
-
const overrides_1 = require("../overrides");
|
|
28
|
-
const fileInstallRegEx = /^(\.[\/\\]|\.\.[\/\\]|\/|\\|~[\/\\])/;
|
|
29
|
-
class Installer {
|
|
30
|
-
constructor(project) {
|
|
31
|
-
this.project = project;
|
|
32
|
-
this.config = project.config;
|
|
33
|
-
this.registryManager = project.registryManager;
|
|
34
|
-
// cache information associated with the current jspm project
|
|
35
|
-
// keyed by package path -> package info
|
|
36
|
-
this.jspmPackageInstallStateCache = {};
|
|
37
|
-
this.binFolderChecked = false;
|
|
38
|
-
this.sourceInstalls = {};
|
|
39
|
-
this.installs = {};
|
|
40
|
-
this.primaryType = undefined;
|
|
41
|
-
this.primaryRanges = this.config.pjson.dependencies;
|
|
42
|
-
this.updatePrimaryRanges = true;
|
|
43
|
-
this.secondaryRanges = {};
|
|
44
|
-
this.installTree = this.config.jspm.installed;
|
|
45
|
-
this.globalPackagesPath = path.join(project.cacheDir, 'packages');
|
|
46
|
-
// ensure registries are loaded
|
|
47
|
-
this.registryManager.loadEndpoints();
|
|
48
|
-
this.changed = false;
|
|
49
|
-
this.busy = false;
|
|
50
|
-
}
|
|
51
|
-
dispose() {
|
|
52
|
-
}
|
|
53
|
-
ensureNotBusy() {
|
|
54
|
-
if (this.busy)
|
|
55
|
-
throw new common_1.JspmUserError('Installer can only install a single top-level install operation at once.');
|
|
56
|
-
}
|
|
57
|
-
async update(selectors, opts) {
|
|
58
|
-
let updateInstalls = [];
|
|
59
|
-
selectors.forEach(selector => {
|
|
60
|
-
let matches = this.installTree.select(selector);
|
|
61
|
-
if (!matches.length)
|
|
62
|
-
throw new common_1.JspmUserError(`Package ${common_1.bold(selector)} is not an installed package.`);
|
|
63
|
-
if (matches.length > 1) {
|
|
64
|
-
// if a secondary, ensure that they all coalesce to the same package
|
|
65
|
-
let primary = false;
|
|
66
|
-
let exactNames = [];
|
|
67
|
-
matches.forEach(match => {
|
|
68
|
-
if (primary) {
|
|
69
|
-
if (match.parent)
|
|
70
|
-
return;
|
|
71
|
-
}
|
|
72
|
-
else if (!match.parent) {
|
|
73
|
-
primary = true;
|
|
74
|
-
exactNames = [];
|
|
75
|
-
}
|
|
76
|
-
const exactResolution = match.parent ? this.installTree.dependencies[match.parent].resolve[match.name] : this.installTree.resolve[match.name];
|
|
77
|
-
const exactName = package_1.serializePackageName(exactResolution);
|
|
78
|
-
if (exactNames.indexOf(exactName) === -1)
|
|
79
|
-
exactNames.push(exactName);
|
|
80
|
-
});
|
|
81
|
-
if (exactNames.length > 1)
|
|
82
|
-
throw new common_1.JspmUserError(`Ambiguous update package ${common_1.bold(selector)} matches multiple packages: ${exactNames.map(name => common_1.highlight(name)).join(', ')}.`);
|
|
83
|
-
}
|
|
84
|
-
matches.forEach(match => {
|
|
85
|
-
const { name, parent } = match;
|
|
86
|
-
updateInstalls.push({
|
|
87
|
-
name,
|
|
88
|
-
parent,
|
|
89
|
-
type: package_1.DepType.primary,
|
|
90
|
-
target: undefined
|
|
91
|
-
});
|
|
92
|
-
});
|
|
93
|
-
});
|
|
94
|
-
await this.ensureInstallRanges();
|
|
95
|
-
updateInstalls.forEach(install => {
|
|
96
|
-
if (!install.parent) {
|
|
97
|
-
const parentRanges = this.primaryRanges[install.name];
|
|
98
|
-
if (!parentRanges)
|
|
99
|
-
throw new common_1.JspmUserError(`Unable to detect an install range for ${common_1.bold(install.name)}.`);
|
|
100
|
-
install.type = parentRanges.type;
|
|
101
|
-
install.target = parentRanges.target;
|
|
102
|
-
}
|
|
103
|
-
else {
|
|
104
|
-
const parentObj = this.secondaryRanges[install.parent];
|
|
105
|
-
install.target = parentObj && parentObj[install.name];
|
|
106
|
-
if (!install.target)
|
|
107
|
-
throw new common_1.JspmUserError(`Unable to detect an install range for ${common_1.bold(install.name)} in ${common_1.highlight(install.parent)}.`);
|
|
108
|
-
}
|
|
109
|
-
});
|
|
110
|
-
return this.install(updateInstalls, opts);
|
|
111
|
-
}
|
|
112
|
-
// could support override here for link to non-link: sources
|
|
113
|
-
async link(pkg, source, opts) {
|
|
114
|
-
const linkSource = await this.registryManager.resolveSource(source, this.project.projectPath, this.project.projectPath);
|
|
115
|
-
const linkInstall = {
|
|
116
|
-
name: undefined,
|
|
117
|
-
parent: undefined,
|
|
118
|
-
target: undefined,
|
|
119
|
-
type: undefined
|
|
120
|
-
};
|
|
121
|
-
let linkPkg;
|
|
122
|
-
// find exact or unique matching package in the tree, throwing if not found
|
|
123
|
-
try {
|
|
124
|
-
linkPkg = package_1.parseExactPackageName(pkg);
|
|
125
|
-
}
|
|
126
|
-
catch (e) { }
|
|
127
|
-
// not a full package name -> select for best name match
|
|
128
|
-
if (!linkPkg) {
|
|
129
|
-
let matches = this.installTree.select(pkg);
|
|
130
|
-
if (!matches.length)
|
|
131
|
-
throw new common_1.JspmUserError(`Package ${common_1.bold(pkg)} is not an installed package. Either reference an existing installed package or provide the full package name to link into of the form ${common_1.bold('<registry:name@version>')}`);
|
|
132
|
-
// if a secondary, ensure that they all coalesce to the same package
|
|
133
|
-
const exactNames = [];
|
|
134
|
-
matches.forEach(match => {
|
|
135
|
-
const exactResolution = match.parent ? this.installTree.dependencies[match.parent].resolve[match.name] : this.installTree.resolve[match.name];
|
|
136
|
-
linkPkg = exactResolution;
|
|
137
|
-
const exactName = package_1.serializePackageName(exactResolution);
|
|
138
|
-
if (exactNames.indexOf(exactName) === -1)
|
|
139
|
-
exactNames.push(exactName);
|
|
140
|
-
});
|
|
141
|
-
if (exactNames.length > 1)
|
|
142
|
-
throw new common_1.JspmUserError(`Ambiguous link package ${common_1.bold(pkg)} matches multiple packages: ${exactNames.map(name => common_1.highlight(name)).join(', ')}.`);
|
|
143
|
-
linkInstall.parent = matches[0].parent;
|
|
144
|
-
linkInstall.name = matches[0].name;
|
|
145
|
-
}
|
|
146
|
-
// exact package name -> find it in the tree
|
|
147
|
-
else if (this.installTree.visit((pkg, name, parent) => {
|
|
148
|
-
if (linkPkg.name !== pkg.name || linkPkg.version !== pkg.version || pkg.registry !== linkPkg.registry)
|
|
149
|
-
return false;
|
|
150
|
-
linkInstall.name = name;
|
|
151
|
-
linkInstall.parent = parent;
|
|
152
|
-
return true;
|
|
153
|
-
})) { }
|
|
154
|
-
// see if the exact package matches a top-level package.json install
|
|
155
|
-
// that has not been done
|
|
156
|
-
else if (Object.keys(this.primaryRanges).some(name => {
|
|
157
|
-
const range = this.primaryRanges[name];
|
|
158
|
-
if (typeof range.target !== 'string' && range.target.has(linkPkg)) {
|
|
159
|
-
linkInstall.name = name;
|
|
160
|
-
linkInstall.type = range.type;
|
|
161
|
-
return true;
|
|
162
|
-
}
|
|
163
|
-
return false;
|
|
164
|
-
})) { }
|
|
165
|
-
// not existing at all
|
|
166
|
-
// -> new primary install to linked
|
|
167
|
-
else {
|
|
168
|
-
linkInstall.type = package_1.DepType.primary; // check opts type?
|
|
169
|
-
linkInstall.target = new package_1.PackageTarget(linkPkg.registry, linkPkg.name, linkPkg.version);
|
|
170
|
-
this.installTree.resolve[linkInstall.name] = linkPkg;
|
|
171
|
-
}
|
|
172
|
-
// set primary range type and target
|
|
173
|
-
// type not needed for secondaries and target not needed as lock is used
|
|
174
|
-
if (linkInstall.parent === undefined) {
|
|
175
|
-
const primaryRange = this.primaryRanges[linkInstall.name];
|
|
176
|
-
if (primaryRange) {
|
|
177
|
-
linkInstall.type = primaryRange.type;
|
|
178
|
-
linkInstall.target = primaryRange.target;
|
|
179
|
-
}
|
|
180
|
-
else {
|
|
181
|
-
linkInstall.type = package_1.DepType.primary;
|
|
182
|
-
linkInstall.target = new package_1.PackageTarget(linkPkg.registry, linkPkg.name, linkPkg.version);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
// source set through lock for existing "link over" cases
|
|
186
|
-
const linkPkgName = package_1.serializePackageName(linkPkg);
|
|
187
|
-
const linkPkgResolved = this.installTree.dependencies[linkPkgName] = this.installTree.dependencies[linkPkgName] || { source: undefined, resolve: {} };
|
|
188
|
-
linkPkgResolved.source = linkSource;
|
|
189
|
-
opts.lock = true;
|
|
190
|
-
return this.install([linkInstall], opts);
|
|
191
|
-
}
|
|
192
|
-
async checkout(selectors) {
|
|
193
|
-
const checkouts = [];
|
|
194
|
-
selectors.forEach(selector => {
|
|
195
|
-
let matches = this.installTree.select(selector);
|
|
196
|
-
if (!matches.length)
|
|
197
|
-
throw new common_1.JspmUserError(`Package ${common_1.bold(selector)} is not an installed package.`);
|
|
198
|
-
// if a secondary, ensure that they all coalesce to the same package
|
|
199
|
-
const exactNames = [];
|
|
200
|
-
matches.forEach(match => {
|
|
201
|
-
const exactResolution = match.parent ? this.installTree.dependencies[match.parent].resolve[match.name] : this.installTree.resolve[match.name];
|
|
202
|
-
const exactName = package_1.serializePackageName(exactResolution);
|
|
203
|
-
if (exactNames.indexOf(exactName) === -1)
|
|
204
|
-
exactNames.push(exactName);
|
|
205
|
-
});
|
|
206
|
-
if (exactNames.length > 1)
|
|
207
|
-
throw new common_1.JspmUserError(`Ambiguous checkout package ${common_1.bold(selector)} matches multiple packages: ${exactNames.map(name => common_1.highlight(name)).join(', ')}.`);
|
|
208
|
-
checkouts.push(exactNames[0]);
|
|
209
|
-
});
|
|
210
|
-
await Promise.all(checkouts.map(async (checkoutName) => {
|
|
211
|
-
const registryIndex = checkoutName.indexOf(':');
|
|
212
|
-
const packageInstallState = await this.getPackageInstallState(checkoutName);
|
|
213
|
-
let stopReason = '';
|
|
214
|
-
if (!packageInstallState.exists)
|
|
215
|
-
stopReason = 'not installed';
|
|
216
|
-
else if (packageInstallState.linkPath)
|
|
217
|
-
stopReason = 'already linked';
|
|
218
|
-
// skip if already checked out
|
|
219
|
-
else if (!packageInstallState.hash)
|
|
220
|
-
return this.project.log.ok(`Package ${common_1.highlight(checkoutName)} is already checked out.`);
|
|
221
|
-
if (stopReason)
|
|
222
|
-
throw new common_1.JspmUserError(`Unable to checkout ${common_1.highlight(checkoutName)} as it is ${stopReason}.`);
|
|
223
|
-
const checkoutPath = path.join(this.config.pjson.packages, checkoutName.substr(0, registryIndex), checkoutName.substr(registryIndex + 1));
|
|
224
|
-
const installPath = await new Promise((resolve, reject) => fs.readlink(checkoutPath, (err, path) => err ? reject(err) : resolve(path)));
|
|
225
|
-
await new Promise((resolve, reject) => fs.unlink(checkoutPath, err => err ? reject(err) : resolve()));
|
|
226
|
-
await new Promise((resolve, reject) => ncp(installPath, checkoutPath, err => err ? reject(err) : resolve()));
|
|
227
|
-
this.project.log.ok(`Checked out package ${common_1.highlight(checkoutName)} for local modifications.`);
|
|
228
|
-
}));
|
|
229
|
-
}
|
|
230
|
-
async uninstall(names) {
|
|
231
|
-
this.ensureNotBusy();
|
|
232
|
-
this.busy = true;
|
|
233
|
-
if (names.length === 0)
|
|
234
|
-
throw new common_1.JspmUserError(`No package provided to uninstall.`);
|
|
235
|
-
names.forEach(name => {
|
|
236
|
-
if (!this.primaryRanges[name])
|
|
237
|
-
throw new common_1.JspmUserError(`Package ${common_1.bold(name)} doesn\'t match any existing top-level installed packages.`);
|
|
238
|
-
if (this.primaryRanges[name]) {
|
|
239
|
-
delete this.primaryRanges[name];
|
|
240
|
-
this.changed = true;
|
|
241
|
-
}
|
|
242
|
-
if (this.installTree.resolve[name]) {
|
|
243
|
-
delete this.installTree.resolve[name];
|
|
244
|
-
this.changed = true;
|
|
245
|
-
}
|
|
246
|
-
});
|
|
247
|
-
await this.clean();
|
|
248
|
-
this.busy = false;
|
|
249
|
-
return this.config.save();
|
|
250
|
-
}
|
|
251
|
-
/*
|
|
252
|
-
* Install API top-level function
|
|
253
|
-
*/
|
|
254
|
-
async install(installs, opts) {
|
|
255
|
-
this.ensureNotBusy();
|
|
256
|
-
this.busy = true;
|
|
257
|
-
this.opts = opts;
|
|
258
|
-
this.changed = false;
|
|
259
|
-
if (this.opts.dedupe !== false)
|
|
260
|
-
this.opts.dedupe = !this.opts.lock;
|
|
261
|
-
this.primaryType = installs.length === 0 ? package_1.DepType.primary : installs[0].type;
|
|
262
|
-
// no installs, install from package.json
|
|
263
|
-
if (installs.length === 0) {
|
|
264
|
-
// maintain existing package.json ranges
|
|
265
|
-
this.updatePrimaryRanges = false;
|
|
266
|
-
installs = Object.keys(this.primaryRanges).map(dep => {
|
|
267
|
-
const entry = this.primaryRanges[dep];
|
|
268
|
-
return {
|
|
269
|
-
name: dep,
|
|
270
|
-
target: entry.target,
|
|
271
|
-
type: entry.type,
|
|
272
|
-
parent: undefined
|
|
273
|
-
};
|
|
274
|
-
});
|
|
275
|
-
}
|
|
276
|
-
// install in parallel
|
|
277
|
-
await Promise.all(installs.map(install => {
|
|
278
|
-
const target = install.target;
|
|
279
|
-
if (typeof target === 'string') {
|
|
280
|
-
/*
|
|
281
|
-
* File install sugar cases:
|
|
282
|
-
* ./local -> file:./local
|
|
283
|
-
* /local -> file:/local
|
|
284
|
-
* ~/file -> file:~/file
|
|
285
|
-
*/
|
|
286
|
-
if (target.match(fileInstallRegEx)) {
|
|
287
|
-
install.target = 'file:' + target;
|
|
288
|
-
}
|
|
289
|
-
/*
|
|
290
|
-
* Plain target install
|
|
291
|
-
* Should ideally support a/b/c -> file:a/b/c resource sugar, but for now omitted
|
|
292
|
-
*/
|
|
293
|
-
else if (!target.match(package_1.resourceInstallRegEx)) {
|
|
294
|
-
let registryIndex = target.indexOf(':');
|
|
295
|
-
let targetString = target;
|
|
296
|
-
// a/b -> github:a/b sugar
|
|
297
|
-
if (registryIndex === -1 && target.indexOf('/') !== -1 && target[0] !== '@')
|
|
298
|
-
targetString = 'github:' + target;
|
|
299
|
-
if (registryIndex === -1)
|
|
300
|
-
targetString = ':' + targetString;
|
|
301
|
-
install.target = package_1.processPackageTarget(install.name, targetString, this.project.defaultRegistry);
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
// auto-generate name from target if necessary
|
|
305
|
-
if (!install.name) {
|
|
306
|
-
if (typeof install.target !== 'string') {
|
|
307
|
-
const idx = install.target.name.lastIndexOf(':') + 1;
|
|
308
|
-
const substr = install.target.name.substr(idx);
|
|
309
|
-
if (substr.match(common_1.validAliasRegEx))
|
|
310
|
-
install.name = substr;
|
|
311
|
-
else
|
|
312
|
-
install.name = substr.split('/').pop();
|
|
313
|
-
}
|
|
314
|
-
else {
|
|
315
|
-
install.name = getResourceName(install.target, this.project.projectPath);
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
if (!install.name.match(common_1.validAliasRegEx))
|
|
319
|
-
throw new common_1.JspmUserError(`Invalid name ${common_1.bold(install.name)} for install to ${common_1.highlight(install.target.toString())}`);
|
|
320
|
-
if (typeof install.target === 'string')
|
|
321
|
-
return this.resourceInstall(install);
|
|
322
|
-
else
|
|
323
|
-
return this.packageInstall(install);
|
|
324
|
-
}));
|
|
325
|
-
await this.clean();
|
|
326
|
-
const configChanged = this.config.save();
|
|
327
|
-
this.busy = false;
|
|
328
|
-
return configChanged || this.changed;
|
|
329
|
-
}
|
|
330
|
-
/*
|
|
331
|
-
private async installPeer (_install: Install) {
|
|
332
|
-
throw new Error('Todo');
|
|
333
|
-
}
|
|
334
|
-
*/
|
|
335
|
-
// most general override applies (greater containing range)
|
|
336
|
-
// we first check this.config.pjson.overrides, followed by globalOverrides
|
|
337
|
-
getOverride(pkg, cut = false) {
|
|
338
|
-
if (typeof pkg === 'string') {
|
|
339
|
-
const matchIndex = this.config.pjson.overrides.findIndex(({ target }) => target === pkg);
|
|
340
|
-
const match = this.config.pjson.overrides[matchIndex];
|
|
341
|
-
if (cut && matchIndex !== -1 && !match.fresh)
|
|
342
|
-
this.config.pjson.overrides.splice(matchIndex, 1);
|
|
343
|
-
return match && match.override;
|
|
344
|
-
}
|
|
345
|
-
else {
|
|
346
|
-
let bestTargetIndex = -1;
|
|
347
|
-
let bestTarget;
|
|
348
|
-
let bestOverride;
|
|
349
|
-
let bestIsFresh;
|
|
350
|
-
for (let i = 0; i < this.config.pjson.overrides.length; i++) {
|
|
351
|
-
let { target, override, fresh } = this.config.pjson.overrides[i];
|
|
352
|
-
if (typeof target === 'string')
|
|
353
|
-
continue;
|
|
354
|
-
if (target.has(pkg)) {
|
|
355
|
-
if (!bestTarget || target.range.gt(bestTarget.range)) {
|
|
356
|
-
bestTargetIndex = i;
|
|
357
|
-
bestTarget = target;
|
|
358
|
-
bestOverride = override;
|
|
359
|
-
bestIsFresh = fresh;
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
if (cut && bestTargetIndex !== -1 && !bestIsFresh)
|
|
364
|
-
this.config.pjson.overrides.splice(bestTargetIndex, 1);
|
|
365
|
-
if (!bestOverride) {
|
|
366
|
-
const pkgs = overrides_1.default[pkg.registry];
|
|
367
|
-
if (pkgs) {
|
|
368
|
-
const versions = pkgs[pkg.name];
|
|
369
|
-
if (versions) {
|
|
370
|
-
let bestTargetRange;
|
|
371
|
-
for (const v in versions) {
|
|
372
|
-
const range = new sver_1.SemverRange(v);
|
|
373
|
-
if (range.has(pkg.version)) {
|
|
374
|
-
if (!bestTarget || range.gt(bestTargetRange)) {
|
|
375
|
-
bestTargetRange = range;
|
|
376
|
-
bestOverride = package_1.processPackageConfig(versions[v]);
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
return bestOverride;
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
// get an override and remove it from the override list in the process
|
|
387
|
-
// this way an override saved back does not result in duplication
|
|
388
|
-
cutOverride(pkg) {
|
|
389
|
-
return this.getOverride(pkg, true);
|
|
390
|
-
}
|
|
391
|
-
setOverride(pkgTarget, override) {
|
|
392
|
-
this.config.pjson.overrides.push({
|
|
393
|
-
target: pkgTarget,
|
|
394
|
-
override,
|
|
395
|
-
fresh: true
|
|
396
|
-
});
|
|
397
|
-
}
|
|
398
|
-
async packageInstall(install) {
|
|
399
|
-
// first check if already doing this install, to avoid redoing work
|
|
400
|
-
// this in turn catches circular installs on the early returns
|
|
401
|
-
const installId = `${install.type === package_1.DepType.peer ? undefined : install.parent}|${install.name}`;
|
|
402
|
-
const existingPackageInstall = this.installs[installId];
|
|
403
|
-
if (existingPackageInstall)
|
|
404
|
-
return;
|
|
405
|
-
return this.installs[installId] = (async () => {
|
|
406
|
-
this.project.log.debug(`Installing ${install.name}${install.parent ? ` for ${install.parent}` : ``}`);
|
|
407
|
-
// install information
|
|
408
|
-
let target = install.target;
|
|
409
|
-
let override = install.override && package_1.validateOverride(install.override, install.name) && package_1.processPackageConfig(install.override);
|
|
410
|
-
let source;
|
|
411
|
-
let resolvedPkg;
|
|
412
|
-
// if a lock install, use existing resolution
|
|
413
|
-
if (this.opts.lock)
|
|
414
|
-
resolvedPkg = this.installTree.getResolution(install);
|
|
415
|
-
// if a non-latest secondary install, use existing resolution or find the best match in the tree
|
|
416
|
-
if (install.type === package_1.DepType.secondary && !this.opts.latest)
|
|
417
|
-
resolvedPkg = this.installTree.getResolution(install) || this.installTree.getBestMatch(target);
|
|
418
|
-
if (resolvedPkg) {
|
|
419
|
-
const existingResolutionName = package_1.serializePackageName(resolvedPkg);
|
|
420
|
-
const existingResolved = this.installTree.dependencies[existingResolutionName];
|
|
421
|
-
// if we found an existing resolution, use it if we have enough information
|
|
422
|
-
if (existingResolved && existingResolved.source) {
|
|
423
|
-
this.project.log.debug(`${install.name} matched against existing install`);
|
|
424
|
-
target = this.setResolution(install, target, resolvedPkg, existingResolved.source);
|
|
425
|
-
override = this.cutOverride(resolvedPkg);
|
|
426
|
-
override = await this.sourceInstall(resolvedPkg, existingResolved.source, override, undefined);
|
|
427
|
-
if (override)
|
|
428
|
-
this.setOverride(target, override);
|
|
429
|
-
return;
|
|
430
|
-
}
|
|
431
|
-
// otherwise specifically lookup this exact version
|
|
432
|
-
else {
|
|
433
|
-
target = new package_1.PackageTarget(resolvedPkg.registry, resolvedPkg.name, resolvedPkg.version);
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
// run resolver lookup
|
|
437
|
-
let resolution;
|
|
438
|
-
try {
|
|
439
|
-
resolution = await this.registryManager.resolve(target, override, this.opts.edge);
|
|
440
|
-
}
|
|
441
|
-
catch (e) {
|
|
442
|
-
throw new common_1.JspmError(`Resolving ${common_1.highlight(package_1.serializePackageName(target))}`, undefined, e);
|
|
443
|
-
}
|
|
444
|
-
if (!resolution)
|
|
445
|
-
throw new common_1.JspmUserError(`No resolution found for ${common_1.highlight(package_1.serializePackageName(target).replace(/\@\*$/, ''))}${this.offline ? ' (offline)' : ''}.`);
|
|
446
|
-
resolvedPkg = resolution.pkg;
|
|
447
|
-
source = resolution.source;
|
|
448
|
-
override = resolution.override;
|
|
449
|
-
// if there was no install override, get any override from package.json
|
|
450
|
-
if (!install.override) {
|
|
451
|
-
const existingOverride = this.cutOverride(resolvedPkg);
|
|
452
|
-
if (existingOverride) {
|
|
453
|
-
if (override)
|
|
454
|
-
package_1.overridePackageConfig(override, existingOverride);
|
|
455
|
-
else
|
|
456
|
-
override = Object.assign({}, existingOverride);
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
// immediately store the resolution if necessary
|
|
460
|
-
target = this.setResolution(install, new package_1.PackageTarget(resolution.target.registry, resolution.target.name, resolution.target.version), resolution.pkg, source);
|
|
461
|
-
// upgrade anything to this resolution which can (this is the orphaning)
|
|
462
|
-
if (this.opts.dedupe)
|
|
463
|
-
this.upgradePackagesTo(resolvedPkg).catch(() => { });
|
|
464
|
-
const sourceInstallPromise = this.sourceInstall(resolvedPkg, source, override, resolution && resolution.deprecated);
|
|
465
|
-
if (sourceInstallPromise) {
|
|
466
|
-
// override from resolve replaces any existing package.json override which is not used
|
|
467
|
-
override = await sourceInstallPromise;
|
|
468
|
-
if (override)
|
|
469
|
-
this.setOverride(target, override);
|
|
470
|
-
}
|
|
471
|
-
})();
|
|
472
|
-
}
|
|
473
|
-
sourceInstall(resolvedPkg, source, override, deprecated) {
|
|
474
|
-
const resolvedPkgName = package_1.serializePackageName(resolvedPkg);
|
|
475
|
-
const sourceInstallId = `${resolvedPkgName}|${source}`;
|
|
476
|
-
let existingSourceInstall = this.sourceInstalls[sourceInstallId];
|
|
477
|
-
// avoid circular (ok since a single install tree)
|
|
478
|
-
if (existingSourceInstall) {
|
|
479
|
-
return;
|
|
480
|
-
}
|
|
481
|
-
return this.sourceInstalls[sourceInstallId] = (async () => {
|
|
482
|
-
// checked out packages stay unless a reset
|
|
483
|
-
// and use the configuration from the package.json directly
|
|
484
|
-
if (!this.opts.reset && await this.isPackageCheckedOut(resolvedPkgName)) {
|
|
485
|
-
const config = await this.readCheckedOutConfig(resolvedPkgName, override);
|
|
486
|
-
this.project.log.info(`Skipping reinstall for ${common_1.highlight(resolvedPkgName)} as there is a custom folder checked out in its place. Use the ${common_1.bold('--reset')} install flag to revert to the original source.`);
|
|
487
|
-
// override is undefined by definition of checked out.
|
|
488
|
-
return this.installDependencies(config, resolvedPkgName);
|
|
489
|
-
}
|
|
490
|
-
// handle linked packages
|
|
491
|
-
if (source.startsWith('link:')) {
|
|
492
|
-
if (await this.setPackageToLinked(resolvedPkgName, path.resolve(this.project.projectPath, source.substr(5))))
|
|
493
|
-
this.changed = true;
|
|
494
|
-
const config = await this.readCheckedOutConfig(resolvedPkgName, override, true);
|
|
495
|
-
return this.installDependencies(config, resolvedPkgName);
|
|
496
|
-
}
|
|
497
|
-
let preloadedDepNames, preloadDepsInstallPromise;
|
|
498
|
-
// kick off dependency installs now
|
|
499
|
-
if (override) {
|
|
500
|
-
preloadDepsInstallPromise = this.installDependencies(override, resolvedPkgName, preloadedDepNames);
|
|
501
|
-
preloadDepsInstallPromise.catch(() => { });
|
|
502
|
-
}
|
|
503
|
-
// install
|
|
504
|
-
try {
|
|
505
|
-
var installResult = await this.registryManager.ensureInstall(source, override, this.opts.reset ? async () => false : this.createCheckoutPrompt(resolvedPkgName), this.opts.verify);
|
|
506
|
-
}
|
|
507
|
-
catch (e) {
|
|
508
|
-
const errMsg = `Unable to install ${common_1.highlight(resolvedPkgName)}.`;
|
|
509
|
-
if (e instanceof common_1.JspmUserError)
|
|
510
|
-
throw new common_1.JspmUserError(errMsg, undefined, e);
|
|
511
|
-
else
|
|
512
|
-
throw new common_1.JspmError(errMsg, undefined, e);
|
|
513
|
-
}
|
|
514
|
-
// install result is undefined when verification fails and we have a checkout
|
|
515
|
-
// then handle like checked out instead
|
|
516
|
-
if (!installResult) {
|
|
517
|
-
const config = await this.readCheckedOutConfig(resolvedPkgName, override);
|
|
518
|
-
return this.installDependencies(config, resolvedPkgName);
|
|
519
|
-
}
|
|
520
|
-
if (installResult.changed)
|
|
521
|
-
this.changed = true;
|
|
522
|
-
let config, hash;
|
|
523
|
-
({ config, override, hash } = installResult);
|
|
524
|
-
await Promise.all([
|
|
525
|
-
// install dependencies, skipping already preloaded
|
|
526
|
-
this.installDependencies(config, resolvedPkgName, preloadedDepNames),
|
|
527
|
-
// symlink to the global install
|
|
528
|
-
(async () => {
|
|
529
|
-
if (await this.setPackageToHash(resolvedPkgName, hash)) {
|
|
530
|
-
this.changed = true;
|
|
531
|
-
// only show deprecation message on first install into jspm_packages
|
|
532
|
-
if (deprecated)
|
|
533
|
-
this.project.log.warn(`Deprecation warning for ${common_1.highlight(resolvedPkgName)}: ${common_1.bold(deprecated)}`);
|
|
534
|
-
}
|
|
535
|
-
})(),
|
|
536
|
-
this.createBins(config, resolvedPkgName),
|
|
537
|
-
preloadDepsInstallPromise
|
|
538
|
-
]);
|
|
539
|
-
return override;
|
|
540
|
-
})();
|
|
541
|
-
}
|
|
542
|
-
async createBins(config, resolvedPkgName) {
|
|
543
|
-
// NB we should create a queue based on precedence to ensure deterministic ordering
|
|
544
|
-
// when there are namespace collissions, but this problem will likely not be hit for a while
|
|
545
|
-
if (config.bin) {
|
|
546
|
-
const binDir = path.join(this.config.pjson.packages, '.bin');
|
|
547
|
-
if (!this.binFolderChecked) {
|
|
548
|
-
await new Promise((resolve, reject) => mkdirp(binDir, err => err ? reject(err) : resolve(binDir)));
|
|
549
|
-
this.binFolderChecked = true;
|
|
550
|
-
}
|
|
551
|
-
await Promise.all(Object.keys(config.bin).map(p => bin_1.writeBinScripts(binDir, p, resolvedPkgName.replace(':', path.sep) + path.sep + config.bin[p])));
|
|
552
|
-
}
|
|
553
|
-
}
|
|
554
|
-
// resource install is different to source install in that
|
|
555
|
-
// we need to normalize the source string into resolved form and
|
|
556
|
-
// we need to install first to find out the name of the package
|
|
557
|
-
async resourceInstall(install) {
|
|
558
|
-
// first check if already doing this install, to avoid redoing work
|
|
559
|
-
// this in turn catches circular installs on the early returns
|
|
560
|
-
const installId = `${install.type === package_1.DepType.peer ? undefined : install.parent}|${install.name}`;
|
|
561
|
-
const existingPackageInstall = this.installs[installId];
|
|
562
|
-
if (existingPackageInstall)
|
|
563
|
-
return;
|
|
564
|
-
return this.installs[installId] = (async () => {
|
|
565
|
-
let override = install.override || this.cutOverride(install.target);
|
|
566
|
-
// handle lock lookups for resourceInstall
|
|
567
|
-
const existingResolution = this.installTree.getResolution(install);
|
|
568
|
-
if (existingResolution) {
|
|
569
|
-
const existingResolutionName = package_1.serializePackageName(existingResolution);
|
|
570
|
-
const existingResolved = this.installTree.dependencies[existingResolutionName];
|
|
571
|
-
if (existingResolved && existingResolved.source) {
|
|
572
|
-
this.project.log.debug(`${install.name} matched against existing install`);
|
|
573
|
-
this.setResolution(install, install.target, existingResolution, existingResolved.source);
|
|
574
|
-
override = await this.sourceInstall(existingResolution, existingResolved.source, override, undefined);
|
|
575
|
-
if (override)
|
|
576
|
-
this.setOverride(install.target, override);
|
|
577
|
-
return;
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
this.project.log.debug(`Installing resource ${install.name}${install.parent ? ` for ${install.parent}` : ``}`);
|
|
581
|
-
const parentPath = install.parent && install.type !== package_1.DepType.peer ? path.join(this.config.pjson.packages, install.parent.replace(':', path.sep)) : this.project.projectPath;
|
|
582
|
-
// first normalize the source
|
|
583
|
-
try {
|
|
584
|
-
var source = await this.registryManager.resolveSource(install.target, parentPath, this.project.projectPath);
|
|
585
|
-
}
|
|
586
|
-
catch (e) {
|
|
587
|
-
const errMsg = `Unable to locate ${common_1.highlight(install.target)}.`;
|
|
588
|
-
if (e instanceof common_1.JspmUserError)
|
|
589
|
-
throw new common_1.JspmUserError(errMsg, undefined, e);
|
|
590
|
-
else
|
|
591
|
-
throw new common_1.JspmError(errMsg, undefined, e);
|
|
592
|
-
}
|
|
593
|
-
const isLink = source.startsWith('link:');
|
|
594
|
-
let config, hash, linkPath;
|
|
595
|
-
let registry, name, version;
|
|
596
|
-
// link
|
|
597
|
-
if (isLink) {
|
|
598
|
-
linkPath = path.resolve(this.project.projectPath, source.substr(5));
|
|
599
|
-
try {
|
|
600
|
-
var json = await common_1.readJSON(path.join(linkPath, 'package.json'));
|
|
601
|
-
}
|
|
602
|
-
catch (e) { }
|
|
603
|
-
config = package_1.processPackageConfig(json || {});
|
|
604
|
-
if (override) {
|
|
605
|
-
({ config, override } = package_1.overridePackageConfig(config, override));
|
|
606
|
-
if (override)
|
|
607
|
-
this.project.log.warn(`The override for ${common_1.highlight(install.target)} is not being applied as it is linked. Rather edit the original package.json file directly instead of applying an override.`);
|
|
608
|
-
}
|
|
609
|
-
registry = config.registry || this.project.defaultRegistry;
|
|
610
|
-
name = config.name || install.name;
|
|
611
|
-
version = config.version;
|
|
612
|
-
}
|
|
613
|
-
// install
|
|
614
|
-
else {
|
|
615
|
-
try {
|
|
616
|
-
var installResult = await this.registryManager.ensureInstall(source, override, async () => false, this.opts.verify);
|
|
617
|
-
}
|
|
618
|
-
catch (e) {
|
|
619
|
-
const errMsg = `Unable to install ${source}.`;
|
|
620
|
-
if (e instanceof common_1.JspmUserError)
|
|
621
|
-
throw new common_1.JspmUserError(errMsg, undefined, e);
|
|
622
|
-
else
|
|
623
|
-
throw new common_1.JspmError(errMsg, undefined, e);
|
|
624
|
-
}
|
|
625
|
-
if (installResult.changed)
|
|
626
|
-
this.changed = true;
|
|
627
|
-
({ config, override, hash } = installResult);
|
|
628
|
-
registry = config.registry || this.project.defaultRegistry;
|
|
629
|
-
name = config.name || install.name;
|
|
630
|
-
version = config.version;
|
|
631
|
-
if (!version) {
|
|
632
|
-
let refIndex = install.target.lastIndexOf('#');
|
|
633
|
-
if (refIndex !== -1)
|
|
634
|
-
version = install.target.substr(refIndex + 1);
|
|
635
|
-
}
|
|
636
|
-
}
|
|
637
|
-
if (this.project.userInput) {
|
|
638
|
-
if (!registry)
|
|
639
|
-
registry = 'npm';
|
|
640
|
-
if (!version)
|
|
641
|
-
version = await this.project.input(`Enter the ${common_1.bold('version')} to ${isLink ? `link as` : `install ${install.target} as`}`, 'master', {
|
|
642
|
-
info: 'All installs in jspm need to be assigned a registry, name and version for flat installation.',
|
|
643
|
-
validate: (input) => {
|
|
644
|
-
if (!input)
|
|
645
|
-
return 'A version must be provided.';
|
|
646
|
-
}
|
|
647
|
-
});
|
|
648
|
-
}
|
|
649
|
-
else {
|
|
650
|
-
let missing = !registry && 'registry' || !name && 'name' || !version && 'version';
|
|
651
|
-
if (missing) {
|
|
652
|
-
throw new common_1.JspmUserError(`Unable to ${isLink ? `link ${linkPath}` : `install resource target ${install.target}`} as no ${common_1.bold(missing)} property is provided. This should be set in the original package.json or be added with an override to the install if necessary.`);
|
|
653
|
-
}
|
|
654
|
-
}
|
|
655
|
-
const resolvedPkgName = `${registry}:${name}@${version}`;
|
|
656
|
-
const resolvedPkg = package_1.parseExactPackageName(resolvedPkgName);
|
|
657
|
-
// save resolution
|
|
658
|
-
this.setResolution(install, install.target, resolvedPkg, source);
|
|
659
|
-
if (override)
|
|
660
|
-
this.setOverride(install.target, override);
|
|
661
|
-
// if checked out, skip the actual resource install
|
|
662
|
-
if (!this.opts.reset && await this.isPackageCheckedOut(resolvedPkgName)) {
|
|
663
|
-
const config = await this.readCheckedOutConfig(resolvedPkgName, override);
|
|
664
|
-
this.project.log.info(`Skipping reinstall for ${common_1.highlight(resolvedPkgName)} as there is a custom folder checked out in its place. Use the ${common_1.bold('--reset')} install flag to revert to the original source.`);
|
|
665
|
-
// override is undefined by definition of checked out.
|
|
666
|
-
return this.installDependencies(config, resolvedPkgName);
|
|
667
|
-
}
|
|
668
|
-
await Promise.all([
|
|
669
|
-
this.installDependencies(config, resolvedPkgName),
|
|
670
|
-
(async () => {
|
|
671
|
-
if (isLink) {
|
|
672
|
-
if (await this.setPackageToLinked(resolvedPkgName, linkPath))
|
|
673
|
-
this.changed = true;
|
|
674
|
-
}
|
|
675
|
-
else {
|
|
676
|
-
if (await this.setPackageToHash(resolvedPkgName, hash))
|
|
677
|
-
this.changed = true;
|
|
678
|
-
}
|
|
679
|
-
})(),
|
|
680
|
-
this.createBins(config, resolvedPkgName)
|
|
681
|
-
]);
|
|
682
|
-
})();
|
|
683
|
-
}
|
|
684
|
-
async installDependencies(config, resolvedPkgName, preloadedDepNames) {
|
|
685
|
-
const registry = config.registry || this.project.defaultRegistry;
|
|
686
|
-
const preLoad = preloadedDepNames !== undefined && preloadedDepNames.length !== 0;
|
|
687
|
-
try {
|
|
688
|
-
await Promise.all(depsToInstalls(registry, config, resolvedPkgName, preLoad === false && preloadedDepNames).map(install => {
|
|
689
|
-
if (preLoad && preloadedDepNames)
|
|
690
|
-
preloadedDepNames.push(install.name);
|
|
691
|
-
if (typeof install.target === 'string')
|
|
692
|
-
return this.resourceInstall(install);
|
|
693
|
-
else
|
|
694
|
-
return this.packageInstall(install);
|
|
695
|
-
}));
|
|
696
|
-
}
|
|
697
|
-
catch (e) {
|
|
698
|
-
throw new common_1.JspmError(`Installing ${common_1.highlight(resolvedPkgName)}.`, undefined, e);
|
|
699
|
-
}
|
|
700
|
-
}
|
|
701
|
-
setResolution(install, target, resolution, source) {
|
|
702
|
-
const exactResolution = {
|
|
703
|
-
registry: resolution.registry,
|
|
704
|
-
name: resolution.name,
|
|
705
|
-
version: resolution.version,
|
|
706
|
-
semver: new sver_1.Semver(resolution.version)
|
|
707
|
-
};
|
|
708
|
-
const resolutionString = package_1.serializePackageName(resolution);
|
|
709
|
-
if (!install.parent || install.type === package_1.DepType.peer) {
|
|
710
|
-
this.installTree.resolve[install.name] = exactResolution;
|
|
711
|
-
// only write in targets when primary range is empty
|
|
712
|
-
const existingRange = this.primaryRanges[install.name];
|
|
713
|
-
if (!existingRange || this.updatePrimaryRanges === true) {
|
|
714
|
-
if (typeof target !== 'string') {
|
|
715
|
-
if (target.range.isExact || this.opts.exact)
|
|
716
|
-
target = target.fromVersion(resolution.version);
|
|
717
|
-
if (sver_1.Semver.isValid(resolution.version)) {
|
|
718
|
-
if (target.range.isMajor || target.range.isWildcard)
|
|
719
|
-
target = target.fromVersion('^' + resolution.version);
|
|
720
|
-
else if (target.range.isStable)
|
|
721
|
-
target = target.fromVersion('~' + resolution.version);
|
|
722
|
-
}
|
|
723
|
-
else {
|
|
724
|
-
target = new package_1.PackageTarget(resolution.registry, resolution.name, resolution.version);
|
|
725
|
-
}
|
|
726
|
-
}
|
|
727
|
-
this.changed = true;
|
|
728
|
-
if (this.updatePrimaryRanges && !install.parent) {
|
|
729
|
-
this.primaryRanges[install.name] = { type: install.type, target };
|
|
730
|
-
}
|
|
731
|
-
else {
|
|
732
|
-
const existingPrimaryAndNotDev = this.primaryRanges[install.name] &&
|
|
733
|
-
(this.primaryRanges[install.name].type === package_1.DepType.peer || this.primaryRanges[install.name].type === package_1.DepType.primary);
|
|
734
|
-
// peerDependencies install as devDependencies
|
|
735
|
-
const type = existingPrimaryAndNotDev ? this.primaryRanges[install.name].type
|
|
736
|
-
: install.type === package_1.DepType.peer ? package_1.DepType.dev
|
|
737
|
-
: install.parent ? this.primaryType
|
|
738
|
-
: install.type;
|
|
739
|
-
this.primaryRanges[install.name] = { type, target };
|
|
740
|
-
}
|
|
741
|
-
}
|
|
742
|
-
}
|
|
743
|
-
else {
|
|
744
|
-
const parentRecord = this.installTree.dependencies[install.parent];
|
|
745
|
-
if (!parentRecord)
|
|
746
|
-
throw new common_1.JspmError(`No parent in tree for resolution ${resolutionString}.`);
|
|
747
|
-
parentRecord.resolve[install.name] = exactResolution;
|
|
748
|
-
(this.secondaryRanges[install.parent] = this.secondaryRanges[install.parent] || {})[install.name] = target;
|
|
749
|
-
}
|
|
750
|
-
const installObj = this.installTree.dependencies[resolutionString];
|
|
751
|
-
if (!installObj)
|
|
752
|
-
this.installTree.dependencies[resolutionString] = { source, resolve: {} };
|
|
753
|
-
else
|
|
754
|
-
installObj.source = source;
|
|
755
|
-
return target;
|
|
756
|
-
}
|
|
757
|
-
getPackagePath(name) {
|
|
758
|
-
const resolvedPkgName = package_1.serializePackageName(this.config.jspm.installed.resolve[name]);
|
|
759
|
-
const registryIndex = resolvedPkgName.indexOf(':');
|
|
760
|
-
return path.join(this.config.pjson.packages, resolvedPkgName.substr(0, registryIndex), resolvedPkgName.substr(registryIndex + 1));
|
|
761
|
-
}
|
|
762
|
-
createCheckoutPrompt(resolvedPkgName) {
|
|
763
|
-
const registryIndex = resolvedPkgName.indexOf(':');
|
|
764
|
-
const localPackagePath = path.join(this.config.pjson.packages, resolvedPkgName.substr(0, registryIndex), resolvedPkgName.substr(registryIndex + 1));
|
|
765
|
-
return async (dir) => {
|
|
766
|
-
let checkout = await this.project.confirm(`The global package ${resolvedPkgName} has been modified, do you want to checkout the package now for custom modification, or revert?`, true);
|
|
767
|
-
if (checkout) {
|
|
768
|
-
await new Promise((resolve, reject) => ncp(dir, localPackagePath, err => err ? reject(err) : resolve()));
|
|
769
|
-
await new Promise((resolve, reject) => rimraf(dir, err => err ? reject(err) : resolve()));
|
|
770
|
-
}
|
|
771
|
-
return checkout;
|
|
772
|
-
};
|
|
773
|
-
}
|
|
774
|
-
async readCheckedOutConfig(resolvedPkgName, override, linked = false) {
|
|
775
|
-
const registryIndex = resolvedPkgName.indexOf(':');
|
|
776
|
-
const registry = resolvedPkgName.substr(0, registryIndex);
|
|
777
|
-
const pkgPath = path.join(this.config.pjson.packages, registry, resolvedPkgName.substr(registryIndex + 1));
|
|
778
|
-
var json = await common_1.readJSON(path.join(pkgPath, 'package.json'));
|
|
779
|
-
let config = package_1.processPackageConfig(json || {});
|
|
780
|
-
if (override) {
|
|
781
|
-
({ config, override } = package_1.overridePackageConfig(config, override));
|
|
782
|
-
if (override)
|
|
783
|
-
this.project.log.warn(`The override for ${common_1.highlight(resolvedPkgName)} is not being applied as it is ${linked ? 'linked' : 'checked out'}. Rather edit the original package.json file directly instead of applying an override.`);
|
|
784
|
-
}
|
|
785
|
-
return config;
|
|
786
|
-
}
|
|
787
|
-
// upgrades any packages in the installing or installed tree to the newly added resolution
|
|
788
|
-
async upgradePackagesTo(upgradePkg) {
|
|
789
|
-
await this.ensureInstallRanges(upgradePkg);
|
|
790
|
-
await this.installTree.visit((pkg, name, parent) => {
|
|
791
|
-
let range;
|
|
792
|
-
if (parent) {
|
|
793
|
-
const parentRanges = this.secondaryRanges[parent];
|
|
794
|
-
if (!parentRanges)
|
|
795
|
-
return;
|
|
796
|
-
range = parentRanges[name];
|
|
797
|
-
}
|
|
798
|
-
else {
|
|
799
|
-
range = this.primaryRanges[name].target;
|
|
800
|
-
}
|
|
801
|
-
// if theres a rangeless dependency, ignore
|
|
802
|
-
if (!range)
|
|
803
|
-
return;
|
|
804
|
-
if (!range.has(pkg))
|
|
805
|
-
return;
|
|
806
|
-
if (range.has(upgradePkg) && upgradePkg.semver.gt(pkg.semver)) {
|
|
807
|
-
// handle orphaning inflight cancellation?
|
|
808
|
-
if (parent)
|
|
809
|
-
this.installTree.dependencies[parent][name] = upgradePkg;
|
|
810
|
-
else
|
|
811
|
-
this.installTree[name] = upgradePkg;
|
|
812
|
-
}
|
|
813
|
-
});
|
|
814
|
-
}
|
|
815
|
-
async setPackageToHash(pkgName, hash) {
|
|
816
|
-
const packageInstallState = await this.getPackageInstallState(pkgName);
|
|
817
|
-
if (packageInstallState.hash === hash)
|
|
818
|
-
return false;
|
|
819
|
-
const { exists, linkPath } = packageInstallState;
|
|
820
|
-
packageInstallState.exists = true;
|
|
821
|
-
packageInstallState.hash = hash;
|
|
822
|
-
packageInstallState.linkPath = undefined;
|
|
823
|
-
const localPackagePath = path.join(this.config.pjson.packages, pkgName.replace(':', path.sep));
|
|
824
|
-
if (exists) {
|
|
825
|
-
if (hash === undefined && linkPath === undefined) {
|
|
826
|
-
this.project.log.info(`Removing checked out package ${pkgName}.`);
|
|
827
|
-
await new Promise((resolve, reject) => rimraf(localPackagePath, err => err ? reject(err) : resolve()));
|
|
828
|
-
}
|
|
829
|
-
else {
|
|
830
|
-
if (linkPath !== undefined)
|
|
831
|
-
this.project.log.info(`Replacing custom symlink for ${pkgName}.`);
|
|
832
|
-
await new Promise((resolve, reject) => fs.unlink(localPackagePath, err => err ? reject(err) : resolve()));
|
|
833
|
-
}
|
|
834
|
-
}
|
|
835
|
-
else {
|
|
836
|
-
await new Promise((resolve, reject) => mkdirp(path.dirname(localPackagePath), err => err ? reject(err) : resolve()));
|
|
837
|
-
}
|
|
838
|
-
const cachePath = path.resolve(this.globalPackagesPath, hash);
|
|
839
|
-
await new Promise((resolve, reject) => mkdirp(path.dirname(localPackagePath), err => err ? reject(err) : resolve()));
|
|
840
|
-
await new Promise((resolve, reject) => fs.symlink(cachePath, localPackagePath, 'junction', err => err ? reject(err) : resolve()));
|
|
841
|
-
return true;
|
|
842
|
-
}
|
|
843
|
-
async setPackageToLinked(pkgName, linkPath) {
|
|
844
|
-
const packageInstallState = await this.getPackageInstallState(pkgName);
|
|
845
|
-
if (packageInstallState.linkPath === linkPath)
|
|
846
|
-
return false;
|
|
847
|
-
const { exists, hash } = packageInstallState;
|
|
848
|
-
packageInstallState.exists = true;
|
|
849
|
-
packageInstallState.hash = undefined;
|
|
850
|
-
packageInstallState.linkPath = linkPath;
|
|
851
|
-
const localPackagePath = path.join(this.config.pjson.packages, pkgName.replace(':', path.sep));
|
|
852
|
-
if (exists) {
|
|
853
|
-
if (hash === undefined && linkPath === undefined) {
|
|
854
|
-
this.project.log.info(`Removing checked out package ${pkgName}.`);
|
|
855
|
-
await new Promise((resolve, reject) => rimraf(localPackagePath, err => err ? reject(err) : resolve()));
|
|
856
|
-
}
|
|
857
|
-
else {
|
|
858
|
-
if (linkPath !== undefined)
|
|
859
|
-
this.project.log.info(`Removing custom symlink for ${pkgName}.`);
|
|
860
|
-
await new Promise((resolve, reject) => fs.unlink(localPackagePath, err => err ? reject(err) : resolve()));
|
|
861
|
-
}
|
|
862
|
-
}
|
|
863
|
-
else {
|
|
864
|
-
await new Promise((resolve, reject) => mkdirp(path.dirname(localPackagePath), err => err ? reject(err) : resolve()));
|
|
865
|
-
}
|
|
866
|
-
await new Promise((resolve, reject) => mkdirp(path.dirname(localPackagePath), err => err ? reject(err) : resolve()));
|
|
867
|
-
await new Promise((resolve, reject) => fs.symlink(path.relative(path.dirname(localPackagePath), linkPath), localPackagePath, 'junction', err => err ? reject(err) : resolve()));
|
|
868
|
-
return true;
|
|
869
|
-
}
|
|
870
|
-
async packageExists(pkgName) {
|
|
871
|
-
const packageInstallState = await this.getPackageInstallState(pkgName);
|
|
872
|
-
return packageInstallState.exists;
|
|
873
|
-
}
|
|
874
|
-
async isPackageCheckedOut(pkgName) {
|
|
875
|
-
const packageInstallState = await this.getPackageInstallState(pkgName);
|
|
876
|
-
return packageInstallState.exists && packageInstallState.hash === undefined && packageInstallState.linkPath === undefined;
|
|
877
|
-
}
|
|
878
|
-
async getPackageInstallState(pkgName) {
|
|
879
|
-
let packageInstallState = this.jspmPackageInstallStateCache[pkgName];
|
|
880
|
-
if (packageInstallState)
|
|
881
|
-
return packageInstallState;
|
|
882
|
-
const pkgPath = path.join(this.config.pjson.packages, pkgName.replace(':', path.sep));
|
|
883
|
-
packageInstallState = {
|
|
884
|
-
exists: false,
|
|
885
|
-
hash: undefined,
|
|
886
|
-
linkPath: undefined
|
|
887
|
-
};
|
|
888
|
-
const symlinkPath = await new Promise((resolve, reject) => {
|
|
889
|
-
fs.readlink(pkgPath, (err, resolvedPath) => {
|
|
890
|
-
if (err) {
|
|
891
|
-
switch (err.code) {
|
|
892
|
-
case 'ENOENT':
|
|
893
|
-
resolve();
|
|
894
|
-
break;
|
|
895
|
-
case 'EINVAL':
|
|
896
|
-
resolve('<UNKNOWN>');
|
|
897
|
-
break;
|
|
898
|
-
case 'UNKNOWN':
|
|
899
|
-
resolve(pkgPath);
|
|
900
|
-
break;
|
|
901
|
-
default:
|
|
902
|
-
reject(err);
|
|
903
|
-
break;
|
|
904
|
-
}
|
|
905
|
-
}
|
|
906
|
-
else {
|
|
907
|
-
resolve(path.resolve(path.dirname(pkgPath), resolvedPath));
|
|
908
|
-
}
|
|
909
|
-
});
|
|
910
|
-
});
|
|
911
|
-
if (!symlinkPath)
|
|
912
|
-
return this.jspmPackageInstallStateCache[pkgName] = packageInstallState;
|
|
913
|
-
packageInstallState.exists = true;
|
|
914
|
-
if (symlinkPath.startsWith(this.globalPackagesPath) && symlinkPath[this.globalPackagesPath.length] === path.sep) {
|
|
915
|
-
const pathHash = symlinkPath.substring(this.globalPackagesPath.length + 1, symlinkPath.length - 1);
|
|
916
|
-
if (pathHash.indexOf(path.sep) === -1) {
|
|
917
|
-
packageInstallState.hash = pathHash;
|
|
918
|
-
return this.jspmPackageInstallStateCache[pkgName] = packageInstallState;
|
|
919
|
-
}
|
|
920
|
-
}
|
|
921
|
-
if (symlinkPath !== pkgPath)
|
|
922
|
-
packageInstallState.linkPath = symlinkPath;
|
|
923
|
-
return this.jspmPackageInstallStateCache[pkgName] = packageInstallState;
|
|
924
|
-
}
|
|
925
|
-
async ensureInstallRanges(exactPkg) {
|
|
926
|
-
await this.installTree.visitAsync(async (pkg, name, parent) => {
|
|
927
|
-
// where an upgrade package is specified,
|
|
928
|
-
// only check ranges that are the same package, but a different version
|
|
929
|
-
if (exactPkg && (pkg.registry !== exactPkg.registry || pkg.name !== exactPkg.name || pkg.version === exactPkg.version))
|
|
930
|
-
return;
|
|
931
|
-
if (parent) {
|
|
932
|
-
const secondaryRanges = this.secondaryRanges[parent];
|
|
933
|
-
if (secondaryRanges && secondaryRanges[name])
|
|
934
|
-
return;
|
|
935
|
-
}
|
|
936
|
-
else {
|
|
937
|
-
const primaryRange = this.primaryRanges[name];
|
|
938
|
-
if (primaryRange)
|
|
939
|
-
return;
|
|
940
|
-
return;
|
|
941
|
-
}
|
|
942
|
-
const parentDepObj = this.installTree.dependencies[parent];
|
|
943
|
-
let config;
|
|
944
|
-
if (await this.packageExists(parent)) {
|
|
945
|
-
config = await this.readCheckedOutConfig(parent, undefined);
|
|
946
|
-
}
|
|
947
|
-
else {
|
|
948
|
-
// no source -> ignore
|
|
949
|
-
if (!parentDepObj || !parentDepObj.source)
|
|
950
|
-
return;
|
|
951
|
-
// fail gracefully eg for offline
|
|
952
|
-
try {
|
|
953
|
-
// we dont verify, reset or alter overrides here because we want to be minimally invasive outside of the direct install tree
|
|
954
|
-
const override = this.getOverride(package_1.parseExactPackageName(parent));
|
|
955
|
-
var installResult = await this.registryManager.ensureInstall(parentDepObj.source, override, this.createCheckoutPrompt(parent), false);
|
|
956
|
-
}
|
|
957
|
-
catch (e) {
|
|
958
|
-
return;
|
|
959
|
-
}
|
|
960
|
-
if (!installResult) {
|
|
961
|
-
config = await this.readCheckedOutConfig(parent, undefined);
|
|
962
|
-
}
|
|
963
|
-
// we dont persist the updated override or check the jspm_packages symlink, because we dont want to
|
|
964
|
-
// alter in any way installed packages not directly on the install tree -> aiming for principle of least surprise to user
|
|
965
|
-
else {
|
|
966
|
-
if (installResult.changed)
|
|
967
|
-
this.changed = true;
|
|
968
|
-
({ config } = installResult);
|
|
969
|
-
}
|
|
970
|
-
}
|
|
971
|
-
const rangeTarget = config.dependencies && config.dependencies[name] ||
|
|
972
|
-
config.peerDependencies && config.peerDependencies[name] ||
|
|
973
|
-
config.optionalDependencies && config.optionalDependencies[name];
|
|
974
|
-
if (!rangeTarget)
|
|
975
|
-
return;
|
|
976
|
-
this.secondaryRanges[parent] = this.secondaryRanges[parent] || {};
|
|
977
|
-
this.secondaryRanges[parent][name] = rangeTarget;
|
|
978
|
-
});
|
|
979
|
-
}
|
|
980
|
-
async clean(save = false) {
|
|
981
|
-
const packageList = [];
|
|
982
|
-
const addDependentPackages = (pkgName) => {
|
|
983
|
-
packageList.push(pkgName);
|
|
984
|
-
// get all immediate children of this package
|
|
985
|
-
// for those children not already seen (in packages list),
|
|
986
|
-
// run getDependentPackages in turn on those
|
|
987
|
-
let depObj = this.installTree.dependencies[pkgName];
|
|
988
|
-
if (!depObj || !depObj.resolve)
|
|
989
|
-
return;
|
|
990
|
-
Object.keys(depObj.resolve).forEach(dep => {
|
|
991
|
-
const curPkg = depObj.resolve[dep];
|
|
992
|
-
const curPkgName = package_1.serializePackageName(curPkg);
|
|
993
|
-
if (packageList.indexOf(curPkgName) !== -1)
|
|
994
|
-
return;
|
|
995
|
-
addDependentPackages(curPkgName);
|
|
996
|
-
});
|
|
997
|
-
};
|
|
998
|
-
// Remove anything not explicitly in package.json
|
|
999
|
-
Object.keys(this.installTree.resolve).forEach(name => {
|
|
1000
|
-
if (!this.primaryRanges[name])
|
|
1001
|
-
delete this.installTree.resolve[name];
|
|
1002
|
-
});
|
|
1003
|
-
// getDependentPackages for each of baseMap
|
|
1004
|
-
Object.keys(this.primaryRanges).forEach(dep => {
|
|
1005
|
-
const resolved = this.installTree.resolve[dep];
|
|
1006
|
-
if (!resolved)
|
|
1007
|
-
return;
|
|
1008
|
-
addDependentPackages(package_1.serializePackageName(resolved));
|
|
1009
|
-
});
|
|
1010
|
-
// now that we have the package list, remove everything not in it
|
|
1011
|
-
Object.keys(this.installTree.dependencies).forEach(dep => {
|
|
1012
|
-
if (packageList.indexOf(dep) === -1) {
|
|
1013
|
-
this.project.log.info(`Removed ${common_1.highlight(dep)}.`);
|
|
1014
|
-
delete this.installTree.dependencies[dep];
|
|
1015
|
-
}
|
|
1016
|
-
});
|
|
1017
|
-
// depthCheck returns true to keep going (files being ignored),
|
|
1018
|
-
// false to add the dir to the flat list
|
|
1019
|
-
const removeNonPackageDirs = async (dir) => {
|
|
1020
|
-
let files = await new Promise((resolve, reject) => fs.readdir(dir, (err, files) => err ? reject(err) : resolve(files)));
|
|
1021
|
-
let deletedAll = true;
|
|
1022
|
-
let relPath = path.relative(this.config.pjson.packages, dir);
|
|
1023
|
-
let pkgBase = relPath.replace(path.sep, ':');
|
|
1024
|
-
if (common_1.isWindows)
|
|
1025
|
-
pkgBase = pkgBase.replace(/\\/g, '/');
|
|
1026
|
-
await Promise.all(files.map(async (file) => {
|
|
1027
|
-
let filePath = path.resolve(dir, file);
|
|
1028
|
-
let pkgName = pkgBase + (pkgBase.indexOf(':') === -1 ? ':' : '/') + file;
|
|
1029
|
-
if (packageList.indexOf(pkgName) !== -1 || pkgName === ':.bin') {
|
|
1030
|
-
deletedAll = false;
|
|
1031
|
-
return;
|
|
1032
|
-
}
|
|
1033
|
-
let fileInfo = await new Promise((resolve, reject) => fs.lstat(filePath, (err, stats) => err ? reject(err) : resolve(stats)));
|
|
1034
|
-
// package folder
|
|
1035
|
-
if (file.indexOf('@') > 0) {
|
|
1036
|
-
// warn on directory removal
|
|
1037
|
-
if (fileInfo.isSymbolicLink()) {
|
|
1038
|
-
await new Promise((resolve, reject) => fs.unlink(filePath, err => err ? reject(err) : resolve()));
|
|
1039
|
-
}
|
|
1040
|
-
else if (fileInfo.isDirectory()) {
|
|
1041
|
-
const remove = await this.project.confirm(`The orphaned package at ${common_1.highlight(filePath)} is currently checked out, are you sure you want to remove it?`, true);
|
|
1042
|
-
if (remove)
|
|
1043
|
-
await new Promise((resolve, reject) => rimraf(filePath, err => err ? reject(err) : resolve()));
|
|
1044
|
-
else
|
|
1045
|
-
deletedAll = false;
|
|
1046
|
-
}
|
|
1047
|
-
// ignore rogue files
|
|
1048
|
-
else { }
|
|
1049
|
-
}
|
|
1050
|
-
// non package folder -> traverse
|
|
1051
|
-
else if (fileInfo.isDirectory()) {
|
|
1052
|
-
if (!(await removeNonPackageDirs(filePath)))
|
|
1053
|
-
deletedAll = false;
|
|
1054
|
-
}
|
|
1055
|
-
// ignore rogue files
|
|
1056
|
-
else { }
|
|
1057
|
-
}));
|
|
1058
|
-
if (deletedAll)
|
|
1059
|
-
await new Promise((resolve, reject) => fs.rmdir(dir, err => err ? reject(err) : resolve()));
|
|
1060
|
-
return deletedAll;
|
|
1061
|
-
};
|
|
1062
|
-
await removeNonPackageDirs(this.config.pjson.packages);
|
|
1063
|
-
if (save)
|
|
1064
|
-
return await this.config.save();
|
|
1065
|
-
}
|
|
1066
|
-
}
|
|
1067
|
-
exports.Installer = Installer;
|
|
1068
|
-
function depsToInstalls(defaultRegistry, deps, parent, skipDepsNames) {
|
|
1069
|
-
let installs = [];
|
|
1070
|
-
if (deps.dependencies)
|
|
1071
|
-
Object.keys(deps.dependencies).forEach(name => {
|
|
1072
|
-
if (skipDepsNames && skipDepsNames.indexOf(name) !== -1)
|
|
1073
|
-
return;
|
|
1074
|
-
let target = deps.dependencies[name];
|
|
1075
|
-
if (target) {
|
|
1076
|
-
if (typeof target !== 'string' && !target.registry)
|
|
1077
|
-
target = target.fromRegistry(defaultRegistry);
|
|
1078
|
-
installs.push({
|
|
1079
|
-
name,
|
|
1080
|
-
parent,
|
|
1081
|
-
target,
|
|
1082
|
-
type: package_1.DepType.secondary
|
|
1083
|
-
});
|
|
1084
|
-
}
|
|
1085
|
-
});
|
|
1086
|
-
if (deps.peerDependencies)
|
|
1087
|
-
Object.keys(deps.peerDependencies).forEach(name => {
|
|
1088
|
-
if (skipDepsNames && skipDepsNames.indexOf(name) !== -1)
|
|
1089
|
-
return;
|
|
1090
|
-
let target = deps.peerDependencies[name];
|
|
1091
|
-
if (target) {
|
|
1092
|
-
if (typeof target !== 'string' && !target.registry)
|
|
1093
|
-
target = target.fromRegistry(defaultRegistry);
|
|
1094
|
-
installs.push({
|
|
1095
|
-
name,
|
|
1096
|
-
parent,
|
|
1097
|
-
target,
|
|
1098
|
-
type: package_1.DepType.peer
|
|
1099
|
-
});
|
|
1100
|
-
}
|
|
1101
|
-
});
|
|
1102
|
-
if (deps.optionalDependencies)
|
|
1103
|
-
Object.keys(deps.optionalDependencies).forEach(name => {
|
|
1104
|
-
if (skipDepsNames && skipDepsNames.indexOf(name) !== -1)
|
|
1105
|
-
return;
|
|
1106
|
-
let target = deps.optionalDependencies[name];
|
|
1107
|
-
if (target) {
|
|
1108
|
-
if (typeof target !== 'string' && !target.registry)
|
|
1109
|
-
target = target.fromRegistry(defaultRegistry);
|
|
1110
|
-
installs.push({
|
|
1111
|
-
name,
|
|
1112
|
-
parent,
|
|
1113
|
-
target,
|
|
1114
|
-
type: package_1.DepType.secondary
|
|
1115
|
-
});
|
|
1116
|
-
}
|
|
1117
|
-
});
|
|
1118
|
-
return installs;
|
|
1119
|
-
}
|
|
1120
|
-
function getResourceName(source, projectPath) {
|
|
1121
|
-
// if the resource is a folder, check the package.json file
|
|
1122
|
-
if (source.startsWith('file:') || source.startsWith('link:')) {
|
|
1123
|
-
const pjsonPath = path.resolve(projectPath, source.substr(5), 'package.json');
|
|
1124
|
-
let pjsonSource;
|
|
1125
|
-
try {
|
|
1126
|
-
pjsonSource = fs.readFileSync(pjsonPath).toString();
|
|
1127
|
-
}
|
|
1128
|
-
catch (err) { }
|
|
1129
|
-
if (pjsonSource) {
|
|
1130
|
-
let pjson;
|
|
1131
|
-
try {
|
|
1132
|
-
pjson = JSON.parse(pjsonSource);
|
|
1133
|
-
}
|
|
1134
|
-
catch (err) {
|
|
1135
|
-
throw new common_1.JspmUserError(`Invalid JSON parsing ${common_1.highlight(pjsonPath)}.`);
|
|
1136
|
-
}
|
|
1137
|
-
if (typeof pjson.name === 'string')
|
|
1138
|
-
return pjson.name;
|
|
1139
|
-
}
|
|
1140
|
-
source = source.substr(0, 5) + path.resolve(projectPath, source.substr(5));
|
|
1141
|
-
}
|
|
1142
|
-
// get name simply from end of resource name
|
|
1143
|
-
// name will be validated on install
|
|
1144
|
-
const refIndex = source.lastIndexOf('#');
|
|
1145
|
-
if (refIndex === -1) {
|
|
1146
|
-
let pathIndex = source.lastIndexOf('/');
|
|
1147
|
-
if (pathIndex === -1)
|
|
1148
|
-
pathIndex = source.lastIndexOf('\\');
|
|
1149
|
-
if (pathIndex === -1)
|
|
1150
|
-
return source.substr(source.indexOf(':') + 1);
|
|
1151
|
-
else
|
|
1152
|
-
return source.substr(pathIndex + 1);
|
|
1153
|
-
}
|
|
1154
|
-
else {
|
|
1155
|
-
let pathIndex = source.lastIndexOf('/', refIndex - 1);
|
|
1156
|
-
if (pathIndex === -1)
|
|
1157
|
-
pathIndex = source.lastIndexOf('\\', refIndex - 1);
|
|
1158
|
-
if (pathIndex === -1)
|
|
1159
|
-
return source.substring(source.indexOf(':') + 1, refIndex);
|
|
1160
|
-
else
|
|
1161
|
-
return source.substring(pathIndex + 1, refIndex);
|
|
1162
|
-
}
|
|
1163
|
-
}
|
|
1164
|
-
//# sourceMappingURL=index.js.map
|