verdaccio-memory 13.0.0-next-8.21 → 13.0.0-next-8.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/local-memory.d.ts +8 -5
- package/build/local-memory.js +75 -23
- package/build/local-memory.js.map +1 -1
- package/build/memory-handler.d.ts +17 -14
- package/build/memory-handler.js +212 -101
- package/build/memory-handler.js.map +1 -1
- package/build/utils.d.ts +3 -3
- package/build/utils.js +4 -4
- package/build/utils.js.map +1 -1
- package/package.json +6 -6
package/build/local-memory.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { pluginUtils, searchUtils } from '@verdaccio/core';
|
|
2
|
-
import { Logger, Token } from '@verdaccio/types';
|
|
2
|
+
import { Logger, Token, TokenFilter } from '@verdaccio/types';
|
|
3
3
|
import MemoryHandler, { DataHandler } from './memory-handler';
|
|
4
4
|
export type ConfigMemory = {
|
|
5
5
|
limit?: number;
|
|
@@ -8,6 +8,9 @@ export interface MemoryLocalStorage {
|
|
|
8
8
|
secret: string;
|
|
9
9
|
list: string[];
|
|
10
10
|
files: DataHandler;
|
|
11
|
+
tokens: {
|
|
12
|
+
[user: string]: Token[];
|
|
13
|
+
};
|
|
11
14
|
}
|
|
12
15
|
declare class LocalMemory extends pluginUtils.Plugin<ConfigMemory> implements pluginUtils.Storage<ConfigMemory> {
|
|
13
16
|
private path;
|
|
@@ -21,14 +24,14 @@ declare class LocalMemory extends pluginUtils.Plugin<ConfigMemory> implements pl
|
|
|
21
24
|
setSecret(secret: string): Promise<string | null>;
|
|
22
25
|
add(name: string): Promise<void>;
|
|
23
26
|
search(query: searchUtils.SearchQuery): Promise<searchUtils.SearchItem[]>;
|
|
27
|
+
private filterByQuery;
|
|
28
|
+
private getScore;
|
|
24
29
|
remove(name: string): Promise<void>;
|
|
25
30
|
get(): Promise<any>;
|
|
26
31
|
getPackageStorage(packageInfo: string): MemoryHandler;
|
|
27
|
-
hasTarball(): Promise<boolean>;
|
|
28
|
-
hasPackage(): Promise<boolean>;
|
|
29
32
|
private _createEmtpyDatabase;
|
|
30
|
-
saveToken(): Promise<void>;
|
|
33
|
+
saveToken(token: Token): Promise<void>;
|
|
31
34
|
deleteToken(user: string, tokenKey: string): Promise<void>;
|
|
32
|
-
readTokens(): Promise<Token[]>;
|
|
35
|
+
readTokens(filter: TokenFilter): Promise<Token[]>;
|
|
33
36
|
}
|
|
34
37
|
export default LocalMemory;
|
package/build/local-memory.js
CHANGED
|
@@ -11,8 +11,6 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
|
|
|
11
11
|
const debug = (0, _debug.default)('verdaccio:plugin:storage:local-memory');
|
|
12
12
|
const DEFAULT_LIMIT = 1000;
|
|
13
13
|
class LocalMemory extends _core.pluginUtils.Plugin {
|
|
14
|
-
// @ts-ignore
|
|
15
|
-
|
|
16
14
|
constructor(config, options) {
|
|
17
15
|
super(config, options);
|
|
18
16
|
this.config = config;
|
|
@@ -52,11 +50,41 @@ class LocalMemory extends _core.pluginUtils.Plugin {
|
|
|
52
50
|
}
|
|
53
51
|
});
|
|
54
52
|
}
|
|
53
|
+
async search(query) {
|
|
54
|
+
const results = [];
|
|
55
|
+
const packagesOnStorage = this.filterByQuery(this.data.list, query);
|
|
56
|
+
debug('memory search: packages found %o', packagesOnStorage.length);
|
|
57
|
+
for (const name of packagesOnStorage) {
|
|
58
|
+
const pkg = {
|
|
59
|
+
name
|
|
60
|
+
};
|
|
61
|
+
const isPrivate = this.data.list.includes(name);
|
|
62
|
+
const score = this.getScore(pkg);
|
|
63
|
+
results.push({
|
|
64
|
+
package: pkg,
|
|
65
|
+
verdaccioPrivate: isPrivate,
|
|
66
|
+
verdaccioPkgCached: !isPrivate,
|
|
67
|
+
score
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
return results;
|
|
71
|
+
}
|
|
72
|
+
filterByQuery(list, query) {
|
|
73
|
+
const safeText = query.text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
74
|
+
const regex = new RegExp(safeText, 'i');
|
|
75
|
+
return list.filter(name => regex.test(name));
|
|
76
|
+
}
|
|
55
77
|
|
|
56
78
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
79
|
+
getScore(_pkg) {
|
|
80
|
+
return {
|
|
81
|
+
final: 1,
|
|
82
|
+
detail: {
|
|
83
|
+
maintenance: 0,
|
|
84
|
+
popularity: 1,
|
|
85
|
+
quality: 1
|
|
86
|
+
}
|
|
87
|
+
};
|
|
60
88
|
}
|
|
61
89
|
async remove(name) {
|
|
62
90
|
return new Promise(resolve => {
|
|
@@ -75,39 +103,63 @@ class LocalMemory extends _core.pluginUtils.Plugin {
|
|
|
75
103
|
return Promise.resolve(this.data?.list);
|
|
76
104
|
}
|
|
77
105
|
getPackageStorage(packageInfo) {
|
|
106
|
+
// Ensure the package is in the list
|
|
107
|
+
if (!this.data.list.includes(packageInfo)) {
|
|
108
|
+
this.data.list.push(packageInfo);
|
|
109
|
+
}
|
|
78
110
|
return new _memoryHandler.default(packageInfo, this.data.files, this.logger);
|
|
79
111
|
}
|
|
80
|
-
async hasTarball(/* fileName: string */
|
|
81
|
-
) {
|
|
82
|
-
throw new Error('not implemented');
|
|
83
|
-
}
|
|
84
|
-
async hasPackage() {
|
|
85
|
-
return false;
|
|
86
|
-
}
|
|
87
112
|
_createEmtpyDatabase() {
|
|
88
113
|
const list = [];
|
|
89
114
|
const files = {};
|
|
115
|
+
const tokens = {};
|
|
90
116
|
const emptyDatabase = {
|
|
91
117
|
list,
|
|
92
118
|
files,
|
|
119
|
+
tokens,
|
|
93
120
|
secret: ''
|
|
94
121
|
};
|
|
95
122
|
return emptyDatabase;
|
|
96
123
|
}
|
|
97
|
-
saveToken() {
|
|
98
|
-
|
|
99
|
-
|
|
124
|
+
saveToken(token) {
|
|
125
|
+
return new Promise(resolve => {
|
|
126
|
+
const {
|
|
127
|
+
tokens
|
|
128
|
+
} = this.data;
|
|
129
|
+
if (!tokens[token.user]) {
|
|
130
|
+
tokens[token.user] = [token];
|
|
131
|
+
} else {
|
|
132
|
+
tokens[token.user].push(token);
|
|
133
|
+
}
|
|
134
|
+
debug('token saved for user %o', token.user);
|
|
135
|
+
resolve();
|
|
136
|
+
});
|
|
100
137
|
}
|
|
101
138
|
deleteToken(user, tokenKey) {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
139
|
+
return new Promise((resolve, reject) => {
|
|
140
|
+
const {
|
|
141
|
+
tokens
|
|
142
|
+
} = this.data;
|
|
143
|
+
const userTokens = tokens[user];
|
|
144
|
+
if (!userTokens) {
|
|
145
|
+
reject(new Error('user not found'));
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
const remainingTokens = userTokens.filter(token => token.key !== tokenKey);
|
|
149
|
+
tokens[user] = remainingTokens;
|
|
150
|
+
debug('removed token key %o for user %o', tokenKey, user);
|
|
151
|
+
resolve();
|
|
152
|
+
});
|
|
107
153
|
}
|
|
108
|
-
readTokens() {
|
|
109
|
-
|
|
110
|
-
|
|
154
|
+
readTokens(filter) {
|
|
155
|
+
return new Promise(resolve => {
|
|
156
|
+
const {
|
|
157
|
+
tokens
|
|
158
|
+
} = this.data;
|
|
159
|
+
const userTokens = tokens[filter.user] || [];
|
|
160
|
+
debug('read tokens for user %o: %o tokens', filter.user, userTokens.length);
|
|
161
|
+
resolve(userTokens);
|
|
162
|
+
});
|
|
111
163
|
}
|
|
112
164
|
}
|
|
113
165
|
var _default = exports.default = LocalMemory;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-memory.js","names":["_debug","_interopRequireDefault","require","_core","_memoryHandler","e","__esModule","default","debug","buildDebug","DEFAULT_LIMIT","LocalMemory","pluginUtils","Plugin","constructor","config","options","limit","logger","data","_createEmtpyDatabase","path","init","Promise","resolve","getSecret","secret","setSecret","add","name","reject","list","length","indexOf","push","info","Error","search","query","warn","remove","item","splice","get","getPackageStorage","packageInfo","MemoryHandler","files","hasTarball","hasPackage","emptyDatabase","saveToken","errorUtils","getServiceUnavailable","deleteToken","user","tokenKey","readTokens","_default","exports"],"sources":["../src/local-memory.ts"],"sourcesContent":["import buildDebug from 'debug';\n\nimport { errorUtils, pluginUtils, searchUtils } from '@verdaccio/core';\nimport { Logger, Token } from '@verdaccio/types';\n\nimport MemoryHandler, { DataHandler } from './memory-handler';\n\nexport type ConfigMemory = { limit?: number };\nexport interface MemoryLocalStorage {\n secret: string;\n list: string[];\n files: DataHandler;\n}\n\nconst debug = buildDebug('verdaccio:plugin:storage:local-memory');\n\nconst DEFAULT_LIMIT = 1000;\n\nclass LocalMemory\n extends pluginUtils.Plugin<ConfigMemory>\n implements pluginUtils.Storage<ConfigMemory>\n{\n private path: string;\n private limit: number;\n public logger: Logger;\n private data: MemoryLocalStorage;\n // @ts-ignore\n public config: ConfigMemory;\n\n public constructor(config: ConfigMemory, options: pluginUtils.PluginOptions) {\n super(config, options);\n this.config = config;\n this.limit = config.limit || DEFAULT_LIMIT;\n this.logger = options.logger;\n this.data = this._createEmtpyDatabase();\n this.path = '/';\n debug('start plugin');\n }\n\n public init() {\n return Promise.resolve();\n }\n\n public getSecret(): Promise<string> {\n return Promise.resolve(this.data.secret);\n }\n\n public setSecret(secret: string): Promise<string | null> {\n return new Promise((resolve): void => {\n this.data.secret = secret;\n resolve(null);\n });\n }\n\n async add(name: string): Promise<void> {\n return new Promise((resolve, reject): void => {\n const { list } = this.data;\n\n if (list.length < this.limit) {\n if (list.indexOf(name) === -1) {\n list.push(name);\n }\n resolve();\n } else {\n this.logger.info(\n { limit: this.limit },\n 'Storage memory has reached limit of @{limit} packages'\n );\n reject(new Error(`Storage memory has reached limit of ${this.limit} packages`));\n }\n });\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n public async search(query: searchUtils.SearchQuery): Promise<searchUtils.SearchItem[]> {\n this.logger.warn('[verdaccio/memory]: search method not implemented, PR is welcome');\n return Promise.reject('not implemented');\n }\n\n async remove(name: string): Promise<void> {\n return new Promise((resolve): void => {\n const { list } = this.data;\n const item = list.indexOf(name);\n\n if (item !== -1) {\n list.splice(item, 1);\n }\n\n return resolve();\n });\n }\n\n async get(): Promise<any> {\n debug('data list length %o', this.data?.list?.length);\n return Promise.resolve(this.data?.list);\n }\n\n public getPackageStorage(packageInfo: string): MemoryHandler {\n return new MemoryHandler(packageInfo, this.data.files, this.logger);\n }\n\n public async hasTarball(/* fileName: string */): Promise<boolean> {\n throw new Error('not implemented');\n }\n\n public async hasPackage(): Promise<boolean> {\n return false;\n }\n\n private _createEmtpyDatabase(): MemoryLocalStorage {\n const list: string[] = [];\n const files = {};\n const emptyDatabase = {\n list,\n files,\n secret: '',\n };\n\n return emptyDatabase;\n }\n\n public saveToken(): Promise<void> {\n this.logger.warn('[verdaccio/memory][saveToken] save token has not been implemented yet');\n\n return Promise.reject(errorUtils.getServiceUnavailable('method not implemented'));\n }\n\n public deleteToken(user: string, tokenKey: string): Promise<void> {\n this.logger.warn(\n { tokenKey, user },\n '[verdaccio/memory][deleteToken] delete token has not been implemented yet @{user}'\n );\n\n return Promise.reject(errorUtils.getServiceUnavailable('method not implemented'));\n }\n\n public readTokens(): Promise<Token[]> {\n this.logger.warn('[verdaccio/memory][readTokens] read tokens has not been implemented yet ');\n\n return Promise.reject(errorUtils.getServiceUnavailable('method not implemented'));\n }\n}\n\nexport default LocalMemory;\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"local-memory.js","names":["_debug","_interopRequireDefault","require","_core","_memoryHandler","e","__esModule","default","debug","buildDebug","DEFAULT_LIMIT","LocalMemory","pluginUtils","Plugin","constructor","config","options","limit","logger","data","_createEmtpyDatabase","path","init","Promise","resolve","getSecret","secret","setSecret","add","name","reject","list","length","indexOf","push","info","Error","search","query","results","packagesOnStorage","filterByQuery","pkg","isPrivate","includes","score","getScore","package","verdaccioPrivate","verdaccioPkgCached","safeText","text","replace","regex","RegExp","filter","test","_pkg","final","detail","maintenance","popularity","quality","remove","item","splice","get","getPackageStorage","packageInfo","MemoryHandler","files","tokens","emptyDatabase","saveToken","token","user","deleteToken","tokenKey","userTokens","remainingTokens","key","readTokens","_default","exports"],"sources":["../src/local-memory.ts"],"sourcesContent":["import buildDebug from 'debug';\n\nimport { pluginUtils, searchUtils } from '@verdaccio/core';\nimport { Logger, Token, TokenFilter } from '@verdaccio/types';\n\nimport MemoryHandler, { DataHandler } from './memory-handler';\n\nexport type ConfigMemory = { limit?: number };\nexport interface MemoryLocalStorage {\n secret: string;\n list: string[];\n files: DataHandler;\n tokens: { [user: string]: Token[] };\n}\n\nconst debug = buildDebug('verdaccio:plugin:storage:local-memory');\n\nconst DEFAULT_LIMIT = 1000;\n\nclass LocalMemory\n extends pluginUtils.Plugin<ConfigMemory>\n implements pluginUtils.Storage<ConfigMemory>\n{\n private path: string;\n private limit: number;\n public logger: Logger;\n private data: MemoryLocalStorage;\n public config: ConfigMemory;\n\n public constructor(config: ConfigMemory, options: pluginUtils.PluginOptions) {\n super(config, options);\n this.config = config;\n this.limit = config.limit || DEFAULT_LIMIT;\n this.logger = options.logger;\n this.data = this._createEmtpyDatabase();\n this.path = '/';\n debug('start plugin');\n }\n\n public init() {\n return Promise.resolve();\n }\n\n public getSecret(): Promise<string> {\n return Promise.resolve(this.data.secret);\n }\n\n public setSecret(secret: string): Promise<string | null> {\n return new Promise((resolve): void => {\n this.data.secret = secret;\n resolve(null);\n });\n }\n\n async add(name: string): Promise<void> {\n return new Promise((resolve, reject): void => {\n const { list } = this.data;\n\n if (list.length < this.limit) {\n if (list.indexOf(name) === -1) {\n list.push(name);\n }\n resolve();\n } else {\n this.logger.info(\n { limit: this.limit },\n 'Storage memory has reached limit of @{limit} packages'\n );\n reject(new Error(`Storage memory has reached limit of ${this.limit} packages`));\n }\n });\n }\n\n public async search(query: searchUtils.SearchQuery): Promise<searchUtils.SearchItem[]> {\n const results: searchUtils.SearchItem[] = [];\n const packagesOnStorage = this.filterByQuery(this.data.list, query);\n debug('memory search: packages found %o', packagesOnStorage.length);\n for (const name of packagesOnStorage) {\n const pkg: searchUtils.SearchItemPkg = { name };\n const isPrivate = this.data.list.includes(name);\n const score = this.getScore(pkg);\n results.push({\n package: pkg,\n verdaccioPrivate: isPrivate,\n verdaccioPkgCached: !isPrivate,\n score,\n });\n }\n return results;\n }\n\n private filterByQuery(list: string[], query: searchUtils.SearchQuery): string[] {\n const safeText = query.text.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const regex = new RegExp(safeText, 'i');\n return list.filter((name) => regex.test(name));\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n private getScore(_pkg: searchUtils.SearchItemPkg): searchUtils.Score {\n return {\n final: 1,\n detail: {\n maintenance: 0,\n popularity: 1,\n quality: 1,\n },\n };\n }\n\n async remove(name: string): Promise<void> {\n return new Promise((resolve): void => {\n const { list } = this.data;\n const item = list.indexOf(name);\n\n if (item !== -1) {\n list.splice(item, 1);\n }\n\n return resolve();\n });\n }\n\n async get(): Promise<any> {\n debug('data list length %o', this.data?.list?.length);\n return Promise.resolve(this.data?.list);\n }\n\n public getPackageStorage(packageInfo: string): MemoryHandler {\n // Ensure the package is in the list\n if (!this.data.list.includes(packageInfo)) {\n this.data.list.push(packageInfo);\n }\n return new MemoryHandler(packageInfo, this.data.files, this.logger);\n }\n\n private _createEmtpyDatabase(): MemoryLocalStorage {\n const list: string[] = [];\n const files = {};\n const tokens = {};\n const emptyDatabase = {\n list,\n files,\n tokens,\n secret: '',\n };\n\n return emptyDatabase;\n }\n\n public saveToken(token: Token): Promise<void> {\n return new Promise((resolve): void => {\n const { tokens } = this.data;\n\n if (!tokens[token.user]) {\n tokens[token.user] = [token];\n } else {\n tokens[token.user].push(token);\n }\n\n debug('token saved for user %o', token.user);\n resolve();\n });\n }\n\n public deleteToken(user: string, tokenKey: string): Promise<void> {\n return new Promise((resolve, reject): void => {\n const { tokens } = this.data;\n const userTokens = tokens[user];\n\n if (!userTokens) {\n reject(new Error('user not found'));\n return;\n }\n\n const remainingTokens = userTokens.filter((token) => token.key !== tokenKey);\n tokens[user] = remainingTokens;\n\n debug('removed token key %o for user %o', tokenKey, user);\n resolve();\n });\n }\n\n public readTokens(filter: TokenFilter): Promise<Token[]> {\n return new Promise((resolve): void => {\n const { tokens } = this.data;\n const userTokens = tokens[filter.user] || [];\n\n debug('read tokens for user %o: %o tokens', filter.user, userTokens.length);\n resolve(userTokens);\n });\n }\n}\n\nexport default LocalMemory;\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
import {
|
|
2
|
+
import { Readable, Writable } from 'node:stream';
|
|
3
3
|
import { pluginUtils } from '@verdaccio/core';
|
|
4
4
|
import { Logger, Manifest } from '@verdaccio/types';
|
|
5
5
|
export type DataHandler = {
|
|
@@ -7,22 +7,25 @@ export type DataHandler = {
|
|
|
7
7
|
};
|
|
8
8
|
declare class MemoryHandler implements pluginUtils.StorageHandler {
|
|
9
9
|
private data;
|
|
10
|
-
private
|
|
11
|
-
private path;
|
|
10
|
+
private packageName;
|
|
12
11
|
logger: Logger;
|
|
13
12
|
constructor(packageName: string, data: DataHandler, logger: Logger);
|
|
14
13
|
hasTarball(fileName: string): Promise<boolean>;
|
|
15
|
-
hasPackage(): Promise<boolean>;
|
|
16
|
-
deletePackage(
|
|
17
|
-
removePackage(): Promise<void>;
|
|
18
|
-
createPackage(
|
|
19
|
-
savePackage(
|
|
20
|
-
readPackage(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
|
|
14
|
+
hasPackage(packageName: string): Promise<boolean>;
|
|
15
|
+
deletePackage(fileName: string): Promise<void>;
|
|
16
|
+
removePackage(packageName: string): Promise<void>;
|
|
17
|
+
createPackage(packageName: string, manifest: Manifest): Promise<void>;
|
|
18
|
+
savePackage(packageName: string, manifest: Manifest): Promise<void>;
|
|
19
|
+
readPackage(packageName: string): Promise<Manifest>;
|
|
20
|
+
private getStorageKey;
|
|
21
|
+
private getStoragePath;
|
|
22
|
+
private removeFile;
|
|
23
|
+
writeTarball(fileName: string, { signal }: {
|
|
24
|
+
signal: AbortSignal;
|
|
25
|
+
}): Promise<Writable>;
|
|
26
|
+
readTarball(fileName: string, { signal }: {
|
|
27
|
+
signal: AbortSignal;
|
|
28
|
+
}): Promise<Readable>;
|
|
26
29
|
updatePackage(packageName: string, handleUpdate: (manifest: Manifest) => Promise<Manifest>): Promise<Manifest>;
|
|
27
30
|
}
|
|
28
31
|
export default MemoryHandler;
|
package/build/memory-handler.js
CHANGED
|
@@ -8,145 +8,256 @@ var _debug = _interopRequireDefault(require("debug"));
|
|
|
8
8
|
var _memfs = require("memfs");
|
|
9
9
|
var _nodePath = _interopRequireDefault(require("node:path"));
|
|
10
10
|
var _nodeStream = require("node:stream");
|
|
11
|
-
var _promises = require("node:stream/promises");
|
|
12
11
|
var _core = require("@verdaccio/core");
|
|
13
12
|
var _utils = require("./utils");
|
|
14
13
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
15
14
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
16
15
|
|
|
17
16
|
const debug = (0, _debug.default)('verdaccio:plugin:storage:memory-storage');
|
|
18
|
-
function fstatPromise(fd) {
|
|
19
|
-
return new Promise((resolve, reject) => {
|
|
20
|
-
_memfs.fs.fstat(fd, function (err, stats) {
|
|
21
|
-
if (err) {
|
|
22
|
-
return reject(err);
|
|
23
|
-
}
|
|
24
|
-
return resolve(stats);
|
|
25
|
-
});
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
function mkdirPPromise(fileName) {
|
|
29
|
-
return new Promise((resolve, reject) => {
|
|
30
|
-
_memfs.fs.mkdirp(_nodePath.default.dirname(fileName), function (err) {
|
|
31
|
-
if (err) {
|
|
32
|
-
return reject(err);
|
|
33
|
-
}
|
|
34
|
-
return resolve(true);
|
|
35
|
-
});
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
17
|
class MemoryHandler {
|
|
39
18
|
constructor(packageName, data, logger) {
|
|
40
|
-
// this is not need it
|
|
41
19
|
this.data = data;
|
|
42
|
-
this.name = packageName;
|
|
43
20
|
this.logger = logger;
|
|
44
|
-
this.
|
|
45
|
-
|
|
21
|
+
this.packageName = packageName;
|
|
22
|
+
// Ensure the root directory exists in memfs
|
|
23
|
+
try {
|
|
24
|
+
_memfs.fs.mkdirSync('/');
|
|
25
|
+
} catch (e) {
|
|
26
|
+
// ignore if already exists
|
|
27
|
+
}
|
|
46
28
|
}
|
|
47
29
|
async hasTarball(fileName) {
|
|
48
|
-
|
|
30
|
+
const exists = this.data[this.getStorageKey(fileName)] === 'true';
|
|
31
|
+
debug('hasTarball for %o: %s', fileName, exists);
|
|
32
|
+
return exists;
|
|
49
33
|
}
|
|
50
|
-
async hasPackage() {
|
|
51
|
-
return
|
|
34
|
+
async hasPackage(packageName) {
|
|
35
|
+
return this.data[packageName] !== undefined;
|
|
52
36
|
}
|
|
53
|
-
async deletePackage(
|
|
54
|
-
|
|
55
|
-
|
|
37
|
+
async deletePackage(fileName) {
|
|
38
|
+
// manifest is deleted by removePackage
|
|
39
|
+
if (fileName === 'package.json') {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
debug('delete tarball %o', fileName);
|
|
43
|
+
try {
|
|
44
|
+
const tarballName = this.getStoragePath(fileName);
|
|
45
|
+
const tarballKey = this.getStorageKey(fileName);
|
|
46
|
+
debug('deleting tarball with key: %s', tarballKey);
|
|
47
|
+
this.removeFile(tarballName);
|
|
48
|
+
delete this.data[tarballKey];
|
|
49
|
+
} catch (err) {
|
|
50
|
+
throw _core.errorUtils.getInternalError(err.message);
|
|
51
|
+
}
|
|
56
52
|
}
|
|
57
|
-
removePackage() {
|
|
58
|
-
|
|
53
|
+
async removePackage(packageName) {
|
|
54
|
+
debug('remove package %o', packageName);
|
|
55
|
+
delete this.data[packageName];
|
|
59
56
|
}
|
|
60
|
-
async createPackage(
|
|
61
|
-
debug('create package %o',
|
|
62
|
-
await this.savePackage(
|
|
57
|
+
async createPackage(packageName, manifest) {
|
|
58
|
+
debug('create package %o', packageName);
|
|
59
|
+
await this.savePackage(packageName, manifest);
|
|
63
60
|
}
|
|
64
|
-
async savePackage(
|
|
61
|
+
async savePackage(packageName, manifest) {
|
|
62
|
+
debug('save package %o', packageName);
|
|
65
63
|
try {
|
|
66
|
-
|
|
67
|
-
this.data[name] = (0, _utils.stringifyPackage)(value);
|
|
64
|
+
this.data[packageName] = (0, _utils.stringifyPackage)(manifest);
|
|
68
65
|
} catch (err) {
|
|
69
66
|
throw _core.errorUtils.getInternalError(err.message);
|
|
70
67
|
}
|
|
71
68
|
}
|
|
72
|
-
async readPackage(
|
|
73
|
-
debug('read package %o',
|
|
74
|
-
const json = this.
|
|
75
|
-
|
|
76
|
-
if (isJson) {
|
|
69
|
+
async readPackage(packageName) {
|
|
70
|
+
debug('read package %o', packageName);
|
|
71
|
+
const json = this.data[packageName];
|
|
72
|
+
if (json === undefined) {
|
|
77
73
|
throw _core.errorUtils.getNotFound();
|
|
78
74
|
}
|
|
79
|
-
|
|
75
|
+
try {
|
|
76
|
+
return (0, _utils.parsePackage)(json);
|
|
77
|
+
} catch (err) {
|
|
78
|
+
throw _core.errorUtils.getInternalError(err.message);
|
|
79
|
+
}
|
|
80
80
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
81
|
+
getStorageKey(fileName) {
|
|
82
|
+
return `${this.packageName}/${fileName}`;
|
|
83
|
+
}
|
|
84
|
+
getStoragePath(fileName) {
|
|
85
|
+
// Use the complete package name for proper directory structure
|
|
86
|
+
// memfs works with Unix-style paths on all platforms, so use forward slashes consistently
|
|
87
|
+
const storagePath = _nodePath.default.posix.normalize(_nodePath.default.posix.join('/', this.packageName, fileName));
|
|
88
|
+
debug('storage path for %s: %s', fileName, storagePath);
|
|
89
|
+
return storagePath;
|
|
90
|
+
}
|
|
91
|
+
async removeFile(fileName) {
|
|
92
|
+
debug('remove file %o', fileName);
|
|
93
|
+
try {
|
|
94
|
+
_memfs.fs.unlinkSync(fileName);
|
|
95
|
+
} catch (err) {
|
|
96
|
+
// Ignore if file does not exist
|
|
97
|
+
if (err.code !== 'ENOENT') {
|
|
98
|
+
throw err;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
87
101
|
}
|
|
88
|
-
async
|
|
102
|
+
async writeTarball(fileName, {
|
|
89
103
|
signal
|
|
90
104
|
}) {
|
|
91
|
-
|
|
92
|
-
const
|
|
93
|
-
const
|
|
94
|
-
readStream.on('open', async function (fileDescriptor) {
|
|
95
|
-
const stats = await fstatPromise(fileDescriptor);
|
|
96
|
-
passStream.emit('content-length', stats?.size);
|
|
97
|
-
});
|
|
98
|
-
readStream.on('error', err => {
|
|
99
|
-
passStream.emit('error', err);
|
|
100
|
-
});
|
|
101
|
-
await (0, _promises.pipeline)(readStream, passStream);
|
|
102
|
-
return passStream;
|
|
103
|
-
}
|
|
105
|
+
debug('write tarball %o', fileName);
|
|
106
|
+
const tarballName = this.getStoragePath(fileName);
|
|
107
|
+
const tarballKey = this.getStorageKey(fileName);
|
|
104
108
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
109
|
+
// Create a temporary file path to avoid conflicts (similar to local-fs)
|
|
110
|
+
const temporalName = `${tarballName}.tmp-${String(Math.random()).replace(/^0\./, '')}`;
|
|
111
|
+
debug('using temporal file %o', temporalName);
|
|
108
112
|
|
|
109
|
-
|
|
113
|
+
// Ensure the directory exists for the tarball BEFORE creating the stream
|
|
114
|
+
const dirName = _nodePath.default.posix.dirname(temporalName);
|
|
115
|
+
try {
|
|
116
|
+
// Make sure all directory levels are created
|
|
117
|
+
await _memfs.fs.promises.mkdir(dirName, {
|
|
118
|
+
recursive: true
|
|
119
|
+
});
|
|
120
|
+
debug('ensured directory exists %o', dirName);
|
|
121
|
+
} catch (err) {
|
|
122
|
+
debug('error creating directory %o: %s', dirName, err.message);
|
|
123
|
+
throw _core.errorUtils.getInternalError(`Failed to create directory: ${err.message}`);
|
|
124
|
+
}
|
|
125
|
+
let opened = false;
|
|
126
|
+
let closed = false;
|
|
127
|
+
// Create the write stream but don't rely on its built-in events entirely
|
|
128
|
+
const writeStream = _memfs.fs.createWriteStream(temporalName);
|
|
129
|
+
|
|
130
|
+
// Emit 'open' event in the next tick to ensure consistent behavior with fs streams
|
|
131
|
+
process.nextTick(() => {
|
|
132
|
+
opened = true;
|
|
133
|
+
debug('write stream opened for %o', temporalName);
|
|
134
|
+
writeStream.emit('open');
|
|
135
|
+
});
|
|
136
|
+
writeStream.on('error', err => {
|
|
137
|
+
debug('write stream error %o: %s', temporalName, err.message);
|
|
138
|
+
delete this.data[tarballKey];
|
|
139
|
+
if (opened) {
|
|
140
|
+
this.logger.error({
|
|
141
|
+
err,
|
|
142
|
+
fileName
|
|
143
|
+
}, 'error on open write tarball for @{fileName}: @{err.message}');
|
|
144
|
+
writeStream.on('close', () => {
|
|
145
|
+
this.removeFile(temporalName);
|
|
146
|
+
});
|
|
147
|
+
} else {
|
|
148
|
+
this.logger.error({
|
|
149
|
+
err,
|
|
150
|
+
fileName
|
|
151
|
+
}, 'error on writing tarball for @{fileName}: @{err.message}');
|
|
152
|
+
this.removeFile(temporalName);
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
writeStream.on('finish', () => {
|
|
156
|
+
debug('write stream finished for %o', fileName);
|
|
157
|
+
});
|
|
110
158
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
159
|
+
// This is called when the underlying file descriptor is closed
|
|
160
|
+
// which happens after the stream is finished/ended
|
|
161
|
+
writeStream.on('close', async () => {
|
|
162
|
+
// prevent double close event
|
|
163
|
+
if (closed) {
|
|
164
|
+
debug('close event already handled for %o', temporalName);
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
closed = true;
|
|
168
|
+
try {
|
|
169
|
+
// Check if temporary file exists before trying to rename
|
|
170
|
+
if (!_memfs.fs.existsSync(temporalName)) {
|
|
171
|
+
debug('temporary file %o does not exist, skipping rename', temporalName);
|
|
172
|
+
delete this.data[tarballKey];
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
116
175
|
|
|
117
|
-
|
|
118
|
-
|
|
176
|
+
// Rename the temporary file to the final location (atomic operation)
|
|
177
|
+
await _memfs.fs.promises.rename(temporalName, tarballName);
|
|
178
|
+
// Store the mapping of key to true (indicating it exists)
|
|
179
|
+
this.data[tarballKey] = 'true';
|
|
180
|
+
debug('write stream closed successfully, renamed %o to %o, stored with key %o', temporalName, tarballName, tarballKey);
|
|
181
|
+
} catch (err) {
|
|
182
|
+
debug('error renaming %o to %o: %s', temporalName, tarballName, err.message);
|
|
183
|
+
this.logger.error({
|
|
184
|
+
err,
|
|
185
|
+
temporalName,
|
|
186
|
+
finalTarballPath: tarballName
|
|
187
|
+
}, 'error renaming temporal file @{temporalName} to @{finalTarballPath}: @{err.message}');
|
|
188
|
+
// Clean up the mapping since rename failed
|
|
189
|
+
delete this.data[tarballKey];
|
|
190
|
+
this.removeFile(temporalName);
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
signal?.addEventListener('abort', () => {
|
|
194
|
+
debug('upload aborted for %o', fileName);
|
|
195
|
+
delete this.data[tarballKey];
|
|
196
|
+
if (opened) {
|
|
197
|
+
writeStream.once('close', () => {
|
|
198
|
+
this.removeFile(temporalName);
|
|
199
|
+
});
|
|
200
|
+
writeStream.destroy();
|
|
201
|
+
} else {
|
|
202
|
+
this.removeFile(temporalName);
|
|
203
|
+
}
|
|
204
|
+
}, {
|
|
205
|
+
once: true
|
|
206
|
+
});
|
|
207
|
+
return writeStream;
|
|
208
|
+
}
|
|
209
|
+
async readTarball(fileName, {
|
|
210
|
+
signal
|
|
211
|
+
}) {
|
|
212
|
+
debug('read tarball %o', fileName);
|
|
119
213
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
214
|
+
// Check if the tarball exists in our mapping
|
|
215
|
+
if (!this.hasTarball(fileName)) {
|
|
216
|
+
debug('tarball not found: %s', fileName);
|
|
217
|
+
throw _core.errorUtils.getNotFound('no such package');
|
|
218
|
+
}
|
|
219
|
+
const tarballName = this.getStoragePath(fileName);
|
|
220
|
+
const tarballKey = this.getStorageKey(fileName);
|
|
126
221
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
222
|
+
// Additional filesystem check
|
|
223
|
+
try {
|
|
224
|
+
const exists = _memfs.fs.existsSync(tarballName);
|
|
225
|
+
if (!exists) {
|
|
226
|
+
debug('tarball file does not exist on filesystem: %s', tarballName);
|
|
227
|
+
delete this.data[tarballKey]; // Clean up incorrect state
|
|
228
|
+
throw _core.errorUtils.getNotFound('no such package');
|
|
229
|
+
}
|
|
230
|
+
} catch (err) {
|
|
231
|
+
debug('error checking tarball existence: %s', err.message);
|
|
232
|
+
throw _core.errorUtils.getNotFound('no such package');
|
|
233
|
+
}
|
|
234
|
+
const readStream = (0, _nodeStream.addAbortSignal)(signal, _memfs.fs.createReadStream(tarballName));
|
|
137
235
|
|
|
138
|
-
|
|
139
|
-
|
|
236
|
+
// Check stats before emitting open event to ensure content-length is available
|
|
237
|
+
const stats = _memfs.fs.statSync(tarballName);
|
|
140
238
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
239
|
+
// Manually emit 'open' event in the next tick to ensure consistent behavior with fs streams
|
|
240
|
+
process.nextTick(() => {
|
|
241
|
+
debug('read stream opened for %o', tarballName);
|
|
242
|
+
readStream.emit('open');
|
|
243
|
+
debug('file size %o', stats.size);
|
|
244
|
+
readStream.emit('content-length', stats.size);
|
|
245
|
+
});
|
|
246
|
+
readStream.on('error', error => {
|
|
247
|
+
debug('error reading tarball %o: %s', tarballName, error.message);
|
|
248
|
+
});
|
|
249
|
+
return readStream;
|
|
144
250
|
}
|
|
145
251
|
async updatePackage(packageName, handleUpdate) {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
252
|
+
debug('update package %o', packageName);
|
|
253
|
+
try {
|
|
254
|
+
const json = this.data[packageName];
|
|
255
|
+
let manifest = (0, _utils.parsePackage)(json);
|
|
256
|
+
const newManifest = await handleUpdate(manifest);
|
|
257
|
+
return newManifest;
|
|
258
|
+
} catch (err) {
|
|
259
|
+
throw _core.errorUtils.getInternalError(err.message);
|
|
260
|
+
}
|
|
150
261
|
}
|
|
151
262
|
}
|
|
152
263
|
var _default = exports.default = MemoryHandler;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-handler.js","names":["_debug","_interopRequireDefault","require","_memfs","_nodePath","_nodeStream","_promises","_core","_utils","e","__esModule","default","debug","buildDebug","fstatPromise","fd","Promise","resolve","reject","fs","fstat","err","stats","mkdirPPromise","fileName","mkdirp","path","dirname","MemoryHandler","constructor","packageName","data","logger","name","hasTarball","Error","hasPackage","deletePackage","pkgName","removePackage","createPackage","value","savePackage","stringifyPackage","errorUtils","getInternalError","message","readPackage","json","_getStorage","isJson","getNotFound","parsePackage","writeTarball","temporalName","writeStream","createWriteStream","readTarball","signal","pathName","passStream","PassThrough","readStream","addAbortSignal","createReadStream","on","fileDescriptor","emit","size","pipeline","updatePackage","handleUpdate","pkg","newManifest","_default","exports"],"sources":["../src/memory-handler.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unused-vars */\nimport buildDebug from 'debug';\nimport { fs } from 'memfs';\nimport { Stats } from 'memfs/lib/Stats';\nimport path from 'node:path';\nimport { PassThrough, Writable, addAbortSignal } from 'node:stream';\nimport { pipeline } from 'node:stream/promises';\n\nimport { errorUtils, pluginUtils } from '@verdaccio/core';\nimport { Logger, Manifest } from '@verdaccio/types';\n\nimport { parsePackage, stringifyPackage } from './utils';\n\nconst debug = buildDebug('verdaccio:plugin:storage:memory-storage');\n\nfunction fstatPromise(fd): Promise<Stats | undefined> {\n return new Promise((resolve, reject) => {\n fs.fstat(fd, function (err, stats) {\n if (err) {\n return reject(err);\n }\n return resolve(stats);\n });\n });\n}\n\nfunction mkdirPPromise(fileName) {\n return new Promise((resolve, reject) => {\n fs.mkdirp(path.dirname(fileName), function (err) {\n if (err) {\n return reject(err);\n }\n return resolve(true);\n });\n });\n}\n\nexport type DataHandler = {\n [key: string]: string;\n};\n\nclass MemoryHandler implements pluginUtils.StorageHandler {\n private data: DataHandler;\n private name: string;\n private path: string;\n public logger: Logger;\n\n public constructor(packageName: string, data: DataHandler, logger: Logger) {\n // this is not need it\n this.data = data;\n this.name = packageName;\n this.logger = logger;\n this.path = `/${packageName}`;\n debug('initialized');\n }\n\n public async hasTarball(fileName: string): Promise<boolean> {\n throw new Error('not implemented');\n }\n\n public async hasPackage(): Promise<boolean> {\n return false;\n }\n\n public async deletePackage(pkgName: string): Promise<void> {\n delete this.data[pkgName];\n return;\n }\n\n public removePackage() {\n return Promise.resolve();\n }\n\n public async createPackage(name: string, value: Manifest): Promise<void> {\n debug('create package %o', name);\n await this.savePackage(name, value);\n }\n\n public async savePackage(name: string, value: Manifest): Promise<void> {\n try {\n debug('save package %o', name);\n this.data[name] = stringifyPackage(value);\n } catch (err: any) {\n throw errorUtils.getInternalError(err.message);\n }\n }\n\n public async readPackage(name: string): Promise<Manifest> {\n debug('read package %o', name);\n const json = this._getStorage(name);\n const isJson = typeof json === 'undefined';\n if (isJson) {\n throw errorUtils.getNotFound();\n }\n return parsePackage(json);\n }\n\n public async writeTarball(name: string): Promise<Writable> {\n const temporalName = `${this.path}/${name}`;\n debug('write tarball %o', temporalName);\n await mkdirPPromise(temporalName);\n const writeStream = fs.createWriteStream(temporalName);\n return writeStream;\n }\n\n public async readTarball(pkgName: string, { signal }): Promise<PassThrough> {\n const pathName: string = this._getStorage(pkgName);\n const passStream = new PassThrough();\n const readStream = addAbortSignal(signal, fs.createReadStream(pathName));\n readStream.on('open', async function (fileDescriptor) {\n const stats = await fstatPromise(fileDescriptor);\n passStream.emit('content-length', stats?.size);\n });\n readStream.on('error', (err) => {\n passStream.emit('error', err);\n });\n\n await pipeline(readStream, passStream);\n\n return passStream;\n }\n\n // public readTarball(name: string): IReadTarball {\n // const pathName = `${this.path}/${name}`;\n // debug('read tarball %o', pathName);\n\n // const readTarballStream: IReadTarball = new ReadTarball({});\n\n // process.nextTick(function () {\n // fs.stat(pathName, function (error, stats) {\n // if (error && !stats) {\n // return readTarballStream.emit('error', errorUtils.getNotFound());\n // }\n\n // try {\n // const readStream = fs.createReadStream(pathName);\n\n // readTarballStream.emit('content-length', stats?.size);\n // readTarballStream.emit('open');\n // readStream.pipe(readTarballStream);\n // readStream.on('error', (error: VerdaccioError) => {\n // readTarballStream.emit('error', error);\n // });\n\n // readTarballStream.abort = function (): void {\n // readStream.destroy(errorUtils.getBadRequest('read has been aborted'));\n // };\n // return;\n // } catch (err: any) {\n // readTarballStream.emit('error', err);\n // return;\n // }\n // });\n // });\n\n // return readTarballStream;\n // }\n\n private _getStorage(name = ''): string {\n debug('get storage %o', name);\n return this.data[name];\n }\n\n public async updatePackage(\n packageName: string,\n handleUpdate: (manifest: Manifest) => Promise<Manifest>\n ): Promise<Manifest> {\n const json: string = this._getStorage(packageName);\n let pkg: Manifest = parsePackage(json) as Manifest;\n const newManifest = await handleUpdate(pkg);\n return newManifest;\n }\n}\n\nexport default MemoryHandler;\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"memory-handler.js","names":["_debug","_interopRequireDefault","require","_memfs","_nodePath","_nodeStream","_core","_utils","e","__esModule","default","debug","buildDebug","MemoryHandler","constructor","packageName","data","logger","fs","mkdirSync","hasTarball","fileName","exists","getStorageKey","hasPackage","undefined","deletePackage","tarballName","getStoragePath","tarballKey","removeFile","err","errorUtils","getInternalError","message","removePackage","createPackage","manifest","savePackage","stringifyPackage","readPackage","json","getNotFound","parsePackage","storagePath","path","posix","normalize","join","unlinkSync","code","writeTarball","signal","temporalName","String","Math","random","replace","dirName","dirname","promises","mkdir","recursive","opened","closed","writeStream","createWriteStream","process","nextTick","emit","on","error","existsSync","rename","finalTarballPath","addEventListener","once","destroy","readTarball","readStream","addAbortSignal","createReadStream","stats","statSync","size","updatePackage","handleUpdate","newManifest","_default","exports"],"sources":["../src/memory-handler.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unused-vars */\nimport buildDebug from 'debug';\nimport { fs } from 'memfs';\nimport path from 'node:path';\nimport { Readable, Writable, addAbortSignal } from 'node:stream';\n\nimport { errorUtils, pluginUtils } from '@verdaccio/core';\nimport { Logger, Manifest } from '@verdaccio/types';\n\nimport { parsePackage, stringifyPackage } from './utils';\n\nconst debug = buildDebug('verdaccio:plugin:storage:memory-storage');\n\nexport type DataHandler = {\n [key: string]: string;\n};\n\nclass MemoryHandler implements pluginUtils.StorageHandler {\n private data: DataHandler;\n private packageName: string;\n public logger: Logger;\n\n public constructor(packageName: string, data: DataHandler, logger: Logger) {\n this.data = data;\n this.logger = logger;\n this.packageName = packageName;\n // Ensure the root directory exists in memfs\n try {\n fs.mkdirSync('/');\n } catch (e) {\n // ignore if already exists\n }\n }\n\n public async hasTarball(fileName: string): Promise<boolean> {\n const exists = this.data[this.getStorageKey(fileName)] === 'true';\n debug('hasTarball for %o: %s', fileName, exists);\n return exists;\n }\n\n public async hasPackage(packageName: string): Promise<boolean> {\n return this.data[packageName] !== undefined;\n }\n\n public async deletePackage(fileName: string): Promise<void> {\n // manifest is deleted by removePackage\n if (fileName === 'package.json') {\n return;\n }\n debug('delete tarball %o', fileName);\n try {\n const tarballName = this.getStoragePath(fileName);\n const tarballKey = this.getStorageKey(fileName);\n debug('deleting tarball with key: %s', tarballKey);\n this.removeFile(tarballName);\n delete this.data[tarballKey];\n } catch (err: any) {\n throw errorUtils.getInternalError(err.message);\n }\n }\n\n public async removePackage(packageName: string): Promise<void> {\n debug('remove package %o', packageName);\n delete this.data[packageName];\n }\n\n public async createPackage(packageName: string, manifest: Manifest): Promise<void> {\n debug('create package %o', packageName);\n await this.savePackage(packageName, manifest);\n }\n\n public async savePackage(packageName: string, manifest: Manifest): Promise<void> {\n debug('save package %o', packageName);\n try {\n this.data[packageName] = stringifyPackage(manifest);\n } catch (err: any) {\n throw errorUtils.getInternalError(err.message);\n }\n }\n\n public async readPackage(packageName: string): Promise<Manifest> {\n debug('read package %o', packageName);\n const json = this.data[packageName];\n if (json === undefined) {\n throw errorUtils.getNotFound();\n }\n try {\n return parsePackage(json);\n } catch (err: any) {\n throw errorUtils.getInternalError(err.message);\n }\n }\n\n private getStorageKey(fileName: string): string {\n return `${this.packageName}/${fileName}`;\n }\n\n private getStoragePath(fileName: string): string {\n // Use the complete package name for proper directory structure\n // memfs works with Unix-style paths on all platforms, so use forward slashes consistently\n const storagePath = path.posix.normalize(path.posix.join('/', this.packageName, fileName));\n debug('storage path for %s: %s', fileName, storagePath);\n return storagePath;\n }\n\n private async removeFile(fileName: string): Promise<void> {\n debug('remove file %o', fileName);\n try {\n fs.unlinkSync(fileName);\n } catch (err: any) {\n // Ignore if file does not exist\n if (err.code !== 'ENOENT') {\n throw err;\n }\n }\n }\n\n public async writeTarball(\n fileName: string,\n { signal }: { signal: AbortSignal }\n ): Promise<Writable> {\n debug('write tarball %o', fileName);\n const tarballName = this.getStoragePath(fileName);\n const tarballKey = this.getStorageKey(fileName);\n\n // Create a temporary file path to avoid conflicts (similar to local-fs)\n const temporalName = `${tarballName}.tmp-${String(Math.random()).replace(/^0\\./, '')}`;\n debug('using temporal file %o', temporalName);\n\n // Ensure the directory exists for the tarball BEFORE creating the stream\n const dirName = path.posix.dirname(temporalName);\n try {\n // Make sure all directory levels are created\n await fs.promises.mkdir(dirName, { recursive: true });\n debug('ensured directory exists %o', dirName);\n } catch (err: any) {\n debug('error creating directory %o: %s', dirName, err.message);\n throw errorUtils.getInternalError(`Failed to create directory: ${err.message}`);\n }\n\n let opened = false;\n let closed = false;\n // Create the write stream but don't rely on its built-in events entirely\n const writeStream = fs.createWriteStream(temporalName);\n\n // Emit 'open' event in the next tick to ensure consistent behavior with fs streams\n process.nextTick(() => {\n opened = true;\n debug('write stream opened for %o', temporalName);\n writeStream.emit('open');\n });\n\n writeStream.on('error', (err) => {\n debug('write stream error %o: %s', temporalName, err.message);\n delete this.data[tarballKey];\n if (opened) {\n this.logger.error(\n { err, fileName },\n 'error on open write tarball for @{fileName}: @{err.message}'\n );\n writeStream.on('close', () => {\n this.removeFile(temporalName);\n });\n } else {\n this.logger.error(\n { err, fileName },\n 'error on writing tarball for @{fileName}: @{err.message}'\n );\n this.removeFile(temporalName);\n }\n });\n\n writeStream.on('finish', () => {\n debug('write stream finished for %o', fileName);\n });\n\n // This is called when the underlying file descriptor is closed\n // which happens after the stream is finished/ended\n writeStream.on('close', async () => {\n // prevent double close event\n if (closed) {\n debug('close event already handled for %o', temporalName);\n return;\n }\n closed = true;\n try {\n // Check if temporary file exists before trying to rename\n if (!fs.existsSync(temporalName)) {\n debug('temporary file %o does not exist, skipping rename', temporalName);\n delete this.data[tarballKey];\n return;\n }\n\n // Rename the temporary file to the final location (atomic operation)\n await fs.promises.rename(temporalName, tarballName);\n // Store the mapping of key to true (indicating it exists)\n this.data[tarballKey] = 'true';\n debug(\n 'write stream closed successfully, renamed %o to %o, stored with key %o',\n temporalName,\n tarballName,\n tarballKey\n );\n } catch (err: any) {\n debug('error renaming %o to %o: %s', temporalName, tarballName, err.message);\n this.logger.error(\n { err, temporalName, finalTarballPath: tarballName },\n 'error renaming temporal file @{temporalName} to @{finalTarballPath}: @{err.message}'\n );\n // Clean up the mapping since rename failed\n delete this.data[tarballKey];\n this.removeFile(temporalName);\n }\n });\n\n signal?.addEventListener(\n 'abort',\n () => {\n debug('upload aborted for %o', fileName);\n delete this.data[tarballKey];\n if (opened) {\n writeStream.once('close', () => {\n this.removeFile(temporalName);\n });\n writeStream.destroy();\n } else {\n this.removeFile(temporalName);\n }\n },\n { once: true }\n );\n\n return writeStream;\n }\n\n public async readTarball(\n fileName: string,\n { signal }: { signal: AbortSignal }\n ): Promise<Readable> {\n debug('read tarball %o', fileName);\n\n // Check if the tarball exists in our mapping\n if (!this.hasTarball(fileName)) {\n debug('tarball not found: %s', fileName);\n throw errorUtils.getNotFound('no such package');\n }\n\n const tarballName = this.getStoragePath(fileName);\n const tarballKey = this.getStorageKey(fileName);\n\n // Additional filesystem check\n try {\n const exists = fs.existsSync(tarballName);\n if (!exists) {\n debug('tarball file does not exist on filesystem: %s', tarballName);\n delete this.data[tarballKey]; // Clean up incorrect state\n throw errorUtils.getNotFound('no such package');\n }\n } catch (err: any) {\n debug('error checking tarball existence: %s', err.message);\n throw errorUtils.getNotFound('no such package');\n }\n\n const readStream = addAbortSignal(signal, fs.createReadStream(tarballName));\n\n // Check stats before emitting open event to ensure content-length is available\n const stats = fs.statSync(tarballName);\n\n // Manually emit 'open' event in the next tick to ensure consistent behavior with fs streams\n process.nextTick(() => {\n debug('read stream opened for %o', tarballName);\n readStream.emit('open');\n debug('file size %o', stats.size);\n readStream.emit('content-length', stats.size);\n });\n\n readStream.on('error', (error) => {\n debug('error reading tarball %o: %s', tarballName, error.message);\n });\n\n return readStream;\n }\n\n public async updatePackage(\n packageName: string,\n handleUpdate: (manifest: Manifest) => Promise<Manifest>\n ): Promise<Manifest> {\n debug('update package %o', packageName);\n try {\n const json = this.data[packageName];\n let manifest = parsePackage(json);\n const newManifest = await handleUpdate(manifest);\n return newManifest;\n } catch (err: any) {\n throw errorUtils.getInternalError(err.message);\n }\n }\n}\n\nexport default MemoryHandler;\n"],"mappings":"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","ignoreList":[]}
|
package/build/utils.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare function stringifyPackage(
|
|
3
|
-
export declare function parsePackage(
|
|
1
|
+
import { Manifest } from '@verdaccio/types';
|
|
2
|
+
export declare function stringifyPackage(manifest: Manifest): string;
|
|
3
|
+
export declare function parsePackage(json: string): Manifest;
|
package/build/utils.js
CHANGED
|
@@ -5,10 +5,10 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.parsePackage = parsePackage;
|
|
7
7
|
exports.stringifyPackage = stringifyPackage;
|
|
8
|
-
function stringifyPackage(
|
|
9
|
-
return JSON.stringify(
|
|
8
|
+
function stringifyPackage(manifest) {
|
|
9
|
+
return JSON.stringify(manifest, null, '\t');
|
|
10
10
|
}
|
|
11
|
-
function parsePackage(
|
|
12
|
-
return JSON.parse(
|
|
11
|
+
function parsePackage(json) {
|
|
12
|
+
return JSON.parse(json);
|
|
13
13
|
}
|
|
14
14
|
//# sourceMappingURL=utils.js.map
|
package/build/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","names":["stringifyPackage","
|
|
1
|
+
{"version":3,"file":"utils.js","names":["stringifyPackage","manifest","JSON","stringify","parsePackage","json","parse"],"sources":["../src/utils.ts"],"sourcesContent":["import { Manifest } from '@verdaccio/types';\n\nexport function stringifyPackage(manifest: Manifest): string {\n return JSON.stringify(manifest, null, '\\t');\n}\n\nexport function parsePackage(json: string): Manifest {\n return JSON.parse(json);\n}\n"],"mappings":";;;;;;;AAEO,SAASA,gBAAgBA,CAACC,QAAkB,EAAU;EAC3D,OAAOC,IAAI,CAACC,SAAS,CAACF,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC;AAC7C;AAEO,SAASG,YAAYA,CAACC,IAAY,EAAY;EACnD,OAAOH,IAAI,CAACI,KAAK,CAACD,IAAI,CAAC;AACzB","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "verdaccio-memory",
|
|
3
|
-
"version": "13.0.0-next-8.
|
|
3
|
+
"version": "13.0.0-next-8.22",
|
|
4
4
|
"description": "Verdaccio Memory Storage Plugin",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"private",
|
|
@@ -30,15 +30,15 @@
|
|
|
30
30
|
"node": ">=18"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@verdaccio/core": "8.0.0-next-8.
|
|
33
|
+
"@verdaccio/core": "8.0.0-next-8.22",
|
|
34
34
|
"debug": "4.4.1",
|
|
35
|
-
"memfs": "
|
|
35
|
+
"memfs": "4.17.2"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@verdaccio/types": "13.0.0-next-8.7",
|
|
39
|
-
"@verdaccio/config": "8.0.0-next-8.
|
|
40
|
-
"@verdaccio/logger": "8.0.0-next-8.
|
|
41
|
-
"vitest": "3.
|
|
39
|
+
"@verdaccio/config": "8.0.0-next-8.22",
|
|
40
|
+
"@verdaccio/logger": "8.0.0-next-8.22",
|
|
41
|
+
"vitest": "3.2.4"
|
|
42
42
|
},
|
|
43
43
|
"funding": {
|
|
44
44
|
"type": "opencollective",
|