@push.rocks/smartregistry 2.2.3 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/cargo/classes.cargoregistry.d.ts +7 -1
- package/dist_ts/cargo/classes.cargoregistry.js +42 -4
- package/dist_ts/cargo/classes.cargoupstream.d.ts +44 -0
- package/dist_ts/cargo/classes.cargoupstream.js +129 -0
- package/dist_ts/cargo/index.d.ts +1 -0
- package/dist_ts/cargo/index.js +2 -1
- package/dist_ts/classes.smartregistry.d.ts +33 -2
- package/dist_ts/classes.smartregistry.js +45 -12
- package/dist_ts/composer/classes.composerregistry.d.ts +7 -1
- package/dist_ts/composer/classes.composerregistry.js +34 -3
- package/dist_ts/composer/classes.composerupstream.d.ts +40 -0
- package/dist_ts/composer/classes.composerupstream.js +159 -0
- package/dist_ts/composer/index.d.ts +1 -0
- package/dist_ts/composer/index.js +2 -1
- package/dist_ts/core/classes.authmanager.d.ts +30 -80
- package/dist_ts/core/classes.authmanager.js +63 -337
- package/dist_ts/core/classes.defaultauthprovider.d.ts +78 -0
- package/dist_ts/core/classes.defaultauthprovider.js +311 -0
- package/dist_ts/core/classes.registrystorage.d.ts +70 -4
- package/dist_ts/core/classes.registrystorage.js +165 -5
- package/dist_ts/core/index.d.ts +3 -0
- package/dist_ts/core/index.js +7 -2
- package/dist_ts/core/interfaces.auth.d.ts +83 -0
- package/dist_ts/core/interfaces.auth.js +2 -0
- package/dist_ts/core/interfaces.core.d.ts +38 -0
- package/dist_ts/core/interfaces.storage.d.ts +120 -0
- package/dist_ts/core/interfaces.storage.js +2 -0
- package/dist_ts/index.d.ts +1 -0
- package/dist_ts/index.js +3 -1
- package/dist_ts/maven/classes.mavenregistry.d.ts +12 -1
- package/dist_ts/maven/classes.mavenregistry.js +69 -4
- package/dist_ts/maven/classes.mavenupstream.d.ts +45 -0
- package/dist_ts/maven/classes.mavenupstream.js +153 -0
- package/dist_ts/maven/index.d.ts +1 -0
- package/dist_ts/maven/index.js +2 -1
- package/dist_ts/npm/classes.npmregistry.d.ts +3 -1
- package/dist_ts/npm/classes.npmregistry.js +55 -6
- package/dist_ts/npm/classes.npmupstream.d.ts +51 -0
- package/dist_ts/npm/classes.npmupstream.js +206 -0
- package/dist_ts/npm/index.d.ts +1 -0
- package/dist_ts/npm/index.js +2 -1
- package/dist_ts/oci/classes.ociregistry.d.ts +4 -1
- package/dist_ts/oci/classes.ociregistry.js +78 -17
- package/dist_ts/oci/classes.ociupstream.d.ts +62 -0
- package/dist_ts/oci/classes.ociupstream.js +206 -0
- package/dist_ts/oci/index.d.ts +1 -0
- package/dist_ts/oci/index.js +2 -1
- package/dist_ts/plugins.d.ts +4 -1
- package/dist_ts/plugins.js +6 -2
- package/dist_ts/pypi/classes.pypiregistry.d.ts +7 -1
- package/dist_ts/pypi/classes.pypiregistry.js +60 -4
- package/dist_ts/pypi/classes.pypiupstream.d.ts +48 -0
- package/dist_ts/pypi/classes.pypiupstream.js +165 -0
- package/dist_ts/pypi/index.d.ts +1 -0
- package/dist_ts/pypi/index.js +2 -1
- package/dist_ts/rubygems/classes.rubygemsregistry.d.ts +7 -1
- package/dist_ts/rubygems/classes.rubygemsregistry.js +35 -4
- package/dist_ts/rubygems/classes.rubygemsupstream.d.ts +47 -0
- package/dist_ts/rubygems/classes.rubygemsupstream.js +184 -0
- package/dist_ts/rubygems/index.d.ts +1 -0
- package/dist_ts/rubygems/index.js +2 -1
- package/dist_ts/upstream/classes.baseupstream.d.ts +112 -0
- package/dist_ts/upstream/classes.baseupstream.js +411 -0
- package/dist_ts/upstream/classes.circuitbreaker.d.ts +111 -0
- package/dist_ts/upstream/classes.circuitbreaker.js +192 -0
- package/dist_ts/upstream/classes.upstreamcache.d.ts +170 -0
- package/dist_ts/upstream/classes.upstreamcache.js +485 -0
- package/dist_ts/upstream/index.d.ts +6 -0
- package/dist_ts/upstream/index.js +7 -0
- package/dist_ts/upstream/interfaces.upstream.d.ts +169 -0
- package/dist_ts/upstream/interfaces.upstream.js +23 -0
- package/package.json +4 -2
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/cargo/classes.cargoregistry.ts +48 -3
- package/ts/cargo/classes.cargoupstream.ts +159 -0
- package/ts/cargo/index.ts +1 -0
- package/ts/classes.smartregistry.ts +88 -11
- package/ts/composer/classes.composerregistry.ts +39 -2
- package/ts/composer/classes.composerupstream.ts +200 -0
- package/ts/composer/index.ts +1 -0
- package/ts/core/classes.authmanager.ts +74 -412
- package/ts/core/classes.defaultauthprovider.ts +393 -0
- package/ts/core/classes.registrystorage.ts +199 -5
- package/ts/core/index.ts +8 -1
- package/ts/core/interfaces.auth.ts +91 -0
- package/ts/core/interfaces.core.ts +42 -0
- package/ts/core/interfaces.storage.ts +130 -0
- package/ts/index.ts +3 -0
- package/ts/maven/classes.mavenregistry.ts +84 -3
- package/ts/maven/classes.mavenupstream.ts +220 -0
- package/ts/maven/index.ts +1 -0
- package/ts/npm/classes.npmregistry.ts +61 -5
- package/ts/npm/classes.npmupstream.ts +260 -0
- package/ts/npm/index.ts +1 -0
- package/ts/oci/classes.ociregistry.ts +89 -17
- package/ts/oci/classes.ociupstream.ts +263 -0
- package/ts/oci/index.ts +1 -0
- package/ts/plugins.ts +7 -1
- package/ts/pypi/classes.pypiregistry.ts +68 -3
- package/ts/pypi/classes.pypiupstream.ts +211 -0
- package/ts/pypi/index.ts +1 -0
- package/ts/rubygems/classes.rubygemsregistry.ts +40 -3
- package/ts/rubygems/classes.rubygemsupstream.ts +230 -0
- package/ts/rubygems/index.ts +1 -0
- package/ts/upstream/classes.baseupstream.ts +526 -0
- package/ts/upstream/classes.circuitbreaker.ts +238 -0
- package/ts/upstream/classes.upstreamcache.ts +626 -0
- package/ts/upstream/index.ts +11 -0
- package/ts/upstream/interfaces.upstream.ts +195 -0
|
@@ -7,6 +7,7 @@ import { BaseRegistry } from '../core/classes.baseregistry.js';
|
|
|
7
7
|
import type { RegistryStorage } from '../core/classes.registrystorage.js';
|
|
8
8
|
import type { AuthManager } from '../core/classes.authmanager.js';
|
|
9
9
|
import type { IRequestContext, IResponse, IAuthToken } from '../core/interfaces.core.js';
|
|
10
|
+
import type { IProtocolUpstreamConfig } from '../upstream/interfaces.upstream.js';
|
|
10
11
|
import { isBinaryData, toBuffer } from '../core/helpers.buffer.js';
|
|
11
12
|
import type {
|
|
12
13
|
IComposerPackage,
|
|
@@ -22,24 +23,41 @@ import {
|
|
|
22
23
|
generatePackagesJson,
|
|
23
24
|
sortVersions,
|
|
24
25
|
} from './helpers.composer.js';
|
|
26
|
+
import { ComposerUpstream } from './classes.composerupstream.js';
|
|
25
27
|
|
|
26
28
|
export class ComposerRegistry extends BaseRegistry {
|
|
27
29
|
private storage: RegistryStorage;
|
|
28
30
|
private authManager: AuthManager;
|
|
29
31
|
private basePath: string = '/composer';
|
|
30
32
|
private registryUrl: string;
|
|
33
|
+
private upstream: ComposerUpstream | null = null;
|
|
31
34
|
|
|
32
35
|
constructor(
|
|
33
36
|
storage: RegistryStorage,
|
|
34
37
|
authManager: AuthManager,
|
|
35
38
|
basePath: string = '/composer',
|
|
36
|
-
registryUrl: string = 'http://localhost:5000/composer'
|
|
39
|
+
registryUrl: string = 'http://localhost:5000/composer',
|
|
40
|
+
upstreamConfig?: IProtocolUpstreamConfig
|
|
37
41
|
) {
|
|
38
42
|
super();
|
|
39
43
|
this.storage = storage;
|
|
40
44
|
this.authManager = authManager;
|
|
41
45
|
this.basePath = basePath;
|
|
42
46
|
this.registryUrl = registryUrl;
|
|
47
|
+
|
|
48
|
+
// Initialize upstream if configured
|
|
49
|
+
if (upstreamConfig?.enabled) {
|
|
50
|
+
this.upstream = new ComposerUpstream(upstreamConfig);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Clean up resources (timers, connections, etc.)
|
|
56
|
+
*/
|
|
57
|
+
public destroy(): void {
|
|
58
|
+
if (this.upstream) {
|
|
59
|
+
this.upstream.stop();
|
|
60
|
+
}
|
|
43
61
|
}
|
|
44
62
|
|
|
45
63
|
public async init(): Promise<void> {
|
|
@@ -161,7 +179,26 @@ export class ComposerRegistry extends BaseRegistry {
|
|
|
161
179
|
token: IAuthToken | null
|
|
162
180
|
): Promise<IResponse> {
|
|
163
181
|
// Read operations are public, no authentication required
|
|
164
|
-
|
|
182
|
+
let metadata = await this.storage.getComposerPackageMetadata(vendorPackage);
|
|
183
|
+
|
|
184
|
+
// Try upstream if not found locally
|
|
185
|
+
if (!metadata && this.upstream) {
|
|
186
|
+
const [vendor, packageName] = vendorPackage.split('/');
|
|
187
|
+
if (vendor && packageName) {
|
|
188
|
+
const upstreamMetadata = includeDev
|
|
189
|
+
? await this.upstream.fetchPackageDevMetadata(vendor, packageName)
|
|
190
|
+
: await this.upstream.fetchPackageMetadata(vendor, packageName);
|
|
191
|
+
|
|
192
|
+
if (upstreamMetadata && upstreamMetadata.packages) {
|
|
193
|
+
// Store upstream metadata locally
|
|
194
|
+
metadata = {
|
|
195
|
+
packages: upstreamMetadata.packages,
|
|
196
|
+
lastModified: new Date().toUTCString(),
|
|
197
|
+
};
|
|
198
|
+
await this.storage.putComposerPackageMetadata(vendorPackage, metadata);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
165
202
|
|
|
166
203
|
if (!metadata) {
|
|
167
204
|
return {
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import * as plugins from '../plugins.js';
|
|
2
|
+
import { BaseUpstream } from '../upstream/classes.baseupstream.js';
|
|
3
|
+
import type {
|
|
4
|
+
IProtocolUpstreamConfig,
|
|
5
|
+
IUpstreamFetchContext,
|
|
6
|
+
IUpstreamRegistryConfig,
|
|
7
|
+
} from '../upstream/interfaces.upstream.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Composer-specific upstream implementation.
|
|
11
|
+
*
|
|
12
|
+
* Handles:
|
|
13
|
+
* - Package metadata fetching (packages.json, provider-includes)
|
|
14
|
+
* - Package version metadata (p2/{vendor}/{package}.json)
|
|
15
|
+
* - Dist file (zip) proxying
|
|
16
|
+
* - Packagist v2 API support
|
|
17
|
+
*/
|
|
18
|
+
export class ComposerUpstream extends BaseUpstream {
|
|
19
|
+
protected readonly protocolName = 'composer';
|
|
20
|
+
|
|
21
|
+
constructor(
|
|
22
|
+
config: IProtocolUpstreamConfig,
|
|
23
|
+
logger?: plugins.smartlog.Smartlog,
|
|
24
|
+
) {
|
|
25
|
+
super(config, logger);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Fetch the root packages.json from upstream.
|
|
30
|
+
*/
|
|
31
|
+
public async fetchPackagesJson(): Promise<any | null> {
|
|
32
|
+
const context: IUpstreamFetchContext = {
|
|
33
|
+
protocol: 'composer',
|
|
34
|
+
resource: '*',
|
|
35
|
+
resourceType: 'root',
|
|
36
|
+
path: '/packages.json',
|
|
37
|
+
method: 'GET',
|
|
38
|
+
headers: {
|
|
39
|
+
'accept': 'application/json',
|
|
40
|
+
},
|
|
41
|
+
query: {},
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const result = await this.fetch(context);
|
|
45
|
+
|
|
46
|
+
if (!result || !result.success) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (Buffer.isBuffer(result.body)) {
|
|
51
|
+
return JSON.parse(result.body.toString('utf8'));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return result.body;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Fetch package metadata using v2 API (p2/{vendor}/{package}.json).
|
|
59
|
+
*/
|
|
60
|
+
public async fetchPackageMetadata(vendor: string, packageName: string): Promise<any | null> {
|
|
61
|
+
const fullName = `${vendor}/${packageName}`;
|
|
62
|
+
const path = `/p2/${vendor}/${packageName}.json`;
|
|
63
|
+
|
|
64
|
+
const context: IUpstreamFetchContext = {
|
|
65
|
+
protocol: 'composer',
|
|
66
|
+
resource: fullName,
|
|
67
|
+
resourceType: 'metadata',
|
|
68
|
+
path,
|
|
69
|
+
method: 'GET',
|
|
70
|
+
headers: {
|
|
71
|
+
'accept': 'application/json',
|
|
72
|
+
},
|
|
73
|
+
query: {},
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const result = await this.fetch(context);
|
|
77
|
+
|
|
78
|
+
if (!result || !result.success) {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (Buffer.isBuffer(result.body)) {
|
|
83
|
+
return JSON.parse(result.body.toString('utf8'));
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return result.body;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Fetch package metadata with dev versions (p2/{vendor}/{package}~dev.json).
|
|
91
|
+
*/
|
|
92
|
+
public async fetchPackageDevMetadata(vendor: string, packageName: string): Promise<any | null> {
|
|
93
|
+
const fullName = `${vendor}/${packageName}`;
|
|
94
|
+
const path = `/p2/${vendor}/${packageName}~dev.json`;
|
|
95
|
+
|
|
96
|
+
const context: IUpstreamFetchContext = {
|
|
97
|
+
protocol: 'composer',
|
|
98
|
+
resource: fullName,
|
|
99
|
+
resourceType: 'metadata-dev',
|
|
100
|
+
path,
|
|
101
|
+
method: 'GET',
|
|
102
|
+
headers: {
|
|
103
|
+
'accept': 'application/json',
|
|
104
|
+
},
|
|
105
|
+
query: {},
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
const result = await this.fetch(context);
|
|
109
|
+
|
|
110
|
+
if (!result || !result.success) {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (Buffer.isBuffer(result.body)) {
|
|
115
|
+
return JSON.parse(result.body.toString('utf8'));
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return result.body;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Fetch a provider-includes file.
|
|
123
|
+
*/
|
|
124
|
+
public async fetchProviderIncludes(path: string): Promise<any | null> {
|
|
125
|
+
const context: IUpstreamFetchContext = {
|
|
126
|
+
protocol: 'composer',
|
|
127
|
+
resource: '*',
|
|
128
|
+
resourceType: 'provider',
|
|
129
|
+
path: path.startsWith('/') ? path : `/${path}`,
|
|
130
|
+
method: 'GET',
|
|
131
|
+
headers: {
|
|
132
|
+
'accept': 'application/json',
|
|
133
|
+
},
|
|
134
|
+
query: {},
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
const result = await this.fetch(context);
|
|
138
|
+
|
|
139
|
+
if (!result || !result.success) {
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (Buffer.isBuffer(result.body)) {
|
|
144
|
+
return JSON.parse(result.body.toString('utf8'));
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return result.body;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Fetch a dist file (zip) from upstream.
|
|
152
|
+
*/
|
|
153
|
+
public async fetchDist(url: string): Promise<Buffer | null> {
|
|
154
|
+
// Parse the URL to get the path
|
|
155
|
+
let path: string;
|
|
156
|
+
try {
|
|
157
|
+
const parsed = new URL(url);
|
|
158
|
+
path = parsed.pathname;
|
|
159
|
+
} catch {
|
|
160
|
+
path = url;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const context: IUpstreamFetchContext = {
|
|
164
|
+
protocol: 'composer',
|
|
165
|
+
resource: '*',
|
|
166
|
+
resourceType: 'dist',
|
|
167
|
+
path,
|
|
168
|
+
method: 'GET',
|
|
169
|
+
headers: {
|
|
170
|
+
'accept': 'application/zip, application/octet-stream',
|
|
171
|
+
},
|
|
172
|
+
query: {},
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
const result = await this.fetch(context);
|
|
176
|
+
|
|
177
|
+
if (!result || !result.success) {
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return Buffer.isBuffer(result.body) ? result.body : Buffer.from(result.body);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Override URL building for Composer-specific handling.
|
|
186
|
+
*/
|
|
187
|
+
protected buildUpstreamUrl(
|
|
188
|
+
upstream: IUpstreamRegistryConfig,
|
|
189
|
+
context: IUpstreamFetchContext,
|
|
190
|
+
): string {
|
|
191
|
+
let baseUrl = upstream.url;
|
|
192
|
+
|
|
193
|
+
// Remove trailing slash
|
|
194
|
+
if (baseUrl.endsWith('/')) {
|
|
195
|
+
baseUrl = baseUrl.slice(0, -1);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return `${baseUrl}${context.path}`;
|
|
199
|
+
}
|
|
200
|
+
}
|