@push.rocks/smartregistry 1.1.1

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 (52) hide show
  1. package/dist_ts/00_commitinfo_data.d.ts +8 -0
  2. package/dist_ts/00_commitinfo_data.js +9 -0
  3. package/dist_ts/classes.smartregistry.d.ts +45 -0
  4. package/dist_ts/classes.smartregistry.js +113 -0
  5. package/dist_ts/core/classes.authmanager.d.ts +108 -0
  6. package/dist_ts/core/classes.authmanager.js +315 -0
  7. package/dist_ts/core/classes.baseregistry.d.ts +28 -0
  8. package/dist_ts/core/classes.baseregistry.js +6 -0
  9. package/dist_ts/core/classes.registrystorage.d.ts +109 -0
  10. package/dist_ts/core/classes.registrystorage.js +226 -0
  11. package/dist_ts/core/index.d.ts +7 -0
  12. package/dist_ts/core/index.js +10 -0
  13. package/dist_ts/core/interfaces.core.d.ts +142 -0
  14. package/dist_ts/core/interfaces.core.js +5 -0
  15. package/dist_ts/index.d.ts +8 -0
  16. package/dist_ts/index.js +13 -0
  17. package/dist_ts/npm/classes.npmregistry.d.ts +36 -0
  18. package/dist_ts/npm/classes.npmregistry.js +717 -0
  19. package/dist_ts/npm/index.d.ts +5 -0
  20. package/dist_ts/npm/index.js +6 -0
  21. package/dist_ts/npm/interfaces.npm.d.ts +245 -0
  22. package/dist_ts/npm/interfaces.npm.js +6 -0
  23. package/dist_ts/oci/classes.ociregistry.d.ts +43 -0
  24. package/dist_ts/oci/classes.ociregistry.js +565 -0
  25. package/dist_ts/oci/index.d.ts +5 -0
  26. package/dist_ts/oci/index.js +6 -0
  27. package/dist_ts/oci/interfaces.oci.d.ts +103 -0
  28. package/dist_ts/oci/interfaces.oci.js +5 -0
  29. package/dist_ts/paths.d.ts +1 -0
  30. package/dist_ts/paths.js +3 -0
  31. package/dist_ts/plugins.d.ts +6 -0
  32. package/dist_ts/plugins.js +9 -0
  33. package/npmextra.json +18 -0
  34. package/package.json +49 -0
  35. package/readme.hints.md +3 -0
  36. package/readme.md +486 -0
  37. package/ts/00_commitinfo_data.ts +8 -0
  38. package/ts/classes.smartregistry.ts +129 -0
  39. package/ts/core/classes.authmanager.ts +388 -0
  40. package/ts/core/classes.baseregistry.ts +36 -0
  41. package/ts/core/classes.registrystorage.ts +270 -0
  42. package/ts/core/index.ts +11 -0
  43. package/ts/core/interfaces.core.ts +159 -0
  44. package/ts/index.ts +16 -0
  45. package/ts/npm/classes.npmregistry.ts +890 -0
  46. package/ts/npm/index.ts +6 -0
  47. package/ts/npm/interfaces.npm.ts +263 -0
  48. package/ts/oci/classes.ociregistry.ts +734 -0
  49. package/ts/oci/index.ts +6 -0
  50. package/ts/oci/interfaces.oci.ts +101 -0
  51. package/ts/paths.ts +5 -0
  52. package/ts/plugins.ts +11 -0
@@ -0,0 +1,103 @@
1
+ /**
2
+ * OCI Distribution Specification specific interfaces
3
+ */
4
+ /**
5
+ * OCI manifest structure
6
+ */
7
+ export interface IOciManifest {
8
+ schemaVersion: number;
9
+ mediaType: string;
10
+ config: {
11
+ mediaType: string;
12
+ size: number;
13
+ digest: string;
14
+ };
15
+ layers: Array<{
16
+ mediaType: string;
17
+ size: number;
18
+ digest: string;
19
+ urls?: string[];
20
+ }>;
21
+ subject?: {
22
+ mediaType: string;
23
+ size: number;
24
+ digest: string;
25
+ };
26
+ annotations?: {
27
+ [key: string]: string;
28
+ };
29
+ }
30
+ /**
31
+ * OCI Image Index (manifest list)
32
+ */
33
+ export interface IOciImageIndex {
34
+ schemaVersion: number;
35
+ mediaType: string;
36
+ manifests: Array<{
37
+ mediaType: string;
38
+ size: number;
39
+ digest: string;
40
+ platform?: {
41
+ architecture: string;
42
+ os: string;
43
+ 'os.version'?: string;
44
+ 'os.features'?: string[];
45
+ variant?: string;
46
+ features?: string[];
47
+ };
48
+ annotations?: {
49
+ [key: string]: string;
50
+ };
51
+ }>;
52
+ subject?: {
53
+ mediaType: string;
54
+ size: number;
55
+ digest: string;
56
+ };
57
+ annotations?: {
58
+ [key: string]: string;
59
+ };
60
+ }
61
+ /**
62
+ * Upload session for chunked blob uploads
63
+ */
64
+ export interface IUploadSession {
65
+ uploadId: string;
66
+ repository: string;
67
+ chunks: Buffer[];
68
+ totalSize: number;
69
+ createdAt: Date;
70
+ lastActivity: Date;
71
+ }
72
+ /**
73
+ * Tag list response
74
+ */
75
+ export interface ITagList {
76
+ name: string;
77
+ tags: string[];
78
+ }
79
+ /**
80
+ * Referrers response
81
+ */
82
+ export interface IReferrersResponse {
83
+ schemaVersion: number;
84
+ mediaType: string;
85
+ manifests: Array<{
86
+ mediaType: string;
87
+ size: number;
88
+ digest: string;
89
+ artifactType?: string;
90
+ annotations?: {
91
+ [key: string]: string;
92
+ };
93
+ }>;
94
+ }
95
+ /**
96
+ * Pagination options for listing
97
+ */
98
+ export interface IPaginationOptions {
99
+ /** Maximum number of results to return */
100
+ n?: number;
101
+ /** Last entry from previous request */
102
+ last?: string;
103
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * OCI Distribution Specification specific interfaces
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJmYWNlcy5vY2kuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9vY2kvaW50ZXJmYWNlcy5vY2kudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUcifQ==
@@ -0,0 +1 @@
1
+ export declare const packageDir: string;
@@ -0,0 +1,3 @@
1
+ import * as plugins from './plugins.js';
2
+ export const packageDir = plugins.path.join(plugins.smartpath.get.dirnameFromImportMetaUrl(import.meta.url), '../');
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGF0aHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9wYXRocy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUN4QyxNQUFNLENBQUMsTUFBTSxVQUFVLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQ3pDLE9BQU8sQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLHdCQUF3QixDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQy9ELEtBQUssQ0FDTixDQUFDIn0=
@@ -0,0 +1,6 @@
1
+ import * as path from 'path';
2
+ export { path };
3
+ import * as smartbucket from '@push.rocks/smartbucket';
4
+ import * as smartlog from '@push.rocks/smartlog';
5
+ import * as smartpath from '@push.rocks/smartpath';
6
+ export { smartbucket, smartlog, smartpath };
@@ -0,0 +1,9 @@
1
+ // native scope
2
+ import * as path from 'path';
3
+ export { path };
4
+ // @push.rocks scope
5
+ import * as smartbucket from '@push.rocks/smartbucket';
6
+ import * as smartlog from '@push.rocks/smartlog';
7
+ import * as smartpath from '@push.rocks/smartpath';
8
+ export { smartbucket, smartlog, smartpath };
9
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3BsdWdpbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsZUFBZTtBQUNmLE9BQU8sS0FBSyxJQUFJLE1BQU0sTUFBTSxDQUFDO0FBRTdCLE9BQU8sRUFBRSxJQUFJLEVBQUUsQ0FBQztBQUVoQixvQkFBb0I7QUFDcEIsT0FBTyxLQUFLLFdBQVcsTUFBTSx5QkFBeUIsQ0FBQztBQUN2RCxPQUFPLEtBQUssUUFBUSxNQUFNLHNCQUFzQixDQUFDO0FBQ2pELE9BQU8sS0FBSyxTQUFTLE1BQU0sdUJBQXVCLENBQUM7QUFFbkQsT0FBTyxFQUFFLFdBQVcsRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLENBQUMifQ==
package/npmextra.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "gitzone": {
3
+ "projectType": "npm",
4
+ "module": {
5
+ "githost": "code.foss.global",
6
+ "gitscope": "push.rocks",
7
+ "gitrepo": "smartregistry",
8
+ "description": "a registry for npm modules and oci images",
9
+ "npmPackagename": "@push.rocks/smartregistry",
10
+ "license": "MIT",
11
+ "projectDomain": "push.rocks"
12
+ }
13
+ },
14
+ "npmci": {
15
+ "npmGlobalTools": [],
16
+ "npmAccessLevel": "public"
17
+ }
18
+ }
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@push.rocks/smartregistry",
3
+ "version": "1.1.1",
4
+ "private": false,
5
+ "description": "a registry for npm modules and oci images",
6
+ "main": "dist_ts/index.js",
7
+ "typings": "dist_ts/index.d.ts",
8
+ "type": "module",
9
+ "author": "Task Venture Capital GmbH",
10
+ "license": "MIT",
11
+ "devDependencies": {
12
+ "@git.zone/tsbuild": "^3.1.0",
13
+ "@git.zone/tsbundle": "^2.0.5",
14
+ "@git.zone/tsrun": "^2.0.0",
15
+ "@git.zone/tstest": "^3.1.0",
16
+ "@types/node": "^24.10.1"
17
+ },
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "https://code.foss.global/push.rocks/smartregistry.git"
21
+ },
22
+ "bugs": {
23
+ "url": "https://code.foss.global/push.rocks/smartregistry/issues"
24
+ },
25
+ "homepage": "https://code.foss.global/push.rocks/smartregistry#readme",
26
+ "files": [
27
+ "ts/**/*",
28
+ "ts_web/**/*",
29
+ "dist/**/*",
30
+ "dist_*/**/*",
31
+ "dist_ts/**/*",
32
+ "dist_ts_web/**/*",
33
+ "assets/**/*",
34
+ "cli.js",
35
+ "npmextra.json",
36
+ "readme.md"
37
+ ],
38
+ "dependencies": {
39
+ "@push.rocks/qenv": "^6.1.3",
40
+ "@push.rocks/smartbucket": "^4.3.0",
41
+ "@push.rocks/smartlog": "^3.1.10",
42
+ "@push.rocks/smartpath": "^6.0.0"
43
+ },
44
+ "scripts": {
45
+ "test": "(tstest test/ --verbose --logfile --timeout 240)",
46
+ "build": "(tsbuild --web --allowimplicitany)",
47
+ "buildDocs": "(tsdoc)"
48
+ }
49
+ }
@@ -0,0 +1,3 @@
1
+ # Project Readme Hints
2
+
3
+ This is the initial readme hints file.
package/readme.md ADDED
@@ -0,0 +1,486 @@
1
+ # @push.rocks/smartregistry
2
+
3
+ > 🚀 A composable TypeScript library implementing both **OCI Distribution Specification v1.1** and **NPM Registry API** for building unified container and package registries.
4
+
5
+ ## ✨ Features
6
+
7
+ ### 🔄 Dual Protocol Support
8
+ - **OCI Distribution Spec v1.1**: Full container registry with manifest/blob operations
9
+ - **NPM Registry API**: Complete package registry with publish/install/search
10
+
11
+ ### 🏗️ Unified Architecture
12
+ - **Composable Design**: Core infrastructure with protocol plugins
13
+ - **Shared Storage**: Cloud-agnostic S3-compatible backend ([@push.rocks/smartbucket](https://www.npmjs.com/package/@push.rocks/smartbucket))
14
+ - **Unified Authentication**: Scope-based permissions across both protocols
15
+ - **Path-based Routing**: `/oci/*` for containers, `/npm/*` for packages
16
+
17
+ ### 🔐 Authentication & Authorization
18
+ - NPM UUID tokens for package operations
19
+ - OCI JWT tokens for container operations
20
+ - Unified scope system: `npm:package:foo:write`, `oci:repository:bar:push`
21
+ - Pluggable via async callbacks
22
+
23
+ ### 📦 Comprehensive Feature Set
24
+
25
+ **OCI Features:**
26
+ - ✅ Pull operations (manifests, blobs)
27
+ - ✅ Push operations (chunked uploads)
28
+ - ✅ Content discovery (tags, referrers API)
29
+ - ✅ Content management (deletion)
30
+
31
+ **NPM Features:**
32
+ - ✅ Package publish/unpublish
33
+ - ✅ Package download (tarballs)
34
+ - ✅ Metadata & search
35
+ - ✅ Dist-tag management
36
+ - ✅ Token management
37
+
38
+ ## 📥 Installation
39
+
40
+ ```bash
41
+ # Using npm
42
+ npm install @push.rocks/smartregistry
43
+
44
+ # Using pnpm (recommended)
45
+ pnpm add @push.rocks/smartregistry
46
+ ```
47
+
48
+ ## 🚀 Quick Start
49
+
50
+ ```typescript
51
+ import { SmartRegistry, IRegistryConfig } from '@push.rocks/smartregistry';
52
+
53
+ const config: IRegistryConfig = {
54
+ storage: {
55
+ accessKey: 'your-s3-key',
56
+ accessSecret: 'your-s3-secret',
57
+ endpoint: 's3.amazonaws.com',
58
+ port: 443,
59
+ useSsl: true,
60
+ region: 'us-east-1',
61
+ bucketName: 'my-registry',
62
+ },
63
+ auth: {
64
+ jwtSecret: 'your-secret-key',
65
+ tokenStore: 'memory',
66
+ npmTokens: { enabled: true },
67
+ ociTokens: {
68
+ enabled: true,
69
+ realm: 'https://auth.example.com/token',
70
+ service: 'my-registry',
71
+ },
72
+ },
73
+ oci: {
74
+ enabled: true,
75
+ basePath: '/oci',
76
+ },
77
+ npm: {
78
+ enabled: true,
79
+ basePath: '/npm',
80
+ },
81
+ };
82
+
83
+ const registry = new SmartRegistry(config);
84
+ await registry.init();
85
+
86
+ // Handle requests
87
+ const response = await registry.handleRequest({
88
+ method: 'GET',
89
+ path: '/npm/express',
90
+ headers: {},
91
+ query: {},
92
+ });
93
+ ```
94
+
95
+ ## 🏛️ Architecture
96
+
97
+ ### Directory Structure
98
+
99
+ ```
100
+ ts/
101
+ ├── core/ # Shared infrastructure
102
+ │ ├── classes.baseregistry.ts
103
+ │ ├── classes.registrystorage.ts
104
+ │ ├── classes.authmanager.ts
105
+ │ └── interfaces.core.ts
106
+ ├── oci/ # OCI implementation
107
+ │ ├── classes.ociregistry.ts
108
+ │ └── interfaces.oci.ts
109
+ ├── npm/ # NPM implementation
110
+ │ ├── classes.npmregistry.ts
111
+ │ └── interfaces.npm.ts
112
+ └── classes.smartregistry.ts # Main orchestrator
113
+ ```
114
+
115
+ ### Request Flow
116
+
117
+ ```
118
+ HTTP Request
119
+
120
+ SmartRegistry (orchestrator)
121
+
122
+ Path-based routing
123
+ ├─→ /oci/* → OciRegistry
124
+ └─→ /npm/* → NpmRegistry
125
+
126
+ Shared Storage & Auth
127
+
128
+ S3-compatible backend
129
+ ```
130
+
131
+ ## 💡 Usage Examples
132
+
133
+ ### 🐳 OCI Registry (Container Images)
134
+
135
+ ```typescript
136
+ // Pull an image
137
+ const response = await registry.handleRequest({
138
+ method: 'GET',
139
+ path: '/oci/v2/library/nginx/manifests/latest',
140
+ headers: {
141
+ 'Authorization': 'Bearer <token>',
142
+ },
143
+ query: {},
144
+ });
145
+
146
+ // Push a blob
147
+ const uploadInit = await registry.handleRequest({
148
+ method: 'POST',
149
+ path: '/oci/v2/myapp/blobs/uploads/',
150
+ headers: { 'Authorization': 'Bearer <token>' },
151
+ query: {},
152
+ });
153
+
154
+ const uploadId = uploadInit.headers['Docker-Upload-UUID'];
155
+
156
+ await registry.handleRequest({
157
+ method: 'PUT',
158
+ path: `/oci/v2/myapp/blobs/uploads/${uploadId}`,
159
+ headers: { 'Authorization': 'Bearer <token>' },
160
+ query: { digest: 'sha256:abc123...' },
161
+ body: blobData,
162
+ });
163
+ ```
164
+
165
+ ### 📦 NPM Registry (Packages)
166
+
167
+ ```typescript
168
+ // Install a package (get metadata)
169
+ const metadata = await registry.handleRequest({
170
+ method: 'GET',
171
+ path: '/npm/express',
172
+ headers: {},
173
+ query: {},
174
+ });
175
+
176
+ // Download tarball
177
+ const tarball = await registry.handleRequest({
178
+ method: 'GET',
179
+ path: '/npm/express/-/express-4.18.0.tgz',
180
+ headers: {},
181
+ query: {},
182
+ });
183
+
184
+ // Publish a package
185
+ const publishResponse = await registry.handleRequest({
186
+ method: 'PUT',
187
+ path: '/npm/my-package',
188
+ headers: { 'Authorization': 'Bearer <npm-token>' },
189
+ query: {},
190
+ body: {
191
+ name: 'my-package',
192
+ versions: {
193
+ '1.0.0': { /* version metadata */ },
194
+ },
195
+ 'dist-tags': { latest: '1.0.0' },
196
+ _attachments: {
197
+ 'my-package-1.0.0.tgz': {
198
+ content_type: 'application/octet-stream',
199
+ data: '<base64-tarball>',
200
+ length: 12345,
201
+ },
202
+ },
203
+ },
204
+ });
205
+
206
+ // Search packages
207
+ const searchResults = await registry.handleRequest({
208
+ method: 'GET',
209
+ path: '/npm/-/v1/search',
210
+ headers: {},
211
+ query: { text: 'express', size: '20' },
212
+ });
213
+ ```
214
+
215
+ ### 🔐 Authentication
216
+
217
+ ```typescript
218
+ // Get auth manager instance
219
+ const authManager = registry.getAuthManager();
220
+
221
+ // Authenticate user
222
+ const userId = await authManager.authenticate({
223
+ username: 'user',
224
+ password: 'pass',
225
+ });
226
+
227
+ // Create NPM token
228
+ const npmToken = await authManager.createNpmToken(userId, false);
229
+
230
+ // Create OCI token with scopes
231
+ const ociToken = await authManager.createOciToken(
232
+ userId,
233
+ ['oci:repository:myapp:push', 'oci:repository:myapp:pull'],
234
+ 3600
235
+ );
236
+
237
+ // Validate any token
238
+ const token = await authManager.validateToken(npmToken, 'npm');
239
+
240
+ // Check permissions
241
+ const canWrite = await authManager.authorize(
242
+ token,
243
+ 'npm:package:my-package',
244
+ 'write'
245
+ );
246
+ ```
247
+
248
+ ## ⚙️ Configuration
249
+
250
+ ### Storage Configuration
251
+
252
+ ```typescript
253
+ storage: {
254
+ accessKey: string; // S3 access key
255
+ accessSecret: string; // S3 secret key
256
+ endpoint: string; // S3 endpoint
257
+ port?: number; // Default: 443
258
+ useSsl?: boolean; // Default: true
259
+ region?: string; // Default: 'us-east-1'
260
+ bucketName: string; // Bucket name
261
+ }
262
+ ```
263
+
264
+ ### Authentication Configuration
265
+
266
+ ```typescript
267
+ auth: {
268
+ jwtSecret: string; // Secret for signing JWTs
269
+ tokenStore: 'memory' | 'redis' | 'database';
270
+ npmTokens: {
271
+ enabled: boolean;
272
+ defaultReadonly?: boolean;
273
+ };
274
+ ociTokens: {
275
+ enabled: boolean;
276
+ realm: string; // Auth server URL
277
+ service: string; // Service name
278
+ };
279
+ }
280
+ ```
281
+
282
+ ### Protocol Configuration
283
+
284
+ ```typescript
285
+ oci?: {
286
+ enabled: boolean;
287
+ basePath: string; // Default: '/oci'
288
+ features?: {
289
+ referrers?: boolean;
290
+ deletion?: boolean;
291
+ };
292
+ }
293
+
294
+ npm?: {
295
+ enabled: boolean;
296
+ basePath: string; // Default: '/npm'
297
+ features?: {
298
+ publish?: boolean;
299
+ unpublish?: boolean;
300
+ search?: boolean;
301
+ };
302
+ }
303
+ ```
304
+
305
+ ## 📚 API Reference
306
+
307
+ ### Core Classes
308
+
309
+ #### SmartRegistry
310
+
311
+ Main orchestrator class that routes requests to appropriate protocol handlers.
312
+
313
+ **Methods:**
314
+ - `init()` - Initialize the registry
315
+ - `handleRequest(context)` - Handle HTTP request
316
+ - `getStorage()` - Get storage instance
317
+ - `getAuthManager()` - Get auth manager
318
+ - `getRegistry(protocol)` - Get protocol handler
319
+
320
+ #### RegistryStorage
321
+
322
+ Unified storage abstraction for both OCI and NPM content.
323
+
324
+ **OCI Methods:**
325
+ - `getOciBlob(digest)` - Get blob
326
+ - `putOciBlob(digest, data)` - Store blob
327
+ - `getOciManifest(repo, digest)` - Get manifest
328
+ - `putOciManifest(repo, digest, data, type)` - Store manifest
329
+
330
+ **NPM Methods:**
331
+ - `getNpmPackument(name)` - Get package metadata
332
+ - `putNpmPackument(name, data)` - Store package metadata
333
+ - `getNpmTarball(name, version)` - Get tarball
334
+ - `putNpmTarball(name, version, data)` - Store tarball
335
+
336
+ #### AuthManager
337
+
338
+ Unified authentication manager supporting both NPM and OCI authentication schemes.
339
+
340
+ **Methods:**
341
+ - `authenticate(credentials)` - Validate user credentials
342
+ - `createNpmToken(userId, readonly)` - Create NPM token
343
+ - `createOciToken(userId, scopes, expiresIn)` - Create OCI JWT
344
+ - `validateToken(token, protocol)` - Validate any token
345
+ - `authorize(token, resource, action)` - Check permissions
346
+
347
+ ### Protocol Handlers
348
+
349
+ #### OciRegistry
350
+
351
+ OCI Distribution Specification v1.1 compliant registry.
352
+
353
+ **Endpoints:**
354
+ - `GET /v2/` - Version check
355
+ - `GET /v2/{name}/manifests/{ref}` - Get manifest
356
+ - `PUT /v2/{name}/manifests/{ref}` - Push manifest
357
+ - `GET /v2/{name}/blobs/{digest}` - Get blob
358
+ - `POST /v2/{name}/blobs/uploads/` - Initiate upload
359
+ - `PUT /v2/{name}/blobs/uploads/{uuid}` - Complete upload
360
+ - `GET /v2/{name}/tags/list` - List tags
361
+ - `GET /v2/{name}/referrers/{digest}` - Get referrers
362
+
363
+ #### NpmRegistry
364
+
365
+ NPM registry API compliant implementation.
366
+
367
+ **Endpoints:**
368
+ - `GET /{package}` - Get package metadata
369
+ - `PUT /{package}` - Publish package
370
+ - `GET /{package}/-/{tarball}` - Download tarball
371
+ - `GET /-/v1/search` - Search packages
372
+ - `PUT /-/user/org.couchdb.user:{user}` - Login
373
+ - `GET /-/npm/v1/tokens` - List tokens
374
+ - `POST /-/npm/v1/tokens` - Create token
375
+ - `PUT /-/package/{pkg}/dist-tags/{tag}` - Update tag
376
+
377
+ ## 🗄️ Storage Structure
378
+
379
+ ```
380
+ bucket/
381
+ ├── oci/
382
+ │ ├── blobs/
383
+ │ │ └── sha256/{hash}
384
+ │ ├── manifests/
385
+ │ │ └── {repository}/{digest}
386
+ │ └── tags/
387
+ │ └── {repository}/tags.json
388
+ └── npm/
389
+ ├── packages/
390
+ │ ├── {name}/
391
+ │ │ ├── index.json # Packument
392
+ │ │ └── {name}-{ver}.tgz # Tarball
393
+ │ └── @{scope}/{name}/
394
+ │ ├── index.json
395
+ │ └── {name}-{ver}.tgz
396
+ └── users/
397
+ └── {username}.json
398
+ ```
399
+
400
+ ## 🎯 Scope Format
401
+
402
+ Unified scope format across protocols:
403
+
404
+ ```
405
+ {protocol}:{type}:{name}:{action}
406
+
407
+ Examples:
408
+ npm:package:express:read # Read express package
409
+ npm:package:*:write # Write any package
410
+ npm:*:*:* # Full NPM access
411
+ oci:repository:nginx:pull # Pull nginx image
412
+ oci:repository:*:push # Push any image
413
+ oci:*:*:* # Full OCI access
414
+ ```
415
+
416
+ ## 🔌 Integration Examples
417
+
418
+ ### Express Server
419
+
420
+ ```typescript
421
+ import express from 'express';
422
+ import { SmartRegistry } from '@push.rocks/smartregistry';
423
+
424
+ const app = express();
425
+ const registry = new SmartRegistry(config);
426
+ await registry.init();
427
+
428
+ app.all('*', async (req, res) => {
429
+ const response = await registry.handleRequest({
430
+ method: req.method,
431
+ path: req.path,
432
+ headers: req.headers as Record<string, string>,
433
+ query: req.query as Record<string, string>,
434
+ body: req.body,
435
+ });
436
+
437
+ res.status(response.status);
438
+ Object.entries(response.headers).forEach(([key, value]) => {
439
+ res.setHeader(key, value);
440
+ });
441
+
442
+ if (response.body) {
443
+ if (Buffer.isBuffer(response.body)) {
444
+ res.send(response.body);
445
+ } else {
446
+ res.json(response.body);
447
+ }
448
+ } else {
449
+ res.end();
450
+ }
451
+ });
452
+
453
+ app.listen(5000);
454
+ ```
455
+
456
+ ## 🛠️ Development
457
+
458
+ ```bash
459
+ # Install dependencies
460
+ pnpm install
461
+
462
+ # Build
463
+ pnpm run build
464
+
465
+ # Test
466
+ pnpm test
467
+ ```
468
+
469
+ ## License and Legal Information
470
+
471
+ This repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository.
472
+
473
+ **Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
474
+
475
+ ### Trademarks
476
+
477
+ This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.
478
+
479
+ ### Company Information
480
+
481
+ Task Venture Capital GmbH
482
+ Registered at District court Bremen HRB 35230 HB, Germany
483
+
484
+ For any legal inquiries or if you require further information, please contact us via email at hello@task.vc.
485
+
486
+ By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.
@@ -0,0 +1,8 @@
1
+ /**
2
+ * autocreated commitinfo by @push.rocks/commitinfo
3
+ */
4
+ export const commitinfo = {
5
+ name: '@push.rocks/smartregistry',
6
+ version: '1.1.1',
7
+ description: 'a registry for npm modules and oci images'
8
+ }