@push.rocks/smartregistry 1.1.1 → 1.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.
Files changed (51) hide show
  1. package/dist_ts/00_commitinfo_data.js +1 -1
  2. package/dist_ts/cargo/classes.cargoregistry.d.ts +79 -0
  3. package/dist_ts/cargo/classes.cargoregistry.js +490 -0
  4. package/dist_ts/cargo/index.d.ts +5 -0
  5. package/dist_ts/cargo/index.js +6 -0
  6. package/dist_ts/cargo/interfaces.cargo.d.ts +160 -0
  7. package/dist_ts/cargo/interfaces.cargo.js +6 -0
  8. package/dist_ts/classes.smartregistry.d.ts +2 -2
  9. package/dist_ts/classes.smartregistry.js +50 -2
  10. package/dist_ts/composer/classes.composerregistry.d.ts +26 -0
  11. package/dist_ts/composer/classes.composerregistry.js +366 -0
  12. package/dist_ts/composer/helpers.composer.d.ts +35 -0
  13. package/dist_ts/composer/helpers.composer.js +120 -0
  14. package/dist_ts/composer/index.d.ts +7 -0
  15. package/dist_ts/composer/index.js +8 -0
  16. package/dist_ts/composer/interfaces.composer.d.ts +102 -0
  17. package/dist_ts/composer/interfaces.composer.js +6 -0
  18. package/dist_ts/core/classes.authmanager.d.ts +46 -1
  19. package/dist_ts/core/classes.authmanager.js +121 -12
  20. package/dist_ts/core/classes.registrystorage.d.ts +103 -0
  21. package/dist_ts/core/classes.registrystorage.js +253 -1
  22. package/dist_ts/core/interfaces.core.d.ts +4 -1
  23. package/dist_ts/index.d.ts +4 -1
  24. package/dist_ts/index.js +8 -2
  25. package/dist_ts/maven/classes.mavenregistry.d.ts +35 -0
  26. package/dist_ts/maven/classes.mavenregistry.js +407 -0
  27. package/dist_ts/maven/helpers.maven.d.ts +68 -0
  28. package/dist_ts/maven/helpers.maven.js +286 -0
  29. package/dist_ts/maven/index.d.ts +6 -0
  30. package/dist_ts/maven/index.js +7 -0
  31. package/dist_ts/maven/interfaces.maven.d.ts +116 -0
  32. package/dist_ts/maven/interfaces.maven.js +6 -0
  33. package/package.json +3 -2
  34. package/readme.md +288 -14
  35. package/ts/00_commitinfo_data.ts +1 -1
  36. package/ts/cargo/classes.cargoregistry.ts +604 -0
  37. package/ts/cargo/index.ts +6 -0
  38. package/ts/cargo/interfaces.cargo.ts +169 -0
  39. package/ts/classes.smartregistry.ts +56 -2
  40. package/ts/composer/classes.composerregistry.ts +475 -0
  41. package/ts/composer/helpers.composer.ts +139 -0
  42. package/ts/composer/index.ts +8 -0
  43. package/ts/composer/interfaces.composer.ts +111 -0
  44. package/ts/core/classes.authmanager.ts +145 -12
  45. package/ts/core/classes.registrystorage.ts +334 -0
  46. package/ts/core/interfaces.core.ts +4 -1
  47. package/ts/index.ts +10 -1
  48. package/ts/maven/classes.mavenregistry.ts +580 -0
  49. package/ts/maven/helpers.maven.ts +346 -0
  50. package/ts/maven/index.ts +7 -0
  51. package/ts/maven/interfaces.maven.ts +127 -0
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@push.rocks/smartregistry',
6
- version: '1.1.1',
6
+ version: '1.4.0',
7
7
  description: 'a registry for npm modules and oci images'
8
8
  };
9
9
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSwyQkFBMkI7SUFDakMsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLDJDQUEyQztDQUN6RCxDQUFBIn0=
@@ -0,0 +1,79 @@
1
+ import { BaseRegistry } from '../core/classes.baseregistry.js';
2
+ import { RegistryStorage } from '../core/classes.registrystorage.js';
3
+ import { AuthManager } from '../core/classes.authmanager.js';
4
+ import type { IRequestContext, IResponse, IAuthToken } from '../core/interfaces.core.js';
5
+ /**
6
+ * Cargo/crates.io registry implementation
7
+ * Implements the sparse HTTP-based protocol
8
+ * Spec: https://doc.rust-lang.org/cargo/reference/registry-index.html
9
+ */
10
+ export declare class CargoRegistry extends BaseRegistry {
11
+ private storage;
12
+ private authManager;
13
+ private basePath;
14
+ private registryUrl;
15
+ private logger;
16
+ constructor(storage: RegistryStorage, authManager: AuthManager, basePath?: string, registryUrl?: string);
17
+ init(): Promise<void>;
18
+ getBasePath(): string;
19
+ handleRequest(context: IRequestContext): Promise<IResponse>;
20
+ /**
21
+ * Check if token has permission for resource
22
+ */
23
+ protected checkPermission(token: IAuthToken | null, resource: string, action: string): Promise<boolean>;
24
+ /**
25
+ * Handle API requests (/api/v1/*)
26
+ */
27
+ private handleApiRequest;
28
+ /**
29
+ * Handle index file requests
30
+ * Paths: /1/{name}, /2/{name}, /3/{c}/{name}, /{p1}/{p2}/{name}
31
+ */
32
+ private handleIndexRequest;
33
+ /**
34
+ * Serve config.json
35
+ */
36
+ private handleConfigJson;
37
+ /**
38
+ * Serve index file for a crate
39
+ */
40
+ private handleIndexFile;
41
+ /**
42
+ * Parse binary publish request
43
+ * Format: [4 bytes JSON len][JSON][4 bytes crate len][.crate file]
44
+ */
45
+ private parsePublishRequest;
46
+ /**
47
+ * Handle crate publish
48
+ */
49
+ private handlePublish;
50
+ /**
51
+ * Handle crate download
52
+ */
53
+ private handleDownload;
54
+ /**
55
+ * Handle yank operation
56
+ */
57
+ private handleYank;
58
+ /**
59
+ * Handle unyank operation
60
+ */
61
+ private handleUnyank;
62
+ /**
63
+ * Handle yank/unyank operation
64
+ */
65
+ private handleYankOperation;
66
+ /**
67
+ * Handle search
68
+ */
69
+ private handleSearch;
70
+ /**
71
+ * Validate crate name
72
+ * Rules: lowercase alphanumeric + _ and -, length 1-64
73
+ */
74
+ private validateCrateName;
75
+ /**
76
+ * Create error response
77
+ */
78
+ private createError;
79
+ }
@@ -0,0 +1,490 @@
1
+ import { Smartlog } from '@push.rocks/smartlog';
2
+ import { BaseRegistry } from '../core/classes.baseregistry.js';
3
+ import { RegistryStorage } from '../core/classes.registrystorage.js';
4
+ import { AuthManager } from '../core/classes.authmanager.js';
5
+ /**
6
+ * Cargo/crates.io registry implementation
7
+ * Implements the sparse HTTP-based protocol
8
+ * Spec: https://doc.rust-lang.org/cargo/reference/registry-index.html
9
+ */
10
+ export class CargoRegistry extends BaseRegistry {
11
+ storage;
12
+ authManager;
13
+ basePath = '/cargo';
14
+ registryUrl;
15
+ logger;
16
+ constructor(storage, authManager, basePath = '/cargo', registryUrl = 'http://localhost:5000/cargo') {
17
+ super();
18
+ this.storage = storage;
19
+ this.authManager = authManager;
20
+ this.basePath = basePath;
21
+ this.registryUrl = registryUrl;
22
+ // Initialize logger
23
+ this.logger = new Smartlog({
24
+ logContext: {
25
+ company: 'push.rocks',
26
+ companyunit: 'smartregistry',
27
+ containerName: 'cargo-registry',
28
+ environment: process.env.NODE_ENV || 'development',
29
+ runtime: 'node',
30
+ zone: 'cargo'
31
+ }
32
+ });
33
+ this.logger.enableConsole();
34
+ }
35
+ async init() {
36
+ // Initialize config.json if not exists
37
+ const existingConfig = await this.storage.getCargoConfig();
38
+ if (!existingConfig) {
39
+ const config = {
40
+ dl: `${this.registryUrl}/api/v1/crates/{crate}/{version}/download`,
41
+ api: this.registryUrl,
42
+ };
43
+ await this.storage.putCargoConfig(config);
44
+ this.logger.log('info', 'Initialized Cargo registry config', { config });
45
+ }
46
+ }
47
+ getBasePath() {
48
+ return this.basePath;
49
+ }
50
+ async handleRequest(context) {
51
+ const path = context.path.replace(this.basePath, '');
52
+ // Extract token (Cargo uses Authorization header WITHOUT "Bearer" prefix)
53
+ const authHeader = context.headers['authorization'] || context.headers['Authorization'];
54
+ const token = authHeader ? await this.authManager.validateToken(authHeader, 'cargo') : null;
55
+ this.logger.log('debug', `handleRequest: ${context.method} ${path}`, {
56
+ method: context.method,
57
+ path,
58
+ hasAuth: !!token
59
+ });
60
+ // Config endpoint (required for sparse protocol)
61
+ if (path === '/config.json') {
62
+ return this.handleConfigJson();
63
+ }
64
+ // API endpoints
65
+ if (path.startsWith('/api/v1/')) {
66
+ return this.handleApiRequest(path, context, token);
67
+ }
68
+ // Index files (sparse protocol)
69
+ return this.handleIndexRequest(path);
70
+ }
71
+ /**
72
+ * Check if token has permission for resource
73
+ */
74
+ async checkPermission(token, resource, action) {
75
+ if (!token)
76
+ return false;
77
+ return this.authManager.authorize(token, `cargo:crate:${resource}`, action);
78
+ }
79
+ /**
80
+ * Handle API requests (/api/v1/*)
81
+ */
82
+ async handleApiRequest(path, context, token) {
83
+ // Publish: PUT /api/v1/crates/new
84
+ if (path === '/api/v1/crates/new' && context.method === 'PUT') {
85
+ return this.handlePublish(context.body, token);
86
+ }
87
+ // Download: GET /api/v1/crates/{crate}/{version}/download
88
+ const downloadMatch = path.match(/^\/api\/v1\/crates\/([^\/]+)\/([^\/]+)\/download$/);
89
+ if (downloadMatch && context.method === 'GET') {
90
+ return this.handleDownload(downloadMatch[1], downloadMatch[2]);
91
+ }
92
+ // Yank: DELETE /api/v1/crates/{crate}/{version}/yank
93
+ const yankMatch = path.match(/^\/api\/v1\/crates\/([^\/]+)\/([^\/]+)\/yank$/);
94
+ if (yankMatch && context.method === 'DELETE') {
95
+ return this.handleYank(yankMatch[1], yankMatch[2], token);
96
+ }
97
+ // Unyank: PUT /api/v1/crates/{crate}/{version}/unyank
98
+ const unyankMatch = path.match(/^\/api\/v1\/crates\/([^\/]+)\/([^\/]+)\/unyank$/);
99
+ if (unyankMatch && context.method === 'PUT') {
100
+ return this.handleUnyank(unyankMatch[1], unyankMatch[2], token);
101
+ }
102
+ // Search: GET /api/v1/crates?q={query}
103
+ if (path.startsWith('/api/v1/crates') && context.method === 'GET') {
104
+ const query = context.query?.q || '';
105
+ const perPage = parseInt(context.query?.per_page || '10', 10);
106
+ return this.handleSearch(query, perPage);
107
+ }
108
+ return {
109
+ status: 404,
110
+ headers: { 'Content-Type': 'application/json' },
111
+ body: this.createError('API endpoint not found'),
112
+ };
113
+ }
114
+ /**
115
+ * Handle index file requests
116
+ * Paths: /1/{name}, /2/{name}, /3/{c}/{name}, /{p1}/{p2}/{name}
117
+ */
118
+ async handleIndexRequest(path) {
119
+ // Parse index paths to extract crate name
120
+ const pathParts = path.split('/').filter(p => p);
121
+ let crateName = null;
122
+ if (pathParts.length === 2 && pathParts[0] === '1') {
123
+ // 1-character names: /1/{name}
124
+ crateName = pathParts[1];
125
+ }
126
+ else if (pathParts.length === 2 && pathParts[0] === '2') {
127
+ // 2-character names: /2/{name}
128
+ crateName = pathParts[1];
129
+ }
130
+ else if (pathParts.length === 3 && pathParts[0] === '3') {
131
+ // 3-character names: /3/{c}/{name}
132
+ crateName = pathParts[2];
133
+ }
134
+ else if (pathParts.length === 3) {
135
+ // 4+ character names: /{p1}/{p2}/{name}
136
+ crateName = pathParts[2];
137
+ }
138
+ if (!crateName) {
139
+ return {
140
+ status: 404,
141
+ headers: { 'Content-Type': 'text/plain' },
142
+ body: Buffer.from(''),
143
+ };
144
+ }
145
+ return this.handleIndexFile(crateName);
146
+ }
147
+ /**
148
+ * Serve config.json
149
+ */
150
+ async handleConfigJson() {
151
+ const config = await this.storage.getCargoConfig();
152
+ return {
153
+ status: 200,
154
+ headers: { 'Content-Type': 'application/json' },
155
+ body: config || {
156
+ dl: `${this.registryUrl}/api/v1/crates/{crate}/{version}/download`,
157
+ api: this.registryUrl,
158
+ },
159
+ };
160
+ }
161
+ /**
162
+ * Serve index file for a crate
163
+ */
164
+ async handleIndexFile(crateName) {
165
+ const index = await this.storage.getCargoIndex(crateName);
166
+ if (!index || index.length === 0) {
167
+ return {
168
+ status: 404,
169
+ headers: { 'Content-Type': 'text/plain' },
170
+ body: Buffer.from(''),
171
+ };
172
+ }
173
+ // Return newline-delimited JSON
174
+ const data = index.map(e => JSON.stringify(e)).join('\n') + '\n';
175
+ // Calculate ETag for caching
176
+ const crypto = await import('crypto');
177
+ const etag = `"${crypto.createHash('sha256').update(data).digest('hex')}"`;
178
+ return {
179
+ status: 200,
180
+ headers: {
181
+ 'Content-Type': 'text/plain',
182
+ 'ETag': etag,
183
+ },
184
+ body: Buffer.from(data, 'utf-8'),
185
+ };
186
+ }
187
+ /**
188
+ * Parse binary publish request
189
+ * Format: [4 bytes JSON len][JSON][4 bytes crate len][.crate file]
190
+ */
191
+ parsePublishRequest(body) {
192
+ let offset = 0;
193
+ // Read JSON length (4 bytes, u32 little-endian)
194
+ if (body.length < 4) {
195
+ throw new Error('Invalid publish request: body too short');
196
+ }
197
+ const jsonLength = body.readUInt32LE(offset);
198
+ offset += 4;
199
+ // Read JSON metadata
200
+ if (body.length < offset + jsonLength) {
201
+ throw new Error('Invalid publish request: JSON data incomplete');
202
+ }
203
+ const jsonBuffer = body.slice(offset, offset + jsonLength);
204
+ const metadata = JSON.parse(jsonBuffer.toString('utf-8'));
205
+ offset += jsonLength;
206
+ // Read crate file length (4 bytes, u32 little-endian)
207
+ if (body.length < offset + 4) {
208
+ throw new Error('Invalid publish request: crate length missing');
209
+ }
210
+ const crateLength = body.readUInt32LE(offset);
211
+ offset += 4;
212
+ // Read crate file
213
+ if (body.length < offset + crateLength) {
214
+ throw new Error('Invalid publish request: crate data incomplete');
215
+ }
216
+ const crateFile = body.slice(offset, offset + crateLength);
217
+ return { metadata, crateFile };
218
+ }
219
+ /**
220
+ * Handle crate publish
221
+ */
222
+ async handlePublish(body, token) {
223
+ this.logger.log('info', 'handlePublish: received publish request', {
224
+ bodyLength: body?.length || 0,
225
+ hasAuth: !!token
226
+ });
227
+ // Check authorization
228
+ if (!token) {
229
+ return {
230
+ status: 403,
231
+ headers: { 'Content-Type': 'application/json' },
232
+ body: this.createError('Authentication required'),
233
+ };
234
+ }
235
+ // Parse binary request
236
+ let metadata;
237
+ let crateFile;
238
+ try {
239
+ const parsed = this.parsePublishRequest(body);
240
+ metadata = parsed.metadata;
241
+ crateFile = parsed.crateFile;
242
+ }
243
+ catch (error) {
244
+ this.logger.log('error', 'handlePublish: parse error', { error: error.message });
245
+ return {
246
+ status: 400,
247
+ headers: { 'Content-Type': 'application/json' },
248
+ body: this.createError(`Invalid request format: ${error.message}`),
249
+ };
250
+ }
251
+ // Validate crate name
252
+ if (!this.validateCrateName(metadata.name)) {
253
+ return {
254
+ status: 400,
255
+ headers: { 'Content-Type': 'application/json' },
256
+ body: this.createError('Invalid crate name'),
257
+ };
258
+ }
259
+ // Check permission
260
+ const hasPermission = await this.checkPermission(token, metadata.name, 'write');
261
+ if (!hasPermission) {
262
+ this.logger.log('warn', 'handlePublish: unauthorized', {
263
+ crateName: metadata.name,
264
+ userId: token.userId
265
+ });
266
+ return {
267
+ status: 403,
268
+ headers: { 'Content-Type': 'application/json' },
269
+ body: this.createError('Insufficient permissions'),
270
+ };
271
+ }
272
+ // Calculate SHA256 checksum
273
+ const crypto = await import('crypto');
274
+ const cksum = crypto.createHash('sha256').update(crateFile).digest('hex');
275
+ // Create index entry
276
+ const indexEntry = {
277
+ name: metadata.name,
278
+ vers: metadata.vers,
279
+ deps: metadata.deps,
280
+ cksum,
281
+ features: metadata.features,
282
+ yanked: false,
283
+ links: metadata.links || null,
284
+ v: 2,
285
+ rust_version: metadata.rust_version,
286
+ };
287
+ // Check for duplicate version
288
+ const existingIndex = await this.storage.getCargoIndex(metadata.name) || [];
289
+ if (existingIndex.some(e => e.vers === metadata.vers)) {
290
+ return {
291
+ status: 400,
292
+ headers: { 'Content-Type': 'application/json' },
293
+ body: this.createError(`Version ${metadata.vers} already exists`),
294
+ };
295
+ }
296
+ // Store crate file
297
+ await this.storage.putCargoCrate(metadata.name, metadata.vers, crateFile);
298
+ // Update index (append new version)
299
+ existingIndex.push(indexEntry);
300
+ await this.storage.putCargoIndex(metadata.name, existingIndex);
301
+ this.logger.log('success', 'handlePublish: published crate', {
302
+ name: metadata.name,
303
+ version: metadata.vers,
304
+ checksum: cksum
305
+ });
306
+ const response = {
307
+ warnings: {
308
+ invalid_categories: [],
309
+ invalid_badges: [],
310
+ other: [],
311
+ },
312
+ };
313
+ return {
314
+ status: 200,
315
+ headers: { 'Content-Type': 'application/json' },
316
+ body: response,
317
+ };
318
+ }
319
+ /**
320
+ * Handle crate download
321
+ */
322
+ async handleDownload(crateName, version) {
323
+ this.logger.log('debug', 'handleDownload', { crate: crateName, version });
324
+ const crateFile = await this.storage.getCargoCrate(crateName, version);
325
+ if (!crateFile) {
326
+ return {
327
+ status: 404,
328
+ headers: { 'Content-Type': 'application/json' },
329
+ body: this.createError('Crate not found'),
330
+ };
331
+ }
332
+ return {
333
+ status: 200,
334
+ headers: {
335
+ 'Content-Type': 'application/gzip',
336
+ 'Content-Length': crateFile.length.toString(),
337
+ 'Content-Disposition': `attachment; filename="${crateName}-${version}.crate"`,
338
+ },
339
+ body: crateFile,
340
+ };
341
+ }
342
+ /**
343
+ * Handle yank operation
344
+ */
345
+ async handleYank(crateName, version, token) {
346
+ return this.handleYankOperation(crateName, version, token, true);
347
+ }
348
+ /**
349
+ * Handle unyank operation
350
+ */
351
+ async handleUnyank(crateName, version, token) {
352
+ return this.handleYankOperation(crateName, version, token, false);
353
+ }
354
+ /**
355
+ * Handle yank/unyank operation
356
+ */
357
+ async handleYankOperation(crateName, version, token, yank) {
358
+ this.logger.log('info', `handle${yank ? 'Yank' : 'Unyank'}`, {
359
+ crate: crateName,
360
+ version,
361
+ hasAuth: !!token
362
+ });
363
+ // Check authorization
364
+ if (!token) {
365
+ return {
366
+ status: 403,
367
+ headers: { 'Content-Type': 'application/json' },
368
+ body: this.createError('Authentication required'),
369
+ };
370
+ }
371
+ // Check permission
372
+ const hasPermission = await this.checkPermission(token, crateName, 'write');
373
+ if (!hasPermission) {
374
+ return {
375
+ status: 403,
376
+ headers: { 'Content-Type': 'application/json' },
377
+ body: this.createError('Insufficient permissions'),
378
+ };
379
+ }
380
+ // Load index
381
+ const index = await this.storage.getCargoIndex(crateName);
382
+ if (!index) {
383
+ return {
384
+ status: 404,
385
+ headers: { 'Content-Type': 'application/json' },
386
+ body: this.createError('Crate not found'),
387
+ };
388
+ }
389
+ // Find version
390
+ const entry = index.find(e => e.vers === version);
391
+ if (!entry) {
392
+ return {
393
+ status: 404,
394
+ headers: { 'Content-Type': 'application/json' },
395
+ body: this.createError('Version not found'),
396
+ };
397
+ }
398
+ // Update yank status
399
+ entry.yanked = yank;
400
+ // Save index (NOTE: do NOT delete .crate file)
401
+ await this.storage.putCargoIndex(crateName, index);
402
+ this.logger.log('success', `${yank ? 'Yanked' : 'Unyanked'} version`, {
403
+ crate: crateName,
404
+ version
405
+ });
406
+ const response = { ok: true };
407
+ return {
408
+ status: 200,
409
+ headers: { 'Content-Type': 'application/json' },
410
+ body: response,
411
+ };
412
+ }
413
+ /**
414
+ * Handle search
415
+ */
416
+ async handleSearch(query, perPage) {
417
+ this.logger.log('debug', 'handleSearch', { query, perPage });
418
+ const results = [];
419
+ try {
420
+ // List all index paths
421
+ const indexPaths = await this.storage.listObjects('cargo/index/');
422
+ // Extract unique crate names
423
+ const crateNames = new Set();
424
+ for (const path of indexPaths) {
425
+ // Parse path to extract crate name
426
+ const parts = path.split('/');
427
+ if (parts.length >= 3) {
428
+ const name = parts[parts.length - 1];
429
+ if (name && !name.includes('.')) {
430
+ crateNames.add(name);
431
+ }
432
+ }
433
+ }
434
+ this.logger.log('debug', `handleSearch: found ${crateNames.size} crates`, {
435
+ totalCrates: crateNames.size
436
+ });
437
+ // Filter and process matching crates
438
+ for (const name of crateNames) {
439
+ if (!query || name.toLowerCase().includes(query.toLowerCase())) {
440
+ const index = await this.storage.getCargoIndex(name);
441
+ if (index && index.length > 0) {
442
+ // Find latest non-yanked version
443
+ const nonYanked = index.filter(e => !e.yanked);
444
+ if (nonYanked.length > 0) {
445
+ // Sort by version (simplified - should use semver)
446
+ const sorted = [...nonYanked].sort((a, b) => b.vers.localeCompare(a.vers));
447
+ results.push({
448
+ name: sorted[0].name,
449
+ max_version: sorted[0].vers,
450
+ description: '', // Would need to store separately
451
+ });
452
+ if (results.length >= perPage)
453
+ break;
454
+ }
455
+ }
456
+ }
457
+ }
458
+ }
459
+ catch (error) {
460
+ this.logger.log('error', 'handleSearch: error', { error: error.message });
461
+ }
462
+ const response = {
463
+ crates: results,
464
+ meta: {
465
+ total: results.length,
466
+ },
467
+ };
468
+ return {
469
+ status: 200,
470
+ headers: { 'Content-Type': 'application/json' },
471
+ body: response,
472
+ };
473
+ }
474
+ /**
475
+ * Validate crate name
476
+ * Rules: lowercase alphanumeric + _ and -, length 1-64
477
+ */
478
+ validateCrateName(name) {
479
+ return /^[a-z0-9_-]+$/.test(name) && name.length >= 1 && name.length <= 64;
480
+ }
481
+ /**
482
+ * Create error response
483
+ */
484
+ createError(detail) {
485
+ return {
486
+ errors: [{ detail }],
487
+ };
488
+ }
489
+ }
490
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5jYXJnb3JlZ2lzdHJ5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvY2FyZ28vY2xhc3Nlcy5jYXJnb3JlZ2lzdHJ5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNoRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDL0QsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBQ3JFLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQWE3RDs7OztHQUlHO0FBQ0gsTUFBTSxPQUFPLGFBQWMsU0FBUSxZQUFZO0lBQ3JDLE9BQU8sQ0FBa0I7SUFDekIsV0FBVyxDQUFjO0lBQ3pCLFFBQVEsR0FBVyxRQUFRLENBQUM7SUFDNUIsV0FBVyxDQUFTO0lBQ3BCLE1BQU0sQ0FBVztJQUV6QixZQUNFLE9BQXdCLEVBQ3hCLFdBQXdCLEVBQ3hCLFdBQW1CLFFBQVEsRUFDM0IsY0FBc0IsNkJBQTZCO1FBRW5ELEtBQUssRUFBRSxDQUFDO1FBQ1IsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7UUFDdkIsSUFBSSxDQUFDLFdBQVcsR0FBRyxXQUFXLENBQUM7UUFDL0IsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7UUFDekIsSUFBSSxDQUFDLFdBQVcsR0FBRyxXQUFXLENBQUM7UUFFL0Isb0JBQW9CO1FBQ3BCLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxRQUFRLENBQUM7WUFDekIsVUFBVSxFQUFFO2dCQUNWLE9BQU8sRUFBRSxZQUFZO2dCQUNyQixXQUFXLEVBQUUsZUFBZTtnQkFDNUIsYUFBYSxFQUFFLGdCQUFnQjtnQkFDL0IsV0FBVyxFQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsUUFBZ0IsSUFBSSxhQUFhO2dCQUMzRCxPQUFPLEVBQUUsTUFBTTtnQkFDZixJQUFJLEVB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
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Cargo/crates.io Registry module exports
3
+ */
4
+ export { CargoRegistry } from './classes.cargoregistry.js';
5
+ export * from './interfaces.cargo.js';
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Cargo/crates.io Registry module exports
3
+ */
4
+ export { CargoRegistry } from './classes.cargoregistry.js';
5
+ export * from './interfaces.cargo.js';
6
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9jYXJnby9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUVILE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUMzRCxjQUFjLHVCQUF1QixDQUFDIn0=