@verdaccio/store 6.0.0-6-next.21 → 6.0.0-6-next.24
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 +92 -0
- package/build/index.d.ts +5 -4
- package/build/index.js +31 -15
- package/build/index.js.map +1 -1
- package/build/lib/TransFormResults.d.ts +15 -0
- package/build/lib/TransFormResults.js +61 -0
- package/build/lib/TransFormResults.js.map +1 -0
- package/build/lib/search-utils.d.ts +4 -0
- package/build/lib/search-utils.js +59 -0
- package/build/lib/search-utils.js.map +1 -0
- package/build/lib/star-utils.d.ts +14 -0
- package/build/{star-utils.js → lib/star-utils.js} +16 -2
- package/build/lib/star-utils.js.map +1 -0
- package/build/lib/storage-utils.d.ts +82 -0
- package/build/{storage-utils.js → lib/storage-utils.js} +173 -60
- package/build/lib/storage-utils.js.map +1 -0
- package/build/lib/uplink-util.d.ts +10 -0
- package/build/lib/uplink-util.js +49 -0
- package/build/lib/uplink-util.js.map +1 -0
- package/build/lib/versions-utils.d.ts +28 -0
- package/build/lib/versions-utils.js +104 -0
- package/build/lib/versions-utils.js.map +1 -0
- package/build/local-storage.d.ts +3 -165
- package/build/local-storage.js +6 -1166
- package/build/local-storage.js.map +1 -1
- package/build/storage.d.ts +242 -86
- package/build/storage.js +1681 -548
- package/build/storage.js.map +1 -1
- package/build/type.d.ts +42 -19
- package/build/type.js.map +1 -1
- package/jest.config.js +8 -2
- package/package.json +71 -71
- package/src/index.ts +5 -4
- package/src/lib/TransFormResults.ts +42 -0
- package/src/lib/search-utils.ts +50 -0
- package/src/{star-utils.ts → lib/star-utils.ts} +16 -5
- package/src/lib/storage-utils.ts +362 -0
- package/src/lib/uplink-util.ts +41 -0
- package/src/lib/versions-utils.ts +87 -0
- package/src/local-storage.ts +7 -1217
- package/src/storage.ts +1683 -635
- package/src/type.ts +47 -21
- package/test/fixtures/config/getTarballNext-getupstream.yaml +17 -0
- package/test/fixtures/config/syncDoubleUplinksMetadata.yaml +25 -0
- package/test/fixtures/config/syncNoUplinksMetadata.yaml +17 -0
- package/test/fixtures/config/syncSingleUplinksMetadata.yaml +21 -0
- package/test/fixtures/config/updateManifest-1.yaml +16 -0
- package/test/fixtures/manifests/foo-npmjs.json +253 -0
- package/test/fixtures/manifests/foo-verdaccio.json +253 -0
- package/test/fixtures/tarball.tgz +0 -0
- package/test/helpers.ts +22 -0
- package/test/local-store.__disabled__.ts +553 -0
- package/test/search.spec.ts +4 -5
- package/test/star.spec.ts +31 -0
- package/test/storage-utils.spec.ts +129 -42
- package/test/storage.spec.ts +943 -33
- package/test/versions.spec.ts +109 -0
- package/tsconfig.json +6 -3
- package/build/search.d.ts +0 -35
- package/build/search.js +0 -198
- package/build/search.js.map +0 -1
- package/build/star-utils.d.ts +0 -9
- package/build/star-utils.js.map +0 -1
- package/build/storage-utils.d.ts +0 -39
- package/build/storage-utils.js.map +0 -1
- package/build/uplink-util.d.ts +0 -7
- package/build/uplink-util.js +0 -38
- package/build/uplink-util.js.map +0 -1
- package/src/search.ts +0 -175
- package/src/storage-utils.ts +0 -263
- package/src/uplink-util.ts +0 -32
- package/test/local-storage.spec.ts +0 -583
package/build/local-storage.js
CHANGED
|
@@ -3,9 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
7
|
-
exports.normalizeSearchPackage = normalizeSearchPackage;
|
|
8
|
-
exports.resourceNotAvailable = void 0;
|
|
6
|
+
exports.resourceNotAvailable = exports.noSuchFile = exports.LocalStorage = void 0;
|
|
9
7
|
|
|
10
8
|
var _assert = _interopRequireDefault(require("assert"));
|
|
11
9
|
|
|
@@ -13,20 +11,12 @@ var _debug = _interopRequireDefault(require("debug"));
|
|
|
13
11
|
|
|
14
12
|
var _lodash = _interopRequireDefault(require("lodash"));
|
|
15
13
|
|
|
16
|
-
var _url = _interopRequireDefault(require("url"));
|
|
17
|
-
|
|
18
14
|
var _core = require("@verdaccio/core");
|
|
19
15
|
|
|
20
16
|
var _loaders = require("@verdaccio/loaders");
|
|
21
17
|
|
|
22
18
|
var _localStorage = _interopRequireDefault(require("@verdaccio/local-storage"));
|
|
23
19
|
|
|
24
|
-
var _streams = require("@verdaccio/streams");
|
|
25
|
-
|
|
26
|
-
var _utils = require("@verdaccio/utils");
|
|
27
|
-
|
|
28
|
-
var _storageUtils = require("./storage-utils");
|
|
29
|
-
|
|
30
20
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
31
21
|
|
|
32
22
|
const debug = (0, _debug.default)('verdaccio:storage:local');
|
|
@@ -35,45 +25,9 @@ exports.noSuchFile = noSuchFile;
|
|
|
35
25
|
const resourceNotAvailable = 'EAGAIN';
|
|
36
26
|
exports.resourceNotAvailable = resourceNotAvailable;
|
|
37
27
|
|
|
38
|
-
function normalizeSearchPackage(pkg, searchItem) {
|
|
39
|
-
const latest = _core.pkgUtils.getLatest(pkg);
|
|
40
|
-
|
|
41
|
-
const version = pkg.versions[latest];
|
|
42
|
-
const result = {
|
|
43
|
-
name: version.name,
|
|
44
|
-
scope: '',
|
|
45
|
-
description: version.description,
|
|
46
|
-
version: latest,
|
|
47
|
-
keywords: version.keywords,
|
|
48
|
-
date: pkg.time[latest],
|
|
49
|
-
// FIXME: type
|
|
50
|
-
author: version.author,
|
|
51
|
-
// FIXME: not possible fill this out from a private package
|
|
52
|
-
publisher: {},
|
|
53
|
-
// FIXME: type
|
|
54
|
-
maintainers: version.maintainers,
|
|
55
|
-
links: {
|
|
56
|
-
npm: '',
|
|
57
|
-
homepage: version.homepage,
|
|
58
|
-
repository: version.repository,
|
|
59
|
-
bugs: version.bugs
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
if (typeof searchItem.package.scoped === 'string') {
|
|
64
|
-
result.scope = searchItem.package.scoped;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
return result;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const PROTO_NAME = '__proto__';
|
|
71
28
|
/**
|
|
72
29
|
* Implements Storage interface (same for storage.js, local-storage.js, up-storage.js).
|
|
73
30
|
*/
|
|
74
|
-
|
|
75
|
-
exports.PROTO_NAME = PROTO_NAME;
|
|
76
|
-
|
|
77
31
|
class LocalStorage {
|
|
78
32
|
constructor(config, logger) {
|
|
79
33
|
debug('local storage created');
|
|
@@ -98,1102 +52,12 @@ class LocalStorage {
|
|
|
98
52
|
return;
|
|
99
53
|
}
|
|
100
54
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const storage = this._getLocalStorage(name);
|
|
105
|
-
|
|
106
|
-
if (_lodash.default.isNil(storage)) {
|
|
107
|
-
debug(`storage is missing for %o package cannot be added`, name);
|
|
108
|
-
return callback(_core.errorUtils.getNotFound('this package cannot be added'));
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
storage.createPackage(name, (0, _storageUtils.generatePackageTemplate)(name), err => {
|
|
112
|
-
if (_lodash.default.isNull(err) === false && (err.code === _storageUtils.STORAGE.FILE_EXIST_ERROR || err.code === _core.HTTP_STATUS.CONFLICT)) {
|
|
113
|
-
debug(`error on creating a package for %o with error %o`, name, err.message);
|
|
114
|
-
return callback(_core.errorUtils.getConflict());
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
const latest = (0, _utils.getLatestVersion)(pkg);
|
|
118
|
-
|
|
119
|
-
if (_lodash.default.isNil(latest) === false && pkg.versions[latest]) {
|
|
120
|
-
debug('latest version found %o for %o', latest, name);
|
|
121
|
-
return callback(null, pkg.versions[latest]);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
debug('no latest version found for %o', name);
|
|
125
|
-
return callback();
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* Remove package with all it contents.
|
|
130
|
-
*/
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
async removePackage(name) {
|
|
134
|
-
debug('remove package %s', name);
|
|
135
|
-
|
|
136
|
-
const storage = this._getLocalStorage(name);
|
|
137
|
-
|
|
138
|
-
if (_lodash.default.isNil(storage)) {
|
|
139
|
-
throw _core.errorUtils.getNotFound();
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
return new Promise((resolve, reject) => {
|
|
143
|
-
storage.readPackage(name, async (err, data) => {
|
|
144
|
-
if (_lodash.default.isNil(err) === false) {
|
|
145
|
-
if (err.code === _storageUtils.STORAGE.NO_SUCH_FILE_ERROR || err.code === _core.HTTP_STATUS.NOT_FOUND) {
|
|
146
|
-
debug(`error on not found %o with error %o`, name, err.message);
|
|
147
|
-
return reject(_core.errorUtils.getNotFound());
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
return reject(err);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
data = (0, _storageUtils.normalizePackage)(data);
|
|
154
|
-
|
|
155
|
-
try {
|
|
156
|
-
await this.storagePlugin.remove(name); // remove each attachment
|
|
157
|
-
|
|
158
|
-
const attachments = Object.keys(data._attachments);
|
|
159
|
-
debug('attachments to remove %s', attachments === null || attachments === void 0 ? void 0 : attachments.length);
|
|
160
|
-
|
|
161
|
-
for (let attachment of attachments) {
|
|
162
|
-
debug('remove attachment %s', attachment);
|
|
163
|
-
await storage.deletePackage(attachment);
|
|
164
|
-
} // remove package.json
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
debug('remove package.json');
|
|
168
|
-
await storage.deletePackage(_storageUtils.STORAGE.PACKAGE_FILE_NAME); // remove folder
|
|
169
|
-
|
|
170
|
-
debug('remove package folder');
|
|
171
|
-
await storage.removePackage();
|
|
172
|
-
resolve();
|
|
173
|
-
} catch (err) {
|
|
174
|
-
this.logger.error({
|
|
175
|
-
err
|
|
176
|
-
}, 'removed package has failed @{err.message}');
|
|
177
|
-
throw _core.errorUtils.getBadData(err.message);
|
|
178
|
-
}
|
|
179
|
-
});
|
|
180
|
-
});
|
|
181
|
-
}
|
|
182
|
-
/**
|
|
183
|
-
* Synchronize remote package info with the local one
|
|
184
|
-
* @param {*} name
|
|
185
|
-
* @param {*} packageInfo
|
|
186
|
-
* @param {*} callback
|
|
187
|
-
*/
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
updateVersions(name, packageInfo, callback) {
|
|
191
|
-
debug(`updating versions for package %o`, name);
|
|
192
|
-
|
|
193
|
-
this._readCreatePackage(name, (err, packageLocalJson) => {
|
|
194
|
-
if (err) {
|
|
195
|
-
return callback(err);
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
let change = false; // updating readme
|
|
199
|
-
|
|
200
|
-
packageLocalJson.readme = (0, _storageUtils.getLatestReadme)(packageInfo);
|
|
201
|
-
|
|
202
|
-
if (packageInfo.readme !== packageLocalJson.readme) {
|
|
203
|
-
change = true;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
debug('update versions');
|
|
207
|
-
|
|
208
|
-
for (const versionId in packageInfo.versions) {
|
|
209
|
-
if (_lodash.default.isNil(packageLocalJson.versions[versionId])) {
|
|
210
|
-
var _version, _version$dist;
|
|
211
|
-
|
|
212
|
-
let version = packageInfo.versions[versionId]; // we don't keep readme for package versions,
|
|
213
|
-
// only one readme per package
|
|
214
|
-
|
|
215
|
-
version = (0, _storageUtils.cleanUpReadme)(version);
|
|
216
|
-
debug('clean up readme for %o', versionId);
|
|
217
|
-
version.contributors = (0, _utils.normalizeContributors)(version.contributors);
|
|
218
|
-
change = true;
|
|
219
|
-
packageLocalJson.versions[versionId] = version;
|
|
220
|
-
|
|
221
|
-
if ((_version = version) !== null && _version !== void 0 && (_version$dist = _version.dist) !== null && _version$dist !== void 0 && _version$dist.tarball) {
|
|
222
|
-
const urlObject = _url.default.parse(version.dist.tarball);
|
|
223
|
-
|
|
224
|
-
const filename = urlObject.pathname.replace(/^.*\//, ''); // we do NOT overwrite any existing records
|
|
225
|
-
|
|
226
|
-
if (_lodash.default.isNil(packageLocalJson._distfiles[filename])) {
|
|
227
|
-
const hash = packageLocalJson._distfiles[filename] = {
|
|
228
|
-
url: version.dist.tarball,
|
|
229
|
-
sha: version.dist.shasum
|
|
230
|
-
};
|
|
231
|
-
const upLink = version[Symbol.for('__verdaccio_uplink')];
|
|
232
|
-
|
|
233
|
-
if (_lodash.default.isNil(upLink) === false) {
|
|
234
|
-
this._updateUplinkToRemoteProtocol(hash, upLink);
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
debug('update dist-tags');
|
|
242
|
-
|
|
243
|
-
for (const tag in packageInfo[_core.DIST_TAGS]) {
|
|
244
|
-
if (!packageLocalJson[_core.DIST_TAGS][tag] || packageLocalJson[_core.DIST_TAGS][tag] !== packageInfo[_core.DIST_TAGS][tag]) {
|
|
245
|
-
change = true;
|
|
246
|
-
packageLocalJson[_core.DIST_TAGS][tag] = packageInfo[_core.DIST_TAGS][tag];
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
for (const up in packageInfo._uplinks) {
|
|
251
|
-
if (Object.prototype.hasOwnProperty.call(packageInfo._uplinks, up)) {
|
|
252
|
-
const need_change = !(0, _utils.isObject)(packageLocalJson._uplinks[up]) || packageInfo._uplinks[up].etag !== packageLocalJson._uplinks[up].etag || packageInfo._uplinks[up].fetched !== packageLocalJson._uplinks[up].fetched;
|
|
253
|
-
|
|
254
|
-
if (need_change) {
|
|
255
|
-
change = true;
|
|
256
|
-
packageLocalJson._uplinks[up] = packageInfo._uplinks[up];
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
debug('update time');
|
|
262
|
-
|
|
263
|
-
if ('time' in packageInfo && !_lodash.default.isEqual(packageLocalJson.time, packageInfo.time)) {
|
|
264
|
-
packageLocalJson.time = packageInfo.time;
|
|
265
|
-
change = true;
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
if (change) {
|
|
269
|
-
debug('updating package info %o', name);
|
|
270
|
-
|
|
271
|
-
this._writePackage(name, packageLocalJson, function (err) {
|
|
272
|
-
callback(err, packageLocalJson);
|
|
273
|
-
});
|
|
274
|
-
} else {
|
|
275
|
-
callback(null, packageLocalJson);
|
|
276
|
-
}
|
|
277
|
-
});
|
|
278
|
-
}
|
|
279
|
-
/**
|
|
280
|
-
* Add a new version to a previous local package.
|
|
281
|
-
* @param {*} name
|
|
282
|
-
* @param {*} version
|
|
283
|
-
* @param {*} metadata
|
|
284
|
-
* @param {*} tag
|
|
285
|
-
* @param {*} callback
|
|
286
|
-
*/
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
addVersion(name, version, metadata, tag, callback) {
|
|
290
|
-
debug(`add version %s package for %s`, version, name);
|
|
291
|
-
|
|
292
|
-
this._updatePackage(name, async (data, cb) => {
|
|
293
|
-
debug('%s package is being updated', name); // keep only one readme per package
|
|
294
|
-
|
|
295
|
-
data.readme = metadata.readme;
|
|
296
|
-
debug('%s` readme mutated', name); // TODO: lodash remove
|
|
297
|
-
|
|
298
|
-
metadata = (0, _storageUtils.cleanUpReadme)(metadata);
|
|
299
|
-
metadata.contributors = (0, _utils.normalizeContributors)(metadata.contributors);
|
|
300
|
-
debug('%s` contributors normalized', name);
|
|
301
|
-
const hasVersion = data.versions[version] != null;
|
|
302
|
-
|
|
303
|
-
if (hasVersion) {
|
|
304
|
-
debug('%s version %s already exists', name, version);
|
|
305
|
-
return cb(_core.errorUtils.getConflict());
|
|
306
|
-
} // if uploaded tarball has a different shasum, it's very likely that we
|
|
307
|
-
// have some kind of error
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
if (_core.validatioUtils.isObject(metadata.dist) && _lodash.default.isString(metadata.dist.tarball)) {
|
|
311
|
-
const tarball = metadata.dist.tarball.replace(/.*\//, '');
|
|
312
|
-
|
|
313
|
-
if (_core.validatioUtils.isObject(data._attachments[tarball])) {
|
|
314
|
-
if (_lodash.default.isNil(data._attachments[tarball].shasum) === false && _lodash.default.isNil(metadata.dist.shasum) === false) {
|
|
315
|
-
if (data._attachments[tarball].shasum != metadata.dist.shasum) {
|
|
316
|
-
const errorMessage = `shasum error, ` + `${data._attachments[tarball].shasum} != ${metadata.dist.shasum}`;
|
|
317
|
-
return cb(_core.errorUtils.getBadRequest(errorMessage));
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
const currentDate = new Date().toISOString(); // some old storage do not have this field #740
|
|
322
|
-
|
|
323
|
-
if (_lodash.default.isNil(data.time)) {
|
|
324
|
-
data.time = {};
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
data.time['modified'] = currentDate;
|
|
328
|
-
|
|
329
|
-
if ('created' in data.time === false) {
|
|
330
|
-
data.time.created = currentDate;
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
data.time[version] = currentDate;
|
|
334
|
-
data._attachments[tarball].version = version;
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
data.versions[version] = metadata;
|
|
339
|
-
(0, _storageUtils.tagVersion)(data, version, tag);
|
|
340
|
-
|
|
341
|
-
try {
|
|
342
|
-
debug('%s` add on database', name);
|
|
343
|
-
await this.storagePlugin.add(name);
|
|
344
|
-
cb();
|
|
345
|
-
} catch (err) {
|
|
346
|
-
cb(_core.errorUtils.getBadData(err.message));
|
|
347
|
-
}
|
|
348
|
-
}, callback);
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
async addVersionNext(name, version, metadata, tag) {
|
|
352
|
-
debug(`add version %s package for %s`, version, name);
|
|
353
|
-
await this.updatePackageNext(name, async data => {
|
|
354
|
-
debug('%s package is being updated', name); // keep only one readme per package
|
|
355
|
-
|
|
356
|
-
data.readme = metadata.readme;
|
|
357
|
-
debug('%s` readme mutated', name); // TODO: lodash remove
|
|
358
|
-
|
|
359
|
-
metadata = (0, _storageUtils.cleanUpReadme)(metadata);
|
|
360
|
-
metadata.contributors = (0, _utils.normalizeContributors)(metadata.contributors);
|
|
361
|
-
debug('%s` contributors normalized', name);
|
|
362
|
-
const hasVersion = data.versions[version] != null;
|
|
363
|
-
|
|
364
|
-
if (hasVersion) {
|
|
365
|
-
debug('%s version %s already exists', name, version);
|
|
366
|
-
throw _core.errorUtils.getConflict();
|
|
367
|
-
} // if uploaded tarball has a different shasum, it's very likely that we
|
|
368
|
-
// have some kind of error
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
if (_core.validatioUtils.isObject(metadata.dist) && _lodash.default.isString(metadata.dist.tarball)) {
|
|
372
|
-
const tarball = metadata.dist.tarball.replace(/.*\//, '');
|
|
373
|
-
|
|
374
|
-
if (_core.validatioUtils.isObject(data._attachments[tarball])) {
|
|
375
|
-
if (_lodash.default.isNil(data._attachments[tarball].shasum) === false && _lodash.default.isNil(metadata.dist.shasum) === false) {
|
|
376
|
-
if (data._attachments[tarball].shasum != metadata.dist.shasum) {
|
|
377
|
-
const errorMessage = `shasum error, ` + `${data._attachments[tarball].shasum} != ${metadata.dist.shasum}`;
|
|
378
|
-
throw _core.errorUtils.getBadRequest(errorMessage);
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
const currentDate = new Date().toISOString(); // some old storage do not have this field #740
|
|
383
|
-
|
|
384
|
-
if (_lodash.default.isNil(data.time)) {
|
|
385
|
-
data.time = {};
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
data.time['modified'] = currentDate;
|
|
389
|
-
|
|
390
|
-
if ('created' in data.time === false) {
|
|
391
|
-
data.time.created = currentDate;
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
data.time[version] = currentDate;
|
|
395
|
-
data._attachments[tarball].version = version;
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
data.versions[version] = metadata;
|
|
400
|
-
(0, _storageUtils.tagVersion)(data, version, tag);
|
|
401
|
-
|
|
402
|
-
try {
|
|
403
|
-
debug('%s` add on database', name);
|
|
404
|
-
await this.storagePlugin.add(name);
|
|
405
|
-
} catch (err) {
|
|
406
|
-
throw _core.errorUtils.getBadData(err.message);
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
return data;
|
|
410
|
-
}); // this._updatePackage(
|
|
411
|
-
// name,
|
|
412
|
-
// async (data, cb: Callback): Promise<void> => {
|
|
413
|
-
// debug('%s package is being updated', name);
|
|
414
|
-
// // keep only one readme per package
|
|
415
|
-
// data.readme = metadata.readme;
|
|
416
|
-
// debug('%s` readme mutated', name);
|
|
417
|
-
// // TODO: lodash remove
|
|
418
|
-
// metadata = cleanUpReadme(metadata);
|
|
419
|
-
// metadata.contributors = normalizeContributors(metadata.contributors as Author[]);
|
|
420
|
-
// debug('%s` contributors normalized', name);
|
|
421
|
-
// const hasVersion = data.versions[version] != null;
|
|
422
|
-
// if (hasVersion) {
|
|
423
|
-
// debug('%s version %s already exists', name, version);
|
|
424
|
-
// return cb(errorUtils.getConflict());
|
|
425
|
-
// }
|
|
426
|
-
// // if uploaded tarball has a different shasum, it's very likely that we
|
|
427
|
-
// // have some kind of error
|
|
428
|
-
// if (validatioUtils.isObject(metadata.dist) && _.isString(metadata.dist.tarball)) {
|
|
429
|
-
// const tarball = metadata.dist.tarball.replace(/.*\//, '');
|
|
430
|
-
// if (validatioUtils.isObject(data._attachments[tarball])) {
|
|
431
|
-
// if (
|
|
432
|
-
// _.isNil(data._attachments[tarball].shasum) === false &&
|
|
433
|
-
// _.isNil(metadata.dist.shasum) === false
|
|
434
|
-
// ) {
|
|
435
|
-
// if (data._attachments[tarball].shasum != metadata.dist.shasum) {
|
|
436
|
-
// const errorMessage =
|
|
437
|
-
// `shasum error, ` +
|
|
438
|
-
// `${data._attachments[tarball].shasum} != ${metadata.dist.shasum}`;
|
|
439
|
-
// return cb(errorUtils.getBadRequest(errorMessage));
|
|
440
|
-
// }
|
|
441
|
-
// }
|
|
442
|
-
// const currentDate = new Date().toISOString();
|
|
443
|
-
// // some old storage do not have this field #740
|
|
444
|
-
// if (_.isNil(data.time)) {
|
|
445
|
-
// data.time = {};
|
|
446
|
-
// }
|
|
447
|
-
// data.time['modified'] = currentDate;
|
|
448
|
-
// if ('created' in data.time === false) {
|
|
449
|
-
// data.time.created = currentDate;
|
|
450
|
-
// }
|
|
451
|
-
// data.time[version] = currentDate;
|
|
452
|
-
// data._attachments[tarball].version = version;
|
|
453
|
-
// }
|
|
454
|
-
// }
|
|
455
|
-
// data.versions[version] = metadata;
|
|
456
|
-
// tagVersion(data, version, tag);
|
|
457
|
-
// try {
|
|
458
|
-
// debug('%s` add on database', name);
|
|
459
|
-
// await this.storagePlugin.add(name);
|
|
460
|
-
// cb();
|
|
461
|
-
// } catch (err: any) {
|
|
462
|
-
// cb(errorUtils.getBadData(err.message));
|
|
463
|
-
// }
|
|
464
|
-
// },
|
|
465
|
-
// callback
|
|
466
|
-
// );
|
|
467
|
-
}
|
|
468
|
-
/**
|
|
469
|
-
* Merge a new list of tags for a local packages with the existing one.
|
|
470
|
-
* @param {*} pkgName
|
|
471
|
-
* @param {*} tags
|
|
472
|
-
* @param {*} callback
|
|
473
|
-
*/
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
mergeTags(pkgName, tags, callback) {
|
|
477
|
-
debug(`merge tags for`, pkgName);
|
|
478
|
-
|
|
479
|
-
this._updatePackage(pkgName, (data, cb) => {
|
|
480
|
-
/* eslint guard-for-in: 0 */
|
|
481
|
-
for (const tag in tags) {
|
|
482
|
-
// this handle dist-tag rm command
|
|
483
|
-
if (_lodash.default.isNull(tags[tag])) {
|
|
484
|
-
delete data[_core.DIST_TAGS][tag];
|
|
485
|
-
continue;
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
if (_lodash.default.isNil(data.versions[tags[tag]])) {
|
|
489
|
-
return cb(_core.errorUtils.getNotFound(_core.API_ERROR.VERSION_NOT_EXIST));
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
const version = tags[tag];
|
|
493
|
-
(0, _storageUtils.tagVersion)(data, version, tag);
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
cb(null);
|
|
497
|
-
}, callback);
|
|
498
|
-
}
|
|
499
|
-
/**
|
|
500
|
-
* Update the package metadata, tags and attachments (tarballs).
|
|
501
|
-
* Note: Currently supports unpublishing and deprecation.
|
|
502
|
-
* @param {*} name
|
|
503
|
-
* @param {*} incomingPkg
|
|
504
|
-
* @param {*} revision
|
|
505
|
-
* @param {*} callback
|
|
506
|
-
* @return {Function}
|
|
507
|
-
*/
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
changePackage(name, incomingPkg, revision, callback) {
|
|
511
|
-
debug(`change package tags for %o revision %s`, name, revision);
|
|
512
|
-
|
|
513
|
-
if (!_core.validatioUtils.isObject(incomingPkg.versions) || !_core.validatioUtils.isObject(incomingPkg[_core.DIST_TAGS])) {
|
|
514
|
-
debug(`change package bad data for %o`, name);
|
|
515
|
-
return callback(_core.errorUtils.getBadData());
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
debug(`change package udapting package for %o`, name);
|
|
519
|
-
|
|
520
|
-
this._updatePackage(name, (localData, cb) => {
|
|
521
|
-
for (const version in localData.versions) {
|
|
522
|
-
const incomingVersion = incomingPkg.versions[version];
|
|
523
|
-
|
|
524
|
-
if (_lodash.default.isNil(incomingVersion)) {
|
|
525
|
-
this.logger.info({
|
|
526
|
-
name: name,
|
|
527
|
-
version: version
|
|
528
|
-
}, 'unpublishing @{name}@@{version}'); // FIXME: I prefer return a new object rather mutate the metadata
|
|
529
|
-
|
|
530
|
-
delete localData.versions[version];
|
|
531
|
-
delete localData.time[version];
|
|
532
|
-
|
|
533
|
-
for (const file in localData._attachments) {
|
|
534
|
-
if (localData._attachments[file].version === version) {
|
|
535
|
-
delete localData._attachments[file].version;
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
} else if (Object.prototype.hasOwnProperty.call(incomingVersion, 'deprecated')) {
|
|
539
|
-
const incomingDeprecated = incomingVersion.deprecated;
|
|
540
|
-
|
|
541
|
-
if (incomingDeprecated != localData.versions[version].deprecated) {
|
|
542
|
-
if (!incomingDeprecated) {
|
|
543
|
-
this.logger.info({
|
|
544
|
-
name: name,
|
|
545
|
-
version: version
|
|
546
|
-
}, 'undeprecating @{name}@@{version}');
|
|
547
|
-
delete localData.versions[version].deprecated;
|
|
548
|
-
} else {
|
|
549
|
-
this.logger.info({
|
|
550
|
-
name: name,
|
|
551
|
-
version: version
|
|
552
|
-
}, 'deprecating @{name}@@{version}');
|
|
553
|
-
localData.versions[version].deprecated = incomingDeprecated;
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
localData.time.modified = new Date().toISOString();
|
|
557
|
-
}
|
|
558
|
-
}
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
localData[_core.USERS] = incomingPkg[_core.USERS];
|
|
562
|
-
localData[_core.DIST_TAGS] = incomingPkg[_core.DIST_TAGS];
|
|
563
|
-
cb(null);
|
|
564
|
-
}, function (err) {
|
|
565
|
-
if (err) {
|
|
566
|
-
return callback(err);
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
callback();
|
|
570
|
-
});
|
|
571
|
-
}
|
|
572
|
-
/**
|
|
573
|
-
* Update the package metadata, tags and attachments (tarballs).
|
|
574
|
-
* Note: Currently supports unpublishing and deprecation.
|
|
575
|
-
* @param {*} name
|
|
576
|
-
* @param {*} incomingPkg
|
|
577
|
-
* @param {*} revision
|
|
578
|
-
* @param {*} callback
|
|
579
|
-
* @return {Function}
|
|
580
|
-
*/
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
async changePackageNext(name, incomingPkg, revision) {
|
|
584
|
-
debug(`change package tags for %o revision %s`, name, revision);
|
|
585
|
-
|
|
586
|
-
if (!_core.validatioUtils.isObject(incomingPkg.versions) || !_core.validatioUtils.isObject(incomingPkg[_core.DIST_TAGS])) {
|
|
587
|
-
debug(`change package bad data for %o`, name);
|
|
588
|
-
throw _core.errorUtils.getBadData();
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
debug(`change package udapting package for %o`, name);
|
|
592
|
-
await this.updatePackageNext(name, async localData => {
|
|
593
|
-
for (const version in localData.versions) {
|
|
594
|
-
const incomingVersion = incomingPkg.versions[version];
|
|
595
|
-
|
|
596
|
-
if (_lodash.default.isNil(incomingVersion)) {
|
|
597
|
-
this.logger.info({
|
|
598
|
-
name: name,
|
|
599
|
-
version: version
|
|
600
|
-
}, 'unpublishing @{name}@@{version}'); // FIXME: I prefer return a new object rather mutate the metadata
|
|
601
|
-
|
|
602
|
-
delete localData.versions[version];
|
|
603
|
-
delete localData.time[version];
|
|
604
|
-
|
|
605
|
-
for (const file in localData._attachments) {
|
|
606
|
-
if (localData._attachments[file].version === version) {
|
|
607
|
-
delete localData._attachments[file].version;
|
|
608
|
-
}
|
|
609
|
-
}
|
|
610
|
-
} else if (Object.prototype.hasOwnProperty.call(incomingVersion, 'deprecated')) {
|
|
611
|
-
const incomingDeprecated = incomingVersion.deprecated;
|
|
612
|
-
|
|
613
|
-
if (incomingDeprecated != localData.versions[version].deprecated) {
|
|
614
|
-
if (!incomingDeprecated) {
|
|
615
|
-
this.logger.info({
|
|
616
|
-
name: name,
|
|
617
|
-
version: version
|
|
618
|
-
}, 'undeprecating @{name}@@{version}');
|
|
619
|
-
delete localData.versions[version].deprecated;
|
|
620
|
-
} else {
|
|
621
|
-
this.logger.info({
|
|
622
|
-
name: name,
|
|
623
|
-
version: version
|
|
624
|
-
}, 'deprecating @{name}@@{version}');
|
|
625
|
-
localData.versions[version].deprecated = incomingDeprecated;
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
localData.time.modified = new Date().toISOString();
|
|
629
|
-
}
|
|
630
|
-
}
|
|
631
|
-
}
|
|
632
|
-
|
|
633
|
-
localData[_core.USERS] = incomingPkg[_core.USERS];
|
|
634
|
-
localData[_core.DIST_TAGS] = incomingPkg[_core.DIST_TAGS];
|
|
635
|
-
return localData;
|
|
636
|
-
});
|
|
637
|
-
}
|
|
638
|
-
/**
|
|
639
|
-
* Remove a tarball.
|
|
640
|
-
* @param {*} name
|
|
641
|
-
* @param {*} filename
|
|
642
|
-
* @param {*} revision
|
|
643
|
-
* @param {*} callback
|
|
644
|
-
*/
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
removeTarball(name, filename, revision, callback) {
|
|
648
|
-
debug('remove tarball %s for %s', filename, name);
|
|
649
|
-
(0, _assert.default)(_core.validatioUtils.validateName(filename));
|
|
650
|
-
|
|
651
|
-
this._updatePackage(name, (data, cb) => {
|
|
652
|
-
if (data._attachments[filename]) {
|
|
653
|
-
// TODO: avoid using delete
|
|
654
|
-
delete data._attachments[filename];
|
|
655
|
-
cb(null);
|
|
656
|
-
} else {
|
|
657
|
-
cb(_core.errorUtils.getNotFound('no such file available'));
|
|
658
|
-
}
|
|
659
|
-
}, err => {
|
|
660
|
-
if (err) {
|
|
661
|
-
this.logger.error({
|
|
662
|
-
err
|
|
663
|
-
}, 'remove tarball error @{err.message}');
|
|
664
|
-
return callback(err);
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
const storage = this._getLocalStorage(name);
|
|
668
|
-
|
|
669
|
-
if (storage) {
|
|
670
|
-
debug('removing %s from storage', filename);
|
|
671
|
-
storage.deletePackage(filename).then(() => {
|
|
672
|
-
debug('package %s removed', filename);
|
|
673
|
-
return callback(null);
|
|
674
|
-
}).catch(err => {
|
|
675
|
-
this.logger.error({
|
|
676
|
-
err
|
|
677
|
-
}, 'error removing %s from storage');
|
|
678
|
-
return callback(null);
|
|
679
|
-
});
|
|
680
|
-
} else {
|
|
681
|
-
callback(_core.errorUtils.getInternalError());
|
|
682
|
-
}
|
|
683
|
-
});
|
|
684
|
-
}
|
|
685
|
-
/**
|
|
686
|
-
* Add a tarball.
|
|
687
|
-
* @param {String} name
|
|
688
|
-
* @param {String} filename
|
|
689
|
-
* @return {Stream}
|
|
690
|
-
*/
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
addTarball(name, filename) {
|
|
694
|
-
debug(`add a tarball for %o`, name);
|
|
695
|
-
(0, _assert.default)(_core.validatioUtils.validateName(filename));
|
|
696
|
-
let length = 0;
|
|
697
|
-
const shaOneHash = (0, _utils.createTarballHash)();
|
|
698
|
-
const uploadStream = new _streams.UploadTarball({});
|
|
699
|
-
const _transform = uploadStream._transform;
|
|
700
|
-
|
|
701
|
-
const storage = this._getLocalStorage(name);
|
|
702
|
-
|
|
703
|
-
uploadStream.abort = function () {};
|
|
704
|
-
|
|
705
|
-
uploadStream.done = function () {};
|
|
706
|
-
|
|
707
|
-
uploadStream._transform = function (data, ...args) {
|
|
708
|
-
shaOneHash.update(data); // measure the length for validation reasons
|
|
709
|
-
|
|
710
|
-
length += data.length;
|
|
711
|
-
const appliedData = [data, ...args]; // FIXME: not sure about this approach, tsc complains
|
|
712
|
-
// @ts-ignore
|
|
713
|
-
|
|
714
|
-
_transform.apply(uploadStream, appliedData);
|
|
715
|
-
};
|
|
716
|
-
|
|
717
|
-
if (name === PROTO_NAME) {
|
|
718
|
-
process.nextTick(() => {
|
|
719
|
-
uploadStream.emit('error', _core.errorUtils.getForbidden());
|
|
720
|
-
});
|
|
721
|
-
return uploadStream;
|
|
722
|
-
} // FIXME: this condition will never met, storage is always defined
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
if (!storage) {
|
|
726
|
-
process.nextTick(() => {
|
|
727
|
-
uploadStream.emit('error', "can't upload this package");
|
|
728
|
-
});
|
|
729
|
-
return uploadStream;
|
|
730
|
-
}
|
|
731
|
-
|
|
732
|
-
const writeStream = storage.writeTarball(filename);
|
|
733
|
-
writeStream.on('error', err => {
|
|
734
|
-
// @ts-ignore
|
|
735
|
-
if (err.code === _storageUtils.STORAGE.FILE_EXIST_ERROR || err.code === _core.HTTP_STATUS.CONFLICT) {
|
|
736
|
-
uploadStream.emit('error', _core.errorUtils.getConflict());
|
|
737
|
-
uploadStream.abort(); // @ts-ignore
|
|
738
|
-
} else if (err.code === _storageUtils.STORAGE.NO_SUCH_FILE_ERROR || err.code === _core.HTTP_STATUS.NOT_FOUND) {
|
|
739
|
-
// check if package exists to throw an appropriate message
|
|
740
|
-
this.getPackageMetadata(name, function (_err) {
|
|
741
|
-
if (_err) {
|
|
742
|
-
uploadStream.emit('error', _err);
|
|
743
|
-
} else {
|
|
744
|
-
uploadStream.emit('error', err);
|
|
745
|
-
}
|
|
746
|
-
});
|
|
747
|
-
} else {
|
|
748
|
-
uploadStream.emit('error', err);
|
|
749
|
-
}
|
|
750
|
-
});
|
|
751
|
-
writeStream.on('open', function () {
|
|
752
|
-
// re-emitting open because it's handled in storage.js
|
|
753
|
-
uploadStream.emit('open');
|
|
754
|
-
});
|
|
755
|
-
writeStream.on('success', () => {
|
|
756
|
-
this._updatePackage(name, function updater(data, cb) {
|
|
757
|
-
// FUTURE: move this to tarballUtils
|
|
758
|
-
data._attachments[filename] = {
|
|
759
|
-
shasum: shaOneHash.digest('hex')
|
|
760
|
-
};
|
|
761
|
-
cb(null);
|
|
762
|
-
}, function (err) {
|
|
763
|
-
if (err) {
|
|
764
|
-
// FIXME: if the update package fails, remove tarball to avoid left
|
|
765
|
-
// orphan tarballs
|
|
766
|
-
uploadStream.emit('error', err);
|
|
767
|
-
} else {
|
|
768
|
-
uploadStream.emit('success');
|
|
769
|
-
}
|
|
770
|
-
});
|
|
771
|
-
});
|
|
772
|
-
|
|
773
|
-
uploadStream.abort = function () {
|
|
774
|
-
writeStream.abort();
|
|
775
|
-
};
|
|
776
|
-
|
|
777
|
-
uploadStream.done = function () {
|
|
778
|
-
if (!length) {
|
|
779
|
-
uploadStream.emit('error', _core.errorUtils.getBadData('refusing to accept zero-length file'));
|
|
780
|
-
writeStream.abort();
|
|
781
|
-
} else {
|
|
782
|
-
writeStream.done();
|
|
783
|
-
}
|
|
784
|
-
};
|
|
785
|
-
|
|
786
|
-
uploadStream.pipe(writeStream);
|
|
787
|
-
return uploadStream;
|
|
788
|
-
}
|
|
789
|
-
/**
|
|
790
|
-
* Get a tarball.
|
|
791
|
-
* @param {*} name
|
|
792
|
-
* @param {*} filename
|
|
793
|
-
* @return {ReadTarball}
|
|
794
|
-
*/
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
getTarball(name, filename) {
|
|
798
|
-
(0, _assert.default)(_core.validatioUtils.validateName(filename));
|
|
799
|
-
|
|
800
|
-
const storage = this._getLocalStorage(name);
|
|
801
|
-
|
|
802
|
-
if (_lodash.default.isNil(storage)) {
|
|
803
|
-
return this._createFailureStreamResponse();
|
|
804
|
-
}
|
|
805
|
-
|
|
806
|
-
return this._streamSuccessReadTarBall(storage, filename);
|
|
807
|
-
}
|
|
808
|
-
/**
|
|
809
|
-
* Return a stream that emits a read failure.
|
|
810
|
-
* @private
|
|
811
|
-
* @return {ReadTarball}
|
|
812
|
-
*/
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
_createFailureStreamResponse() {
|
|
816
|
-
const stream = new _streams.ReadTarball({});
|
|
817
|
-
process.nextTick(() => {
|
|
818
|
-
stream.emit('error', _core.errorUtils.getNotFound('no such file available'));
|
|
819
|
-
});
|
|
820
|
-
return stream;
|
|
821
|
-
}
|
|
822
|
-
/**
|
|
823
|
-
* Return a stream that emits the tarball data
|
|
824
|
-
* @param {Object} storage
|
|
825
|
-
* @param {String} filename
|
|
826
|
-
* @private
|
|
827
|
-
* @return {ReadTarball}
|
|
828
|
-
*/
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
_streamSuccessReadTarBall(storage, filename) {
|
|
832
|
-
const stream = new _streams.ReadTarball({});
|
|
833
|
-
const readTarballStream = storage.readTarball(filename);
|
|
834
|
-
const e404 = _core.errorUtils.getNotFound;
|
|
835
|
-
|
|
836
|
-
stream.abort = function () {
|
|
837
|
-
if (_lodash.default.isNil(readTarballStream) === false) {
|
|
838
|
-
readTarballStream.abort();
|
|
839
|
-
}
|
|
840
|
-
};
|
|
841
|
-
|
|
842
|
-
readTarballStream.on('error', function (err) {
|
|
843
|
-
// @ts-ignore
|
|
844
|
-
if (err.code === _storageUtils.STORAGE.NO_SUCH_FILE_ERROR || err.code === _core.HTTP_STATUS.NOT_FOUND) {
|
|
845
|
-
stream.emit('error', e404('no such file available'));
|
|
846
|
-
} else {
|
|
847
|
-
stream.emit('error', err);
|
|
848
|
-
}
|
|
849
|
-
});
|
|
850
|
-
readTarballStream.on('content-length', function (content) {
|
|
851
|
-
stream.emit('content-length', content);
|
|
852
|
-
});
|
|
853
|
-
readTarballStream.on('open', function () {
|
|
854
|
-
// re-emitting open because it's handled in storage.js
|
|
855
|
-
stream.emit('open');
|
|
856
|
-
readTarballStream.pipe(stream);
|
|
857
|
-
});
|
|
858
|
-
return stream;
|
|
859
|
-
}
|
|
860
|
-
|
|
861
|
-
async getPackageMetadataNext(name) {
|
|
862
|
-
const storage = this._getLocalStorage(name);
|
|
863
|
-
|
|
864
|
-
debug('get package metadata for %o', name);
|
|
865
|
-
|
|
866
|
-
if (typeof storage === 'undefined') {
|
|
867
|
-
// TODO: this might be a better an error to throw
|
|
868
|
-
// if storage is not there cannot be 404.
|
|
869
|
-
throw _core.errorUtils.getNotFound();
|
|
870
|
-
}
|
|
871
|
-
|
|
872
|
-
return await this._readPackageNext(name, storage);
|
|
873
|
-
}
|
|
874
|
-
/**
|
|
875
|
-
* Retrieve a package by name.
|
|
876
|
-
* @param {*} name
|
|
877
|
-
* @param {*} callback
|
|
878
|
-
* @return {Function}
|
|
879
|
-
* @deprecated
|
|
880
|
-
*/
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
getPackageMetadata(name, callback = () => {}) {
|
|
884
|
-
const storage = this._getLocalStorage(name);
|
|
885
|
-
|
|
886
|
-
debug('get package metadata for %o', name);
|
|
887
|
-
|
|
888
|
-
if (typeof storage === 'undefined') {
|
|
889
|
-
return callback(_core.errorUtils.getNotFound());
|
|
890
|
-
}
|
|
891
|
-
|
|
892
|
-
this._readPackage(name, storage, callback);
|
|
893
|
-
}
|
|
894
|
-
|
|
895
|
-
async search(searchStream, query) {
|
|
896
|
-
debug('search on each package');
|
|
897
|
-
this.logger.info({
|
|
898
|
-
t: query.text,
|
|
899
|
-
q: query.quality,
|
|
900
|
-
p: query.popularity,
|
|
901
|
-
m: query.maintenance,
|
|
902
|
-
s: query.size
|
|
903
|
-
}, 'search by text @{t}| maintenance @{m}| quality @{q}| popularity @{p}');
|
|
904
|
-
|
|
905
|
-
const getMetadata = searchItem => {
|
|
906
|
-
return new Promise((resolve, reject) => {
|
|
907
|
-
var _searchItem$package;
|
|
908
|
-
|
|
909
|
-
this.getPackageMetadata(searchItem === null || searchItem === void 0 ? void 0 : (_searchItem$package = searchItem.package) === null || _searchItem$package === void 0 ? void 0 : _searchItem$package.name, (err, pkg) => {
|
|
910
|
-
var _searchItem$package3;
|
|
911
|
-
|
|
912
|
-
if (err) {
|
|
913
|
-
var _searchItem$package2;
|
|
914
|
-
|
|
915
|
-
this.logger.error({
|
|
916
|
-
err,
|
|
917
|
-
pkgName: searchItem === null || searchItem === void 0 ? void 0 : (_searchItem$package2 = searchItem.package) === null || _searchItem$package2 === void 0 ? void 0 : _searchItem$package2.name
|
|
918
|
-
}, 'error on load package @{pkgName} metaadata @{err.message}');
|
|
919
|
-
reject(err);
|
|
920
|
-
}
|
|
921
|
-
|
|
922
|
-
if (_lodash.default.isEmpty(pkg === null || pkg === void 0 ? void 0 : pkg.versions)) {
|
|
923
|
-
return resolve({});
|
|
924
|
-
}
|
|
925
|
-
|
|
926
|
-
const searchPackage = normalizeSearchPackage(pkg, searchItem);
|
|
927
|
-
const searchPackageItem = {
|
|
928
|
-
package: searchPackage,
|
|
929
|
-
score: searchItem.score,
|
|
930
|
-
verdaccioPkgCached: searchItem.verdaccioPkgCached,
|
|
931
|
-
verdaccioPrivate: searchItem.verdaccioPrivate,
|
|
932
|
-
flags: searchItem === null || searchItem === void 0 ? void 0 : searchItem.flags,
|
|
933
|
-
// FUTURE: find a better way to calculate the score
|
|
934
|
-
searchScore: 1
|
|
935
|
-
};
|
|
936
|
-
debug('push to stream %o', searchItem === null || searchItem === void 0 ? void 0 : (_searchItem$package3 = searchItem.package) === null || _searchItem$package3 === void 0 ? void 0 : _searchItem$package3.name);
|
|
937
|
-
resolve(searchPackageItem);
|
|
938
|
-
});
|
|
939
|
-
});
|
|
940
|
-
};
|
|
941
|
-
|
|
942
|
-
if (typeof this.storagePlugin.search === 'undefined') {
|
|
943
|
-
this.logger.info('plugin search not implemented yet');
|
|
944
|
-
searchStream.end();
|
|
945
|
-
} else {
|
|
946
|
-
debug('search on each package by plugin');
|
|
947
|
-
const items = await this.storagePlugin.search(query);
|
|
948
|
-
|
|
949
|
-
try {
|
|
950
|
-
for (const item of items) {
|
|
951
|
-
const metadata = await getMetadata(item);
|
|
952
|
-
searchStream.write(metadata);
|
|
953
|
-
}
|
|
954
|
-
|
|
955
|
-
debug('search local stream end');
|
|
956
|
-
searchStream.end();
|
|
957
|
-
} catch (err) {
|
|
958
|
-
this.logger.error({
|
|
959
|
-
err,
|
|
960
|
-
query
|
|
961
|
-
}, 'error on search by plugin @{err.message}');
|
|
962
|
-
searchStream.emit('error', err);
|
|
963
|
-
}
|
|
964
|
-
}
|
|
965
|
-
}
|
|
966
|
-
/**
|
|
967
|
-
* Retrieve a wrapper that provide access to the package location.
|
|
968
|
-
* @param {Object} pkgName package name.
|
|
969
|
-
* @return {Object}
|
|
970
|
-
*/
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
_getLocalStorage(pkgName) {
|
|
974
|
-
debug('get local storage for %o', pkgName);
|
|
975
|
-
return this.storagePlugin.getPackageStorage(pkgName);
|
|
976
|
-
}
|
|
977
|
-
/**
|
|
978
|
-
* Read a json file from storage.
|
|
979
|
-
* @param {Object} storage
|
|
980
|
-
* @param {Function} callback
|
|
981
|
-
* @deprecated
|
|
982
|
-
*/
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
_readPackage(name, storage, callback) {
|
|
986
|
-
storage.readPackage(name, (err, result) => {
|
|
987
|
-
if (err) {
|
|
988
|
-
if (err.code === _storageUtils.STORAGE.NO_SUCH_FILE_ERROR || err.code === _core.HTTP_STATUS.NOT_FOUND) {
|
|
989
|
-
debug('package %s not found', name);
|
|
990
|
-
return callback(_core.errorUtils.getNotFound());
|
|
991
|
-
}
|
|
992
|
-
|
|
993
|
-
return callback(this._internalError(err, _storageUtils.STORAGE.PACKAGE_FILE_NAME, 'error reading'));
|
|
994
|
-
}
|
|
995
|
-
|
|
996
|
-
callback(err, (0, _storageUtils.normalizePackage)(result));
|
|
997
|
-
});
|
|
998
|
-
}
|
|
999
|
-
|
|
1000
|
-
async _readPackageNext(name, storage) {
|
|
1001
|
-
try {
|
|
1002
|
-
const result = await storage.readPackageNext(name);
|
|
1003
|
-
return (0, _storageUtils.normalizePackage)(result);
|
|
1004
|
-
} catch (err) {
|
|
1005
|
-
if (err.code === _storageUtils.STORAGE.NO_SUCH_FILE_ERROR || err.code === _core.HTTP_STATUS.NOT_FOUND) {
|
|
1006
|
-
debug('package %s not found', name);
|
|
1007
|
-
throw _core.errorUtils.getNotFound();
|
|
1008
|
-
}
|
|
1009
|
-
|
|
1010
|
-
this.logger.error({
|
|
1011
|
-
err: err,
|
|
1012
|
-
file: _storageUtils.STORAGE.PACKAGE_FILE_NAME
|
|
1013
|
-
}, `error reading @{file}: @{!err.message}`);
|
|
1014
|
-
throw _core.errorUtils.getInternalError();
|
|
1015
|
-
}
|
|
1016
|
-
}
|
|
1017
|
-
/**
|
|
1018
|
-
* Retrieve either a previous created local package or a boilerplate.
|
|
1019
|
-
* @param {*} pkgName
|
|
1020
|
-
* @param {*} callback
|
|
1021
|
-
* @return {Function}
|
|
1022
|
-
*/
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
_readCreatePackage(pkgName, callback) {
|
|
1026
|
-
const storage = this._getLocalStorage(pkgName);
|
|
1027
|
-
|
|
1028
|
-
if (_lodash.default.isNil(storage)) {
|
|
1029
|
-
this._createNewPackage(pkgName, callback);
|
|
1030
|
-
|
|
1031
|
-
return;
|
|
1032
|
-
}
|
|
1033
|
-
|
|
1034
|
-
storage.readPackage(pkgName, (err, data) => {
|
|
1035
|
-
// TODO: race condition
|
|
1036
|
-
if (_lodash.default.isNil(err) === false) {
|
|
1037
|
-
if (err.code === _storageUtils.STORAGE.NO_SUCH_FILE_ERROR || err.code === _core.HTTP_STATUS.NOT_FOUND) {
|
|
1038
|
-
data = (0, _storageUtils.generatePackageTemplate)(pkgName);
|
|
1039
|
-
} else {
|
|
1040
|
-
return callback(this._internalError(err, _storageUtils.STORAGE.PACKAGE_FILE_NAME, 'error reading'));
|
|
1041
|
-
}
|
|
1042
|
-
}
|
|
1043
|
-
|
|
1044
|
-
callback(null, (0, _storageUtils.normalizePackage)(data));
|
|
1045
|
-
});
|
|
1046
|
-
}
|
|
1047
|
-
|
|
1048
|
-
_createNewPackage(name, callback) {
|
|
1049
|
-
return callback(null, (0, _storageUtils.normalizePackage)((0, _storageUtils.generatePackageTemplate)(name)));
|
|
1050
|
-
}
|
|
1051
|
-
/**
|
|
1052
|
-
* Handle internal error
|
|
1053
|
-
* @param {*} err
|
|
1054
|
-
* @param {*} file
|
|
1055
|
-
* @param {*} message
|
|
1056
|
-
* @return {Object} Error instance
|
|
1057
|
-
*/
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
_internalError(err, file, message) {
|
|
1061
|
-
this.logger.error({
|
|
1062
|
-
err: err,
|
|
1063
|
-
file: file
|
|
1064
|
-
}, `${message} @{file}: @{!err.message}`);
|
|
1065
|
-
return _core.errorUtils.getInternalError();
|
|
1066
|
-
}
|
|
1067
|
-
/**
|
|
1068
|
-
* @param {*} name package name
|
|
1069
|
-
* @param {*} updateHandler function(package, cb) - update function
|
|
1070
|
-
* @param {*} callback callback that gets invoked after it's all updated
|
|
1071
|
-
* @return {Function}
|
|
1072
|
-
*/
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
_updatePackage(name, updateHandler, onEnd) {
|
|
1076
|
-
const storage = this._getLocalStorage(name);
|
|
1077
|
-
|
|
1078
|
-
if (!storage) {
|
|
1079
|
-
return onEnd(_core.errorUtils.getNotFound());
|
|
1080
|
-
}
|
|
1081
|
-
|
|
1082
|
-
storage.updatePackage(name, updateHandler, this._writePackage.bind(this), _storageUtils.normalizePackage, onEnd);
|
|
1083
|
-
}
|
|
1084
|
-
/**
|
|
1085
|
-
* @param {*} name package name
|
|
1086
|
-
* @param {*} updateHandler function(package, cb) - update function
|
|
1087
|
-
* @param {*} callback callback that gets invoked after it's all updated
|
|
1088
|
-
* @return {Function}
|
|
1089
|
-
*/
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
async updatePackageNext(name, updateHandler) {
|
|
1093
|
-
const storage = this._getLocalStorage(name);
|
|
1094
|
-
|
|
1095
|
-
if (!storage) {
|
|
1096
|
-
throw _core.errorUtils.getNotFound();
|
|
1097
|
-
} // we update the package on the local storage
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
const updatedManifest = await storage.updatePackageNext(name, updateHandler); // after correctly updated write to the storage
|
|
1101
|
-
|
|
1102
|
-
try {
|
|
1103
|
-
await this.writePackageNext(name, (0, _storageUtils.normalizePackage)(updatedManifest));
|
|
1104
|
-
} catch (err) {
|
|
1105
|
-
if (err.code === resourceNotAvailable) {
|
|
1106
|
-
throw _core.errorUtils.getInternalError('resource temporarily unavailable');
|
|
1107
|
-
} else if (err.code === noSuchFile) {
|
|
1108
|
-
throw _core.errorUtils.getNotFound();
|
|
1109
|
-
} else {
|
|
1110
|
-
throw err;
|
|
1111
|
-
}
|
|
1112
|
-
}
|
|
1113
|
-
}
|
|
1114
|
-
/**
|
|
1115
|
-
* Update the revision (_rev) string for a package.
|
|
1116
|
-
* @param {*} name
|
|
1117
|
-
* @param {*} json
|
|
1118
|
-
* @param {*} callback
|
|
1119
|
-
* @return {Function}
|
|
1120
|
-
*/
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
_writePackage(name, json, callback) {
|
|
1124
|
-
const storage = this._getLocalStorage(name);
|
|
1125
|
-
|
|
1126
|
-
if (_lodash.default.isNil(storage)) {
|
|
1127
|
-
return callback();
|
|
1128
|
-
}
|
|
1129
|
-
|
|
1130
|
-
storage.savePackage(name, this._setDefaultRevision(json), callback);
|
|
1131
|
-
}
|
|
1132
|
-
|
|
1133
|
-
async writePackageNext(name, json) {
|
|
1134
|
-
const storage = this._getLocalStorage(name);
|
|
1135
|
-
|
|
1136
|
-
if (_lodash.default.isNil(storage)) {
|
|
1137
|
-
// TODO: replace here 500 error
|
|
1138
|
-
throw _core.errorUtils.getBadData();
|
|
55
|
+
getStoragePlugin() {
|
|
56
|
+
if (this.storagePlugin === null) {
|
|
57
|
+
throw _core.errorUtils.getInternalError('storage plugin is not initialized');
|
|
1139
58
|
}
|
|
1140
59
|
|
|
1141
|
-
|
|
1142
|
-
}
|
|
1143
|
-
|
|
1144
|
-
_setDefaultRevision(json) {
|
|
1145
|
-
// calculate revision from couch db
|
|
1146
|
-
if (_lodash.default.isString(json._rev) === false) {
|
|
1147
|
-
json._rev = _storageUtils.STORAGE.DEFAULT_REVISION;
|
|
1148
|
-
} // this is intended in debug mode we do not want modify the store revision
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
if (_lodash.default.isNil(this.config._debug)) {
|
|
1152
|
-
json._rev = (0, _storageUtils.generateRevision)(json._rev);
|
|
1153
|
-
}
|
|
1154
|
-
|
|
1155
|
-
return json;
|
|
1156
|
-
} // private _deleteAttachments(storage: any, attachments: string[], callback: Callback): void {
|
|
1157
|
-
// debug('deleting %o attachments total %o', attachments?.length);
|
|
1158
|
-
// const unlinkNext = function (cb): void {
|
|
1159
|
-
// if (_.isEmpty(attachments)) {
|
|
1160
|
-
// return cb();
|
|
1161
|
-
// }
|
|
1162
|
-
// const attachment = attachments.shift();
|
|
1163
|
-
// storage.deletePackage(attachment, function (): void {
|
|
1164
|
-
// unlinkNext(cb);
|
|
1165
|
-
// });
|
|
1166
|
-
// };
|
|
1167
|
-
// unlinkNext(function (): void {
|
|
1168
|
-
// // try to unlink the directory, but ignore errors because it can fail
|
|
1169
|
-
// storage.removePackage(function (err): void {
|
|
1170
|
-
// callback(err);
|
|
1171
|
-
// });
|
|
1172
|
-
// });
|
|
1173
|
-
// }
|
|
1174
|
-
|
|
1175
|
-
/**
|
|
1176
|
-
* Ensure the dist file remains as the same protocol
|
|
1177
|
-
* @param {Object} hash metadata
|
|
1178
|
-
* @param {String} upLinkKey registry key
|
|
1179
|
-
* @private
|
|
1180
|
-
*/
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
_updateUplinkToRemoteProtocol(hash, upLinkKey) {
|
|
1184
|
-
// if we got this information from a known registry,
|
|
1185
|
-
// use the same protocol for the tarball
|
|
1186
|
-
//
|
|
1187
|
-
// see https://github.com/rlidwka/sinopia/issues/166
|
|
1188
|
-
const tarballUrl = _url.default.parse(hash.url);
|
|
1189
|
-
|
|
1190
|
-
const uplinkUrl = _url.default.parse(this.config.uplinks[upLinkKey].url);
|
|
1191
|
-
|
|
1192
|
-
if (uplinkUrl.host === tarballUrl.host) {
|
|
1193
|
-
tarballUrl.protocol = uplinkUrl.protocol;
|
|
1194
|
-
hash.registry = upLinkKey;
|
|
1195
|
-
hash.url = _url.default.format(tarballUrl);
|
|
1196
|
-
}
|
|
60
|
+
return this.storagePlugin;
|
|
1197
61
|
}
|
|
1198
62
|
|
|
1199
63
|
async getSecret(config) {
|
|
@@ -1206,7 +70,7 @@ class LocalStorage {
|
|
|
1206
70
|
|
|
1207
71
|
if (_lodash.default.isNil(Storage)) {
|
|
1208
72
|
(0, _assert.default)(this.config.storage, 'CONFIG: storage path not defined');
|
|
1209
|
-
return new _localStorage.default(
|
|
73
|
+
return new _localStorage.default(config, logger);
|
|
1210
74
|
}
|
|
1211
75
|
|
|
1212
76
|
return Storage;
|
|
@@ -1223,30 +87,6 @@ class LocalStorage {
|
|
|
1223
87
|
return _lodash.default.head(plugins);
|
|
1224
88
|
}
|
|
1225
89
|
|
|
1226
|
-
saveToken(token) {
|
|
1227
|
-
if (_lodash.default.isFunction(this.storagePlugin.saveToken) === false) {
|
|
1228
|
-
return Promise.reject(_core.errorUtils.getCode(_core.HTTP_STATUS.SERVICE_UNAVAILABLE, _core.SUPPORT_ERRORS.PLUGIN_MISSING_INTERFACE));
|
|
1229
|
-
}
|
|
1230
|
-
|
|
1231
|
-
return this.storagePlugin.saveToken(token);
|
|
1232
|
-
}
|
|
1233
|
-
|
|
1234
|
-
deleteToken(user, tokenKey) {
|
|
1235
|
-
if (_lodash.default.isFunction(this.storagePlugin.deleteToken) === false) {
|
|
1236
|
-
return Promise.reject(_core.errorUtils.getCode(_core.HTTP_STATUS.SERVICE_UNAVAILABLE, _core.SUPPORT_ERRORS.PLUGIN_MISSING_INTERFACE));
|
|
1237
|
-
}
|
|
1238
|
-
|
|
1239
|
-
return this.storagePlugin.deleteToken(user, tokenKey);
|
|
1240
|
-
}
|
|
1241
|
-
|
|
1242
|
-
readTokens(filter) {
|
|
1243
|
-
if (_lodash.default.isFunction(this.storagePlugin.readTokens) === false) {
|
|
1244
|
-
return Promise.reject(_core.errorUtils.getCode(_core.HTTP_STATUS.SERVICE_UNAVAILABLE, _core.SUPPORT_ERRORS.PLUGIN_MISSING_INTERFACE));
|
|
1245
|
-
}
|
|
1246
|
-
|
|
1247
|
-
return this.storagePlugin.readTokens(filter);
|
|
1248
|
-
}
|
|
1249
|
-
|
|
1250
90
|
}
|
|
1251
91
|
|
|
1252
92
|
exports.LocalStorage = LocalStorage;
|