@verdaccio/local-storage 11.0.0-6-next.20 → 11.0.0-6-next.22
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/build/dir-utils.js +11 -20
- package/build/dir-utils.js.map +1 -1
- package/build/fs.js +0 -8
- package/build/fs.js.map +1 -1
- package/build/index.js +0 -3
- package/build/index.js.map +1 -1
- package/build/local-database.d.ts +1 -1
- package/build/local-database.js +11 -85
- package/build/local-database.js.map +1 -1
- package/build/local-fs.d.ts +1 -1
- package/build/local-fs.js +29 -85
- package/build/local-fs.js.map +1 -1
- package/build/pkg-utils.d.ts +1 -1
- package/build/pkg-utils.js +0 -9
- package/build/pkg-utils.js.map +1 -1
- package/build/utils.js +3 -21
- package/build/utils.js.map +1 -1
- package/package.json +7 -7
package/build/dir-utils.js
CHANGED
|
@@ -5,24 +5,18 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.getFolders = getFolders;
|
|
7
7
|
exports.searchOnStorage = searchOnStorage;
|
|
8
|
-
|
|
9
8
|
var _debug = _interopRequireDefault(require("debug"));
|
|
10
|
-
|
|
11
9
|
var _globby = _interopRequireDefault(require("globby"));
|
|
12
|
-
|
|
13
10
|
var _path = require("path");
|
|
14
|
-
|
|
15
11
|
var _core = require("@verdaccio/core");
|
|
16
|
-
|
|
17
12
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
18
|
-
|
|
19
13
|
const debug = (0, _debug.default)('verdaccio:plugin:local-storage:utils');
|
|
14
|
+
|
|
20
15
|
/**
|
|
21
16
|
* Retrieve a list of absolute paths to all folders in the given storage path
|
|
22
17
|
* @param storagePath the base path of the storage
|
|
23
18
|
* @return a promise that resolves to an array of absolute paths
|
|
24
19
|
*/
|
|
25
|
-
|
|
26
20
|
async function getFolders(storagePath, pattern = '*') {
|
|
27
21
|
// @ts-ignore - check why this fails, types are correct
|
|
28
22
|
const files = await (0, _globby.default)(pattern, {
|
|
@@ -36,13 +30,15 @@ async function getFolders(storagePath, pattern = '*') {
|
|
|
36
30
|
dot: false,
|
|
37
31
|
followSymbolicLinks: true,
|
|
38
32
|
caseSensitiveMatch: true,
|
|
39
|
-
unique: true
|
|
33
|
+
unique: true
|
|
34
|
+
// FIXME: add here list of forbiden patterns
|
|
40
35
|
// don't include scoped folders.
|
|
41
36
|
// ignore: [`@*`],
|
|
42
|
-
|
|
43
37
|
});
|
|
38
|
+
|
|
44
39
|
return files;
|
|
45
40
|
}
|
|
41
|
+
|
|
46
42
|
/**
|
|
47
43
|
* Search packages on the the storage. The storage could be
|
|
48
44
|
* - storage
|
|
@@ -69,23 +65,20 @@ async function getFolders(storagePath, pattern = '*') {
|
|
|
69
65
|
* and are intended to organize packages in a tree structure.
|
|
70
66
|
* @returns {Promise<searchUtils.SearchItemPkg[]>}
|
|
71
67
|
*/
|
|
72
|
-
|
|
73
|
-
|
|
74
68
|
async function searchOnStorage(storagePath, storages) {
|
|
75
69
|
const matchedStorages = Array.from(storages);
|
|
76
|
-
const storageFolders = Array.from(storages.keys());
|
|
70
|
+
const storageFolders = Array.from(storages.keys());
|
|
71
|
+
// const getScopedFolders = async (pkgName) => {
|
|
77
72
|
// const scopedPackages = await getFolders(join(storagePath, pkgName), '*');
|
|
78
73
|
// const listScoped = scopedPackages.map((scoped) => ({
|
|
79
74
|
// name: `${pkgName}/${scoped}`,
|
|
80
75
|
// }));
|
|
81
76
|
// };
|
|
82
|
-
|
|
83
77
|
debug('search on %o', storagePath);
|
|
84
78
|
debug('storage folders %o', matchedStorages.length);
|
|
85
|
-
let results = [];
|
|
86
|
-
|
|
79
|
+
let results = [];
|
|
80
|
+
// watch base path and ignore storage folders
|
|
87
81
|
const basePathFolders = (await getFolders(storagePath, '*')).filter(storageFolder => !storageFolders.includes(storageFolder));
|
|
88
|
-
|
|
89
82
|
for (let store of basePathFolders) {
|
|
90
83
|
if (_core.validatioUtils.isPackageNameScoped(store)) {
|
|
91
84
|
const scopedPackages = await getFolders((0, _path.join)(storagePath, store), '*');
|
|
@@ -99,12 +92,11 @@ async function searchOnStorage(storagePath, storages) {
|
|
|
99
92
|
name: store
|
|
100
93
|
});
|
|
101
94
|
}
|
|
102
|
-
}
|
|
103
|
-
|
|
95
|
+
}
|
|
104
96
|
|
|
97
|
+
// iterate each storage folder
|
|
105
98
|
for (const store of storageFolders) {
|
|
106
99
|
const foldersOnStorage = await getFolders((0, _path.join)(storagePath, store), '*');
|
|
107
|
-
|
|
108
100
|
for (let pkgName of foldersOnStorage) {
|
|
109
101
|
if (_core.validatioUtils.isPackageNameScoped(pkgName)) {
|
|
110
102
|
const scopedPackages = await getFolders((0, _path.join)(storagePath, store, pkgName), '*');
|
|
@@ -120,7 +112,6 @@ async function searchOnStorage(storagePath, storages) {
|
|
|
120
112
|
}
|
|
121
113
|
}
|
|
122
114
|
}
|
|
123
|
-
|
|
124
115
|
return results;
|
|
125
116
|
}
|
|
126
117
|
//# sourceMappingURL=dir-utils.js.map
|
package/build/dir-utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dir-utils.js","names":["debug","buildDebug","getFolders","storagePath","pattern","files","globby","cwd","expandDirectories","onlyDirectories","onlyFiles","deep","dot","followSymbolicLinks","caseSensitiveMatch","unique","searchOnStorage","storages","matchedStorages","Array","from","storageFolders","keys","length","results","basePathFolders","filter","storageFolder","includes","store","validatioUtils","isPackageNameScoped","scopedPackages","join","listScoped","map","scoped","name","push","foldersOnStorage","pkgName"],"sources":["../src/dir-utils.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport globby from 'globby';\nimport { join } from 'path';\n\nimport { searchUtils, validatioUtils } from '@verdaccio/core';\n\nconst debug = buildDebug('verdaccio:plugin:local-storage:utils');\n\n/**\n * Retrieve a list of absolute paths to all folders in the given storage path\n * @param storagePath the base path of the storage\n * @return a promise that resolves to an array of absolute paths\n */\nexport async function getFolders(storagePath: string, pattern = '*'): Promise<string[]> {\n // @ts-ignore - check why this fails, types are correct\n const files = await globby(pattern, {\n // @ts-ignore\n cwd: storagePath,\n expandDirectories: true,\n onlyDirectories: true,\n onlyFiles: false,\n // should not go deeper than the storage path (10 is reseaon for the storage))\n deep: 10,\n dot: false,\n followSymbolicLinks: true,\n caseSensitiveMatch: true,\n unique: true,\n // FIXME: add here list of forbiden patterns\n // don't include scoped folders.\n // ignore: [`@*`],\n });\n return files;\n}\n\n/**\n * Search packages on the the storage. The storage could be\n * - storage\n * - pkg1\n * - @company\n * - pkg2 -> @scompany/pkg2\n * - storage1\n * - pkg2\n * - pkg3\n * - storage2\n * - @scope\n * - pkg4 > @scope/pkg4\n * The search return a data structure like:\n * [\n * {\n * name: 'pkg1', // package name could be @scope/pkg1\n * path: absolute/path/package/name\n * }\n * ]\n * @param {string} storagePath is the base path of the storage folder,\n * inside could be packages, storages and @scope packages.\n * @param {Set<string>} storages storages are defined peer package access pattern via `storage` property\n * @param query is the search query from the user via npm search command.\n * and are intended to organize packages in a tree structure.\n * @returns {Promise<searchUtils.SearchItemPkg[]>}\n */\nexport async function searchOnStorage(\n storagePath: string,\n storages: Map<string, string>\n): Promise<searchUtils.SearchItemPkg[]> {\n const matchedStorages = Array.from(storages);\n const storageFolders = Array.from(storages.keys());\n // const getScopedFolders = async (pkgName) => {\n // const scopedPackages = await getFolders(join(storagePath, pkgName), '*');\n // const listScoped = scopedPackages.map((scoped) => ({\n // name: `${pkgName}/${scoped}`,\n // }));\n // };\n debug('search on %o', storagePath);\n debug('storage folders %o', matchedStorages.length);\n let results: searchUtils.SearchItemPkg[] = [];\n // watch base path and ignore storage folders\n const basePathFolders = (await getFolders(storagePath, '*')).filter(\n (storageFolder) => !storageFolders.includes(storageFolder)\n );\n\n for (let store of basePathFolders) {\n if (validatioUtils.isPackageNameScoped(store)) {\n const scopedPackages = await getFolders(join(storagePath, store), '*');\n const listScoped = scopedPackages.map((scoped) => ({\n name: `${store}/${scoped}`,\n scoped: store,\n }));\n results.push(...listScoped);\n } else {\n results.push({\n name: store,\n });\n }\n }\n\n // iterate each storage folder\n for (const store of storageFolders) {\n const foldersOnStorage = await getFolders(join(storagePath, store), '*');\n for (let pkgName of foldersOnStorage) {\n if (validatioUtils.isPackageNameScoped(pkgName)) {\n const scopedPackages = await getFolders(join(storagePath, store, pkgName), '*');\n const listScoped = scopedPackages.map((scoped) => ({\n name: `${pkgName}/${scoped}`,\n scoped: pkgName,\n }));\n results.push(...listScoped);\n } else {\n results.push({\n name: pkgName,\n });\n }\n }\n }\n\n return results;\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"dir-utils.js","names":["debug","buildDebug","getFolders","storagePath","pattern","files","globby","cwd","expandDirectories","onlyDirectories","onlyFiles","deep","dot","followSymbolicLinks","caseSensitiveMatch","unique","searchOnStorage","storages","matchedStorages","Array","from","storageFolders","keys","length","results","basePathFolders","filter","storageFolder","includes","store","validatioUtils","isPackageNameScoped","scopedPackages","join","listScoped","map","scoped","name","push","foldersOnStorage","pkgName"],"sources":["../src/dir-utils.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport globby from 'globby';\nimport { join } from 'path';\n\nimport { searchUtils, validatioUtils } from '@verdaccio/core';\n\nconst debug = buildDebug('verdaccio:plugin:local-storage:utils');\n\n/**\n * Retrieve a list of absolute paths to all folders in the given storage path\n * @param storagePath the base path of the storage\n * @return a promise that resolves to an array of absolute paths\n */\nexport async function getFolders(storagePath: string, pattern = '*'): Promise<string[]> {\n // @ts-ignore - check why this fails, types are correct\n const files = await globby(pattern, {\n // @ts-ignore\n cwd: storagePath,\n expandDirectories: true,\n onlyDirectories: true,\n onlyFiles: false,\n // should not go deeper than the storage path (10 is reseaon for the storage))\n deep: 10,\n dot: false,\n followSymbolicLinks: true,\n caseSensitiveMatch: true,\n unique: true,\n // FIXME: add here list of forbiden patterns\n // don't include scoped folders.\n // ignore: [`@*`],\n });\n return files;\n}\n\n/**\n * Search packages on the the storage. The storage could be\n * - storage\n * - pkg1\n * - @company\n * - pkg2 -> @scompany/pkg2\n * - storage1\n * - pkg2\n * - pkg3\n * - storage2\n * - @scope\n * - pkg4 > @scope/pkg4\n * The search return a data structure like:\n * [\n * {\n * name: 'pkg1', // package name could be @scope/pkg1\n * path: absolute/path/package/name\n * }\n * ]\n * @param {string} storagePath is the base path of the storage folder,\n * inside could be packages, storages and @scope packages.\n * @param {Set<string>} storages storages are defined peer package access pattern via `storage` property\n * @param query is the search query from the user via npm search command.\n * and are intended to organize packages in a tree structure.\n * @returns {Promise<searchUtils.SearchItemPkg[]>}\n */\nexport async function searchOnStorage(\n storagePath: string,\n storages: Map<string, string>\n): Promise<searchUtils.SearchItemPkg[]> {\n const matchedStorages = Array.from(storages);\n const storageFolders = Array.from(storages.keys());\n // const getScopedFolders = async (pkgName) => {\n // const scopedPackages = await getFolders(join(storagePath, pkgName), '*');\n // const listScoped = scopedPackages.map((scoped) => ({\n // name: `${pkgName}/${scoped}`,\n // }));\n // };\n debug('search on %o', storagePath);\n debug('storage folders %o', matchedStorages.length);\n let results: searchUtils.SearchItemPkg[] = [];\n // watch base path and ignore storage folders\n const basePathFolders = (await getFolders(storagePath, '*')).filter(\n (storageFolder) => !storageFolders.includes(storageFolder)\n );\n\n for (let store of basePathFolders) {\n if (validatioUtils.isPackageNameScoped(store)) {\n const scopedPackages = await getFolders(join(storagePath, store), '*');\n const listScoped = scopedPackages.map((scoped) => ({\n name: `${store}/${scoped}`,\n scoped: store,\n }));\n results.push(...listScoped);\n } else {\n results.push({\n name: store,\n });\n }\n }\n\n // iterate each storage folder\n for (const store of storageFolders) {\n const foldersOnStorage = await getFolders(join(storagePath, store), '*');\n for (let pkgName of foldersOnStorage) {\n if (validatioUtils.isPackageNameScoped(pkgName)) {\n const scopedPackages = await getFolders(join(storagePath, store, pkgName), '*');\n const listScoped = scopedPackages.map((scoped) => ({\n name: `${pkgName}/${scoped}`,\n scoped: pkgName,\n }));\n results.push(...listScoped);\n } else {\n results.push({\n name: pkgName,\n });\n }\n }\n }\n\n return results;\n}\n"],"mappings":"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"}
|
package/build/fs.js
CHANGED
|
@@ -6,13 +6,9 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.accessPromise = void 0;
|
|
7
7
|
exports.fstatPromise = fstatPromise;
|
|
8
8
|
exports.writeFilePromise = exports.unlinkPromise = exports.statPromise = exports.rmdirPromise = exports.renamePromise = exports.readdirPromise = exports.readFilePromise = exports.openPromise = exports.mkdirPromise = void 0;
|
|
9
|
-
|
|
10
9
|
var _fs = _interopRequireDefault(require("fs"));
|
|
11
|
-
|
|
12
10
|
var _promises = _interopRequireDefault(require("fs/promises"));
|
|
13
|
-
|
|
14
11
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
15
|
-
|
|
16
12
|
const readFile = _promises.default.readFile;
|
|
17
13
|
const mkdirPromise = _promises.default.mkdir;
|
|
18
14
|
exports.mkdirPromise = mkdirPromise;
|
|
@@ -32,20 +28,16 @@ const renamePromise = _promises.default.rename;
|
|
|
32
28
|
exports.renamePromise = renamePromise;
|
|
33
29
|
const openPromise = _promises.default.open;
|
|
34
30
|
exports.openPromise = openPromise;
|
|
35
|
-
|
|
36
31
|
const readFilePromise = async path => {
|
|
37
32
|
return await readFile(path, 'utf8');
|
|
38
33
|
};
|
|
39
|
-
|
|
40
34
|
exports.readFilePromise = readFilePromise;
|
|
41
|
-
|
|
42
35
|
function fstatPromise(fd) {
|
|
43
36
|
return new Promise((resolve, reject) => {
|
|
44
37
|
_fs.default.fstat(fd, function (err, stats) {
|
|
45
38
|
if (err) {
|
|
46
39
|
return reject(err);
|
|
47
40
|
}
|
|
48
|
-
|
|
49
41
|
return resolve(stats);
|
|
50
42
|
});
|
|
51
43
|
});
|
package/build/fs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fs.js","names":["readFile","fs","mkdirPromise","mkdir","accessPromise","access","writeFilePromise","writeFile","readdirPromise","readdir","statPromise","stat","unlinkPromise","unlink","rmdirPromise","rmdir","renamePromise","rename","openPromise","open","readFilePromise","path","fstatPromise","fd","Promise","resolve","reject","fsCallback","fstat","err","stats"],"sources":["../src/fs.ts"],"sourcesContent":["import fsCallback from 'fs';\nimport fs from 'fs/promises';\n\nconst readFile = fs.readFile;\nconst mkdirPromise = fs.mkdir;\nconst accessPromise = fs.access;\nconst writeFilePromise = fs.writeFile;\nconst readdirPromise = fs.readdir;\nconst statPromise = fs.stat;\nconst unlinkPromise = fs.unlink;\nconst rmdirPromise = fs.rmdir;\nconst renamePromise = fs.rename;\nconst openPromise = fs.open;\n\nconst readFilePromise = async (path) => {\n return await readFile(path, 'utf8');\n};\n\nfunction fstatPromise(fd: number): Promise<fsCallback.Stats> {\n return new Promise((resolve, reject) => {\n fsCallback.fstat(fd, function (err, stats) {\n if (err) {\n return reject(err);\n }\n return resolve(stats);\n });\n });\n}\n\nexport {\n readFilePromise,\n renamePromise,\n mkdirPromise,\n writeFilePromise,\n readdirPromise,\n statPromise,\n accessPromise,\n unlinkPromise,\n rmdirPromise,\n openPromise,\n fstatPromise,\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"fs.js","names":["readFile","fs","mkdirPromise","mkdir","accessPromise","access","writeFilePromise","writeFile","readdirPromise","readdir","statPromise","stat","unlinkPromise","unlink","rmdirPromise","rmdir","renamePromise","rename","openPromise","open","readFilePromise","path","fstatPromise","fd","Promise","resolve","reject","fsCallback","fstat","err","stats"],"sources":["../src/fs.ts"],"sourcesContent":["import fsCallback from 'fs';\nimport fs from 'fs/promises';\n\nconst readFile = fs.readFile;\nconst mkdirPromise = fs.mkdir;\nconst accessPromise = fs.access;\nconst writeFilePromise = fs.writeFile;\nconst readdirPromise = fs.readdir;\nconst statPromise = fs.stat;\nconst unlinkPromise = fs.unlink;\nconst rmdirPromise = fs.rmdir;\nconst renamePromise = fs.rename;\nconst openPromise = fs.open;\n\nconst readFilePromise = async (path) => {\n return await readFile(path, 'utf8');\n};\n\nfunction fstatPromise(fd: number): Promise<fsCallback.Stats> {\n return new Promise((resolve, reject) => {\n fsCallback.fstat(fd, function (err, stats) {\n if (err) {\n return reject(err);\n }\n return resolve(stats);\n });\n });\n}\n\nexport {\n readFilePromise,\n renamePromise,\n mkdirPromise,\n writeFilePromise,\n readdirPromise,\n statPromise,\n accessPromise,\n unlinkPromise,\n rmdirPromise,\n openPromise,\n fstatPromise,\n};\n"],"mappings":";;;;;;;;AAAA;AACA;AAA6B;AAE7B,MAAMA,QAAQ,GAAGC,iBAAE,CAACD,QAAQ;AAC5B,MAAME,YAAY,GAAGD,iBAAE,CAACE,KAAK;AAAC;AAC9B,MAAMC,aAAa,GAAGH,iBAAE,CAACI,MAAM;AAAC;AAChC,MAAMC,gBAAgB,GAAGL,iBAAE,CAACM,SAAS;AAAC;AACtC,MAAMC,cAAc,GAAGP,iBAAE,CAACQ,OAAO;AAAC;AAClC,MAAMC,WAAW,GAAGT,iBAAE,CAACU,IAAI;AAAC;AAC5B,MAAMC,aAAa,GAAGX,iBAAE,CAACY,MAAM;AAAC;AAChC,MAAMC,YAAY,GAAGb,iBAAE,CAACc,KAAK;AAAC;AAC9B,MAAMC,aAAa,GAAGf,iBAAE,CAACgB,MAAM;AAAC;AAChC,MAAMC,WAAW,GAAGjB,iBAAE,CAACkB,IAAI;AAAC;AAE5B,MAAMC,eAAe,GAAG,MAAOC,IAAI,IAAK;EACtC,OAAO,MAAMrB,QAAQ,CAACqB,IAAI,EAAE,MAAM,CAAC;AACrC,CAAC;AAAC;AAEF,SAASC,YAAY,CAACC,EAAU,EAA6B;EAC3D,OAAO,IAAIC,OAAO,CAAC,CAACC,OAAO,EAAEC,MAAM,KAAK;IACtCC,WAAU,CAACC,KAAK,CAACL,EAAE,EAAE,UAAUM,GAAG,EAAEC,KAAK,EAAE;MACzC,IAAID,GAAG,EAAE;QACP,OAAOH,MAAM,CAACG,GAAG,CAAC;MACpB;MACA,OAAOJ,OAAO,CAACK,KAAK,CAAC;IACvB,CAAC,CAAC;EACJ,CAAC,CAAC;AACJ"}
|
package/build/index.js
CHANGED
|
@@ -10,11 +10,8 @@ Object.defineProperty(exports, "LocalDatabase", {
|
|
|
10
10
|
}
|
|
11
11
|
});
|
|
12
12
|
exports.default = void 0;
|
|
13
|
-
|
|
14
13
|
var _localDatabase = _interopRequireDefault(require("./local-database"));
|
|
15
|
-
|
|
16
14
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
17
|
-
|
|
18
15
|
var _default = _localDatabase.default;
|
|
19
16
|
exports.default = _default;
|
|
20
17
|
//# sourceMappingURL=index.js.map
|
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["LocalDatabase"],"sources":["../src/index.ts"],"sourcesContent":["import LocalDatabase from './local-database';\n\nexport { LocalDatabase };\n\nexport default LocalDatabase;\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","names":["LocalDatabase"],"sources":["../src/index.ts"],"sourcesContent":["import LocalDatabase from './local-database';\n\nexport { LocalDatabase };\n\nexport default LocalDatabase;\n"],"mappings":";;;;;;;;;;;;AAAA;AAA6C;AAAA,eAI9BA,sBAAa;AAAA"}
|
|
@@ -3,7 +3,7 @@ import { pluginUtils, searchUtils } from '@verdaccio/core';
|
|
|
3
3
|
import { Config, Logger, Token, TokenFilter } from '@verdaccio/types';
|
|
4
4
|
import { LocalStorage } from './pkg-utils';
|
|
5
5
|
export declare const ERROR_DB_LOCKED = "Database is locked, please check error message printed during startup to prevent data loss";
|
|
6
|
-
|
|
6
|
+
type Storage = pluginUtils.Storage<{}>;
|
|
7
7
|
declare class LocalDatabase extends pluginUtils.Plugin<{}> implements Storage {
|
|
8
8
|
private readonly path;
|
|
9
9
|
private readonly logger;
|
package/build/local-database.js
CHANGED
|
@@ -4,46 +4,29 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = exports.ERROR_DB_LOCKED = void 0;
|
|
7
|
-
|
|
8
7
|
var _debug = _interopRequireDefault(require("debug"));
|
|
9
|
-
|
|
10
8
|
var _lodash = _interopRequireDefault(require("lodash"));
|
|
11
|
-
|
|
12
9
|
var _lowdb = _interopRequireDefault(require("lowdb"));
|
|
13
|
-
|
|
14
10
|
var _FileAsync = _interopRequireDefault(require("lowdb/adapters/FileAsync"));
|
|
15
|
-
|
|
16
11
|
var _Memory = _interopRequireDefault(require("lowdb/adapters/Memory"));
|
|
17
|
-
|
|
18
12
|
var _path = _interopRequireDefault(require("path"));
|
|
19
|
-
|
|
20
13
|
var _core = require("@verdaccio/core");
|
|
21
|
-
|
|
22
14
|
var _utils = require("@verdaccio/utils");
|
|
23
|
-
|
|
24
15
|
var _dirUtils = require("./dir-utils");
|
|
25
|
-
|
|
26
16
|
var _fs = require("./fs");
|
|
27
|
-
|
|
28
17
|
var _localFs = _interopRequireWildcard(require("./local-fs"));
|
|
29
|
-
|
|
30
18
|
var _pkgUtils = require("./pkg-utils");
|
|
31
|
-
|
|
32
19
|
var _utils2 = require("./utils");
|
|
33
|
-
|
|
34
20
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
35
|
-
|
|
36
21
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
37
|
-
|
|
38
22
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
39
|
-
|
|
40
23
|
// import LRU from 'lru-cache';
|
|
24
|
+
|
|
41
25
|
const TOKEN_DB_NAME = '.token-db.json';
|
|
42
26
|
const DB_NAME = process.env.VERDACCIO_STORAGE_NAME ?? _core.fileUtils.Files.DatabaseName;
|
|
43
27
|
const debug = (0, _debug.default)('verdaccio:plugin:local-storage');
|
|
44
28
|
const ERROR_DB_LOCKED = 'Database is locked, please check error message printed during startup to prevent data loss';
|
|
45
29
|
exports.ERROR_DB_LOCKED = ERROR_DB_LOCKED;
|
|
46
|
-
|
|
47
30
|
class LocalDatabase extends _core.pluginUtils.Plugin {
|
|
48
31
|
constructor(config, logger) {
|
|
49
32
|
// TODO: fix double config
|
|
@@ -64,37 +47,30 @@ class LocalDatabase extends _core.pluginUtils.Plugin {
|
|
|
64
47
|
}, 'local storage path @{path}');
|
|
65
48
|
debug('plugin storage path %o', this.path);
|
|
66
49
|
}
|
|
67
|
-
|
|
68
50
|
async init() {
|
|
69
51
|
debug('plugin init');
|
|
70
52
|
this.data = await this.fetchLocalPackages();
|
|
71
53
|
debug('local packages loaded');
|
|
72
54
|
await this._sync();
|
|
73
55
|
}
|
|
74
|
-
|
|
75
56
|
async getSecret() {
|
|
76
57
|
if (typeof this.data === 'undefined') {
|
|
77
58
|
throw Error('no data secret available');
|
|
78
59
|
}
|
|
79
|
-
|
|
80
60
|
return Promise.resolve(this.data.secret);
|
|
81
61
|
}
|
|
82
|
-
|
|
83
62
|
async setSecret(secret) {
|
|
84
63
|
if (typeof this.data === 'undefined') {
|
|
85
64
|
throw Error('no data secret available');
|
|
86
65
|
} else {
|
|
87
66
|
this.data.secret = secret;
|
|
88
67
|
}
|
|
89
|
-
|
|
90
68
|
await this._sync();
|
|
91
69
|
}
|
|
92
|
-
|
|
93
70
|
async add(name) {
|
|
94
71
|
if (typeof this.data === 'undefined') {
|
|
95
72
|
throw Error('no data secret available');
|
|
96
73
|
}
|
|
97
|
-
|
|
98
74
|
if (this.data.list.indexOf(name) === -1) {
|
|
99
75
|
this.data.list.push(name);
|
|
100
76
|
debug('the private package %s has been added', name);
|
|
@@ -104,45 +80,39 @@ class LocalDatabase extends _core.pluginUtils.Plugin {
|
|
|
104
80
|
return Promise.resolve();
|
|
105
81
|
}
|
|
106
82
|
}
|
|
83
|
+
|
|
107
84
|
/**
|
|
108
85
|
* The field storage could be absolute or relative.
|
|
109
86
|
* If relative, it will be resolved against the config path.
|
|
110
87
|
* If absolute, it will be returned as is.
|
|
111
88
|
**/
|
|
112
|
-
|
|
113
|
-
|
|
114
89
|
getStoragePath() {
|
|
115
90
|
const {
|
|
116
91
|
storage
|
|
117
92
|
} = this.config;
|
|
118
|
-
|
|
119
93
|
if (typeof storage !== 'string') {
|
|
120
94
|
throw new TypeError('storage field is mandatory');
|
|
121
95
|
}
|
|
122
|
-
|
|
123
96
|
const storagePath = _path.default.isAbsolute(storage) ? storage : _path.default.normalize(_path.default.join(this.getBaseConfigPath(), storage));
|
|
124
97
|
debug('storage path %o', storagePath);
|
|
125
98
|
return storagePath;
|
|
126
99
|
}
|
|
127
|
-
|
|
128
100
|
getBaseConfigPath() {
|
|
129
101
|
return _path.default.dirname(this.config.configPath);
|
|
130
102
|
}
|
|
103
|
+
|
|
131
104
|
/**
|
|
132
105
|
* Filter and only match those values that the query define.
|
|
133
106
|
**/
|
|
134
|
-
|
|
135
|
-
|
|
136
107
|
async filterByQuery(results, query) {
|
|
137
108
|
// FUTURE: apply new filters, keyword, version, ...
|
|
138
109
|
return results.filter(item => {
|
|
139
110
|
var _item$name;
|
|
140
|
-
|
|
141
111
|
return (item === null || item === void 0 ? void 0 : (_item$name = item.name) === null || _item$name === void 0 ? void 0 : _item$name.match(query.text)) !== null;
|
|
142
112
|
});
|
|
143
|
-
}
|
|
144
|
-
|
|
113
|
+
}
|
|
145
114
|
|
|
115
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
146
116
|
async getScore(_pkg) {
|
|
147
117
|
// TODO: there is no particular reason to predefined scores
|
|
148
118
|
// could be improved by using
|
|
@@ -155,13 +125,11 @@ class LocalDatabase extends _core.pluginUtils.Plugin {
|
|
|
155
125
|
}
|
|
156
126
|
});
|
|
157
127
|
}
|
|
158
|
-
|
|
159
128
|
async search(query) {
|
|
160
129
|
const results = [];
|
|
161
130
|
const storagePath = this.getStoragePath();
|
|
162
131
|
const packagesOnStorage = await this.filterByQuery(await (0, _dirUtils.searchOnStorage)(storagePath, this.storages), query);
|
|
163
132
|
debug('packages found %o', packagesOnStorage.length);
|
|
164
|
-
|
|
165
133
|
for (let storage of packagesOnStorage) {
|
|
166
134
|
// check if package is listed on the cache private database
|
|
167
135
|
const isPrivate = this.data.list.includes(storage.name);
|
|
@@ -173,24 +141,19 @@ class LocalDatabase extends _core.pluginUtils.Plugin {
|
|
|
173
141
|
score
|
|
174
142
|
});
|
|
175
143
|
}
|
|
176
|
-
|
|
177
144
|
return results;
|
|
178
145
|
}
|
|
179
|
-
|
|
180
146
|
async remove(name) {
|
|
181
147
|
try {
|
|
182
148
|
if (typeof this.data === 'undefined') {
|
|
183
149
|
throw Error('no data secret available');
|
|
184
150
|
}
|
|
185
|
-
|
|
186
151
|
const data = await this.get();
|
|
187
152
|
const pkgName = data.indexOf(name);
|
|
188
|
-
|
|
189
153
|
if (pkgName !== -1) {
|
|
190
154
|
this.data.list.splice(pkgName, 1);
|
|
191
155
|
debug('remove package %o has been removed', name);
|
|
192
156
|
}
|
|
193
|
-
|
|
194
157
|
await this._sync();
|
|
195
158
|
} catch (err) {
|
|
196
159
|
this.logger.error({
|
|
@@ -199,12 +162,10 @@ class LocalDatabase extends _core.pluginUtils.Plugin {
|
|
|
199
162
|
throw _core.errorUtils.getInternalError('error remove private package');
|
|
200
163
|
}
|
|
201
164
|
}
|
|
202
|
-
|
|
203
165
|
async get() {
|
|
204
166
|
if (typeof this.data === 'undefined') {
|
|
205
167
|
throw Error('no data secret available');
|
|
206
168
|
}
|
|
207
|
-
|
|
208
169
|
const {
|
|
209
170
|
list
|
|
210
171
|
} = this.data;
|
|
@@ -212,66 +173,51 @@ class LocalDatabase extends _core.pluginUtils.Plugin {
|
|
|
212
173
|
debug('get full list of packages (%o) has been fetched', totalItems);
|
|
213
174
|
return Promise.resolve(list);
|
|
214
175
|
}
|
|
215
|
-
|
|
216
176
|
getPackageStorage(packageName) {
|
|
217
177
|
const packageAccess = (0, _utils.getMatchedPackagesSpec)(packageName, this.config.packages);
|
|
218
|
-
|
|
219
178
|
const packagePath = this._getLocalStoragePath(packageAccess ? packageAccess.storage : undefined);
|
|
220
|
-
|
|
221
179
|
debug('storage path selected: ', packagePath);
|
|
222
|
-
|
|
223
180
|
if (_lodash.default.isString(packagePath) === false) {
|
|
224
181
|
debug('the package %o has no storage defined ', packageName);
|
|
225
182
|
throw _core.errorUtils.getInternalError('storage not found or implemented');
|
|
226
183
|
}
|
|
227
|
-
|
|
228
|
-
|
|
184
|
+
const packageStoragePath = _path.default.join(
|
|
185
|
+
// FIXME: use getBaseStoragePath instead
|
|
229
186
|
_path.default.resolve(_path.default.dirname(this.config.config_path || ''), packagePath), packageName);
|
|
230
|
-
|
|
231
187
|
debug('storage absolute path: ', packageStoragePath);
|
|
232
188
|
return new _localFs.default(packageStoragePath, this.logger);
|
|
233
189
|
}
|
|
234
|
-
|
|
235
190
|
async clean() {
|
|
236
191
|
await this._sync();
|
|
237
192
|
}
|
|
238
|
-
|
|
239
193
|
_getCustomPackageLocalStorages() {
|
|
240
194
|
const storages = new Map();
|
|
241
195
|
const {
|
|
242
196
|
packages
|
|
243
197
|
} = this.config;
|
|
244
|
-
|
|
245
198
|
if (packages) {
|
|
246
199
|
Object.keys(packages || {}).map(pkg => {
|
|
247
200
|
const {
|
|
248
201
|
storage
|
|
249
202
|
} = packages[pkg];
|
|
250
|
-
|
|
251
203
|
if (typeof storage === 'string') {
|
|
252
204
|
const storagePath = _path.default.join(this.getStoragePath(), storage);
|
|
253
|
-
|
|
254
205
|
debug('add custom storage for %s on %s', storage, storagePath);
|
|
255
206
|
storages.set(storage, storagePath);
|
|
256
207
|
}
|
|
257
208
|
});
|
|
258
209
|
}
|
|
259
|
-
|
|
260
210
|
return storages;
|
|
261
211
|
}
|
|
262
|
-
|
|
263
212
|
async _sync() {
|
|
264
213
|
debug('sync database started');
|
|
265
|
-
|
|
266
214
|
if (this.locked) {
|
|
267
215
|
this.logger.error(ERROR_DB_LOCKED);
|
|
268
216
|
throw new Error(ERROR_DB_LOCKED);
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
|
|
217
|
+
}
|
|
218
|
+
// Uses sync to prevent ugly race condition
|
|
272
219
|
try {
|
|
273
220
|
const folderName = _path.default.dirname(this.path);
|
|
274
|
-
|
|
275
221
|
debug('creating folder %o', folderName);
|
|
276
222
|
await (0, _fs.mkdirPromise)(folderName, {
|
|
277
223
|
recursive: true
|
|
@@ -283,7 +229,6 @@ class LocalDatabase extends _core.pluginUtils.Plugin {
|
|
|
283
229
|
}, 'sync create folder has failed with error: @{err}');
|
|
284
230
|
throw err;
|
|
285
231
|
}
|
|
286
|
-
|
|
287
232
|
try {
|
|
288
233
|
await (0, _fs.writeFilePromise)(this.path, JSON.stringify(this.data));
|
|
289
234
|
debug('sync write succeeded');
|
|
@@ -295,10 +240,8 @@ class LocalDatabase extends _core.pluginUtils.Plugin {
|
|
|
295
240
|
throw err;
|
|
296
241
|
}
|
|
297
242
|
}
|
|
298
|
-
|
|
299
243
|
_getLocalStoragePath(storage) {
|
|
300
244
|
const globalConfigStorage = this.getStoragePath();
|
|
301
|
-
|
|
302
245
|
if (_lodash.default.isNil(globalConfigStorage)) {
|
|
303
246
|
this.logger.error('property storage in config.yaml is required for using this plugin');
|
|
304
247
|
throw new Error('property storage in config.yaml is required for using this plugin');
|
|
@@ -306,11 +249,9 @@ class LocalDatabase extends _core.pluginUtils.Plugin {
|
|
|
306
249
|
if (typeof storage === 'string') {
|
|
307
250
|
return _path.default.join(globalConfigStorage, storage);
|
|
308
251
|
}
|
|
309
|
-
|
|
310
252
|
return globalConfigStorage;
|
|
311
253
|
}
|
|
312
254
|
}
|
|
313
|
-
|
|
314
255
|
async fetchLocalPackages() {
|
|
315
256
|
try {
|
|
316
257
|
return await (0, _pkgUtils.loadPrivatePackages)(this.path, this.logger);
|
|
@@ -320,25 +261,21 @@ class LocalDatabase extends _core.pluginUtils.Plugin {
|
|
|
320
261
|
this.logger.warn({
|
|
321
262
|
path: this.path
|
|
322
263
|
}, 'no private database found, recreating new one on @{path}');
|
|
323
|
-
|
|
324
264
|
if (err.code !== _localFs.noSuchFile) {
|
|
325
265
|
this.locked = true;
|
|
326
266
|
this.logger.error('Failed to read package database file, please check the error printed below:\n', `File Path: ${this.path}\n\n ${err.message}`);
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
|
|
267
|
+
}
|
|
268
|
+
// if no database is found we set empty placeholders
|
|
330
269
|
return {
|
|
331
270
|
list: [],
|
|
332
271
|
secret: ''
|
|
333
272
|
};
|
|
334
273
|
}
|
|
335
274
|
}
|
|
336
|
-
|
|
337
275
|
async getTokenDb() {
|
|
338
276
|
if (!this.tokenDb) {
|
|
339
277
|
debug('token database is not defined');
|
|
340
278
|
let adapter;
|
|
341
|
-
|
|
342
279
|
if (process.env.NODE_ENV === 'test') {
|
|
343
280
|
debug('token memory adapter');
|
|
344
281
|
adapter = new _Memory.default('');
|
|
@@ -347,20 +284,16 @@ class LocalDatabase extends _core.pluginUtils.Plugin {
|
|
|
347
284
|
const pathDb = (0, _utils2._dbGenPath)(TOKEN_DB_NAME, this.config);
|
|
348
285
|
adapter = new _FileAsync.default(pathDb);
|
|
349
286
|
}
|
|
350
|
-
|
|
351
287
|
debug('token bd generated');
|
|
352
288
|
this.tokenDb = await (0, _lowdb.default)(adapter);
|
|
353
289
|
}
|
|
354
|
-
|
|
355
290
|
return this.tokenDb;
|
|
356
291
|
}
|
|
357
|
-
|
|
358
292
|
async saveToken(token) {
|
|
359
293
|
debug('token key %o', token.key);
|
|
360
294
|
const db = await this.getTokenDb();
|
|
361
295
|
const userData = await db.get(token.user).value();
|
|
362
296
|
debug('user data %o', userData);
|
|
363
|
-
|
|
364
297
|
if (_lodash.default.isNil(userData)) {
|
|
365
298
|
await db.set(token.user, [token]).write();
|
|
366
299
|
debug('token user %o new database', token.user);
|
|
@@ -369,19 +302,15 @@ class LocalDatabase extends _core.pluginUtils.Plugin {
|
|
|
369
302
|
// @ts-ignore
|
|
370
303
|
await db.get(token.user).push(token).write();
|
|
371
304
|
}
|
|
372
|
-
|
|
373
305
|
debug('data %o', await db.getState());
|
|
374
306
|
debug('token saved %o', token.user);
|
|
375
307
|
}
|
|
376
|
-
|
|
377
308
|
async deleteToken(user, tokenKey) {
|
|
378
309
|
const db = await this.getTokenDb();
|
|
379
310
|
const userTokens = await db.get(user).value();
|
|
380
|
-
|
|
381
311
|
if (_lodash.default.isNil(userTokens)) {
|
|
382
312
|
throw new Error('user not found');
|
|
383
313
|
}
|
|
384
|
-
|
|
385
314
|
debug('tokens %o - %o', userTokens, userTokens.length);
|
|
386
315
|
const remainingTokens = userTokens.filter(({
|
|
387
316
|
key
|
|
@@ -392,7 +321,6 @@ class LocalDatabase extends _core.pluginUtils.Plugin {
|
|
|
392
321
|
await db.set(user, remainingTokens).write();
|
|
393
322
|
debug('removed tokens key %o', tokenKey);
|
|
394
323
|
}
|
|
395
|
-
|
|
396
324
|
async readTokens(filter) {
|
|
397
325
|
const {
|
|
398
326
|
user
|
|
@@ -402,9 +330,7 @@ class LocalDatabase extends _core.pluginUtils.Plugin {
|
|
|
402
330
|
const tokens = await db.get(user).value();
|
|
403
331
|
return tokens || [];
|
|
404
332
|
}
|
|
405
|
-
|
|
406
333
|
}
|
|
407
|
-
|
|
408
334
|
var _default = LocalDatabase;
|
|
409
335
|
exports.default = _default;
|
|
410
336
|
//# sourceMappingURL=local-database.js.map
|