@resourcexjs/server 2.5.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.
package/README.md ADDED
@@ -0,0 +1,264 @@
1
+ # @resourcexjs/server
2
+
3
+ ResourceX Registry Server - HTTP API server for hosting and serving ResourceX resources.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ bun add @resourcexjs/server
9
+ ```
10
+
11
+ ## Overview
12
+
13
+ This package provides three levels of abstraction for building a ResourceX registry server:
14
+
15
+ 1. **Hono Server** - Ready-to-use server with all endpoints configured
16
+ 2. **Handlers** - Framework-agnostic request handlers for custom integrations
17
+ 3. **Protocol** - Type definitions and constants for building clients
18
+
19
+ ## Quick Start
20
+
21
+ ```typescript
22
+ import { createRegistryServer } from "@resourcexjs/server";
23
+
24
+ const server = createRegistryServer({
25
+ storagePath: "./data",
26
+ });
27
+
28
+ // Bun
29
+ Bun.serve({ fetch: server.fetch, port: 3000 });
30
+
31
+ // Node.js (with @hono/node-server)
32
+ import { serve } from "@hono/node-server";
33
+ serve({ fetch: server.fetch, port: 3000 });
34
+ ```
35
+
36
+ ## API
37
+
38
+ ### `createRegistryServer(config?)`
39
+
40
+ Creates a Hono app with all registry endpoints configured.
41
+
42
+ ```typescript
43
+ interface RegistryServerConfig {
44
+ storagePath?: string; // Default: "./data"
45
+ basePath?: string; // Default: ""
46
+ cors?: boolean; // Default: true
47
+ }
48
+ ```
49
+
50
+ ### `createRegistry(config)`
51
+
52
+ Creates a registry instance for use with handlers.
53
+
54
+ ```typescript
55
+ import { createRegistry } from "@resourcexjs/server";
56
+
57
+ const registry = createRegistry({ storagePath: "./data" });
58
+ ```
59
+
60
+ ## Handlers
61
+
62
+ Framework-agnostic handlers for custom server integrations (Next.js, Express, etc.).
63
+
64
+ ```typescript
65
+ import {
66
+ handlePublish,
67
+ handleGetResource,
68
+ handleHeadResource,
69
+ handleDeleteResource,
70
+ handleGetContent,
71
+ handleSearch,
72
+ createRegistry,
73
+ } from "@resourcexjs/server";
74
+
75
+ const registry = createRegistry({ storagePath: "./data" });
76
+
77
+ // Next.js Route Handler example
78
+ export async function POST(request: Request) {
79
+ return handlePublish(request, registry);
80
+ }
81
+ ```
82
+
83
+ ### Handler Functions
84
+
85
+ | Handler | Description |
86
+ | ---------------------------------------------- | -------------------------------------- |
87
+ | `handlePublish(request, registry)` | Process multipart form publish request |
88
+ | `handleGetResource(locator, registry)` | Get resource manifest |
89
+ | `handleHeadResource(locator, registry)` | Check resource existence |
90
+ | `handleDeleteResource(locator, registry)` | Delete a resource |
91
+ | `handleGetContent(locator, registry)` | Download resource archive |
92
+ | `handleSearch(query, limit, offset, registry)` | Search resources |
93
+
94
+ ## API Endpoints
95
+
96
+ All endpoints are prefixed with `/api/v1`.
97
+
98
+ ### `GET /api/v1/health`
99
+
100
+ Health check endpoint.
101
+
102
+ **Response:**
103
+
104
+ ```json
105
+ { "status": "ok" }
106
+ ```
107
+
108
+ ### `POST /api/v1/publish`
109
+
110
+ Publish a resource to the registry.
111
+
112
+ **Content-Type:** `multipart/form-data`
113
+
114
+ **Fields:**
115
+
116
+ - `locator` (string) - Resource locator (e.g., `hello.text@1.0.0`)
117
+ - `manifest` (file) - JSON manifest file
118
+ - `content` (file) - Archive file (tar.gz)
119
+
120
+ **Response (201):**
121
+
122
+ ```json
123
+ { "locator": "hello.text@1.0.0" }
124
+ ```
125
+
126
+ ### `GET /api/v1/resource/:locator`
127
+
128
+ Get resource manifest.
129
+
130
+ **Response (200):**
131
+
132
+ ```json
133
+ {
134
+ "name": "hello",
135
+ "type": "text",
136
+ "tag": "1.0.0",
137
+ "registry": "example.com",
138
+ "path": "prompts"
139
+ }
140
+ ```
141
+
142
+ ### `HEAD /api/v1/resource/:locator`
143
+
144
+ Check if resource exists.
145
+
146
+ **Response:** `200` if exists, `404` if not.
147
+
148
+ ### `DELETE /api/v1/resource/:locator`
149
+
150
+ Delete a resource.
151
+
152
+ **Response:** `204` on success.
153
+
154
+ ### `GET /api/v1/content/:locator`
155
+
156
+ Download resource archive.
157
+
158
+ **Response:** Binary `application/gzip` content.
159
+
160
+ ### `GET /api/v1/search`
161
+
162
+ Search for resources.
163
+
164
+ **Query Parameters:**
165
+
166
+ - `q` (string, optional) - Search query
167
+ - `limit` (number, default: 100) - Max results
168
+ - `offset` (number, default: 0) - Pagination offset
169
+
170
+ **Response (200):**
171
+
172
+ ```json
173
+ {
174
+ "results": [
175
+ {
176
+ "locator": "hello.text@1.0.0",
177
+ "name": "hello",
178
+ "type": "text",
179
+ "tag": "1.0.0"
180
+ }
181
+ ],
182
+ "total": 1
183
+ }
184
+ ```
185
+
186
+ ## Protocol
187
+
188
+ Type definitions and constants for building clients.
189
+
190
+ ```typescript
191
+ import {
192
+ API_VERSION, // "v1"
193
+ API_PREFIX, // "/api/v1"
194
+ ENDPOINTS, // { publish, resource, content, search, health }
195
+ CONTENT_TYPES, // { json, binary, formData }
196
+ ERROR_CODES, // Error code constants
197
+ buildResourceUrl, // Build resource URL
198
+ buildContentUrl, // Build content URL
199
+ buildPublishUrl, // Build publish URL
200
+ buildSearchUrl, // Build search URL with params
201
+ } from "@resourcexjs/server";
202
+
203
+ // Types
204
+ import type {
205
+ ManifestData,
206
+ SearchQuery,
207
+ PublishResponse,
208
+ GetResourceResponse,
209
+ SearchResultItem,
210
+ SearchResponse,
211
+ ErrorResponse,
212
+ ErrorCode,
213
+ } from "@resourcexjs/server";
214
+ ```
215
+
216
+ ### URL Builders
217
+
218
+ ```typescript
219
+ import { buildResourceUrl, buildSearchUrl } from "@resourcexjs/server";
220
+
221
+ const url = buildResourceUrl("https://registry.example.com", "hello.text@1.0.0");
222
+ // "https://registry.example.com/api/v1/resource/hello.text%401.0.0"
223
+
224
+ const searchUrl = buildSearchUrl("https://registry.example.com", {
225
+ q: "prompt",
226
+ limit: 10,
227
+ });
228
+ // "https://registry.example.com/api/v1/search?q=prompt&limit=10"
229
+ ```
230
+
231
+ ## Error Handling
232
+
233
+ All error responses follow a consistent format:
234
+
235
+ ```json
236
+ {
237
+ "error": "Error message",
238
+ "code": "ERROR_CODE"
239
+ }
240
+ ```
241
+
242
+ ### Error Codes
243
+
244
+ | Code | Status | Description |
245
+ | -------------------- | ------ | ----------------------- |
246
+ | `LOCATOR_REQUIRED` | 400 | Missing locator field |
247
+ | `MANIFEST_REQUIRED` | 400 | Missing manifest file |
248
+ | `CONTENT_REQUIRED` | 400 | Missing content file |
249
+ | `INVALID_MANIFEST` | 400 | Invalid manifest format |
250
+ | `INVALID_LOCATOR` | 400 | Invalid locator format |
251
+ | `RESOURCE_NOT_FOUND` | 404 | Resource does not exist |
252
+ | `INTERNAL_ERROR` | 500 | Internal server error |
253
+
254
+ ## Re-exports
255
+
256
+ For convenience, this package re-exports commonly used classes:
257
+
258
+ ```typescript
259
+ import { LocalRegistry, FileSystemStorage, MemoryStorage } from "@resourcexjs/server";
260
+ ```
261
+
262
+ ## License
263
+
264
+ Apache-2.0
@@ -0,0 +1,132 @@
1
+ /**
2
+ * ResourceX Registry HTTP API Protocol
3
+ *
4
+ * Defines the contract between ResourceX client and registry server.
5
+ */
6
+ declare const API_VERSION: string;
7
+ declare const API_PREFIX: string;
8
+ declare const ENDPOINTS: {
9
+ readonly publish: string
10
+ readonly resource: string
11
+ readonly content: string
12
+ readonly search: string
13
+ readonly health: string
14
+ };
15
+ declare const CONTENT_TYPES: {
16
+ readonly json: "application/json"
17
+ readonly binary: "application/gzip"
18
+ readonly formData: "multipart/form-data"
19
+ };
20
+ interface ManifestData {
21
+ registry?: string;
22
+ path?: string;
23
+ name: string;
24
+ type: string;
25
+ tag: string;
26
+ }
27
+ declare const PUBLISH_FIELDS: {
28
+ readonly locator: "locator"
29
+ readonly manifest: "manifest"
30
+ readonly content: "content"
31
+ };
32
+ interface SearchQuery {
33
+ q?: string;
34
+ limit?: number;
35
+ offset?: number;
36
+ }
37
+ interface PublishResponse {
38
+ locator: string;
39
+ }
40
+ type GetResourceResponse = ManifestData;
41
+ interface SearchResultItem {
42
+ locator: string;
43
+ registry?: string;
44
+ path?: string;
45
+ name: string;
46
+ type: string;
47
+ tag: string;
48
+ }
49
+ interface SearchResponse {
50
+ results: SearchResultItem[];
51
+ total?: number;
52
+ }
53
+ interface ErrorResponse {
54
+ error: string;
55
+ code?: string;
56
+ }
57
+ declare const ERROR_CODES: {
58
+ readonly LOCATOR_REQUIRED: "LOCATOR_REQUIRED"
59
+ readonly MANIFEST_REQUIRED: "MANIFEST_REQUIRED"
60
+ readonly CONTENT_REQUIRED: "CONTENT_REQUIRED"
61
+ readonly ARCHIVE_REQUIRED: "ARCHIVE_REQUIRED"
62
+ readonly INVALID_MANIFEST: "INVALID_MANIFEST"
63
+ readonly INVALID_LOCATOR: "INVALID_LOCATOR"
64
+ readonly MISSING_REQUIRED_FIELDS: "MISSING_REQUIRED_FIELDS"
65
+ readonly RESOURCE_NOT_FOUND: "RESOURCE_NOT_FOUND"
66
+ readonly INTERNAL_ERROR: "INTERNAL_ERROR"
67
+ };
68
+ type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];
69
+ declare const ERROR_STATUS: Record<ErrorCode, number>;
70
+ declare function buildResourceUrl(baseUrl: string, locator: string): string;
71
+ declare function buildContentUrl(baseUrl: string, locator: string): string;
72
+ declare function buildPublishUrl(baseUrl: string): string;
73
+ declare function buildSearchUrl(baseUrl: string, params?: {
74
+ q?: string
75
+ limit?: number
76
+ offset?: number
77
+ }): string;
78
+ import { Registry } from "@resourcexjs/registry";
79
+ /**
80
+ * Handle POST /publish
81
+ */
82
+ declare function handlePublish(request: Request, registry: Registry): Promise<Response>;
83
+ /**
84
+ * Handle GET /resource/:locator
85
+ */
86
+ declare function handleGetResource(locator: string, registry: Registry): Promise<Response>;
87
+ /**
88
+ * Handle HEAD /resource/:locator
89
+ */
90
+ declare function handleHeadResource(locator: string, registry: Registry): Promise<Response>;
91
+ /**
92
+ * Handle DELETE /resource/:locator
93
+ */
94
+ declare function handleDeleteResource(locator: string, registry: Registry): Promise<Response>;
95
+ /**
96
+ * Handle GET /content/:locator
97
+ */
98
+ declare function handleGetContent(locator: string, registry: Registry): Promise<Response>;
99
+ /**
100
+ * Handle GET /search
101
+ */
102
+ declare function handleSearch(query: string | undefined, limit: number, offset: number, registry: Registry): Promise<Response>;
103
+ import { Hono } from "hono";
104
+ interface RegistryServerConfig {
105
+ /**
106
+ * Path for storing resources.
107
+ * @default "./data"
108
+ */
109
+ storagePath?: string;
110
+ /**
111
+ * Base path for API routes.
112
+ * @default ""
113
+ */
114
+ basePath?: string;
115
+ /**
116
+ * Enable CORS.
117
+ * @default true
118
+ */
119
+ cors?: boolean;
120
+ }
121
+ /**
122
+ * Create a registry server Hono app.
123
+ */
124
+ declare function createRegistryServer(config?: RegistryServerConfig): Hono;
125
+ import { LocalRegistry } from "@resourcexjs/registry";
126
+ import { FileSystemStorage, MemoryStorage } from "@resourcexjs/storage";
127
+ import { Registry as Registry2 } from "@resourcexjs/registry";
128
+ interface CreateRegistryConfig {
129
+ storagePath: string;
130
+ }
131
+ declare function createRegistry(config: CreateRegistryConfig): Registry2;
132
+ export { handleSearch, handlePublish, handleHeadResource, handleGetResource, handleGetContent, handleDeleteResource, createRegistryServer, createRegistry, buildSearchUrl, buildResourceUrl, buildPublishUrl, buildContentUrl, SearchResultItem, SearchResponse, SearchQuery, RegistryServerConfig, PublishResponse, PUBLISH_FIELDS, MemoryStorage, ManifestData, LocalRegistry, GetResourceResponse, FileSystemStorage, ErrorResponse, ErrorCode, ERROR_STATUS, ERROR_CODES, ENDPOINTS, CreateRegistryConfig, CONTENT_TYPES, API_VERSION, API_PREFIX };
package/dist/index.js ADDED
@@ -0,0 +1,280 @@
1
+ // src/protocol.ts
2
+ var API_VERSION = "v1";
3
+ var API_PREFIX = `/api/${API_VERSION}`;
4
+ var ENDPOINTS = {
5
+ publish: `${API_PREFIX}/publish`,
6
+ resource: `${API_PREFIX}/resource`,
7
+ content: `${API_PREFIX}/content`,
8
+ search: `${API_PREFIX}/search`,
9
+ health: `${API_PREFIX}/health`
10
+ };
11
+ var CONTENT_TYPES = {
12
+ json: "application/json",
13
+ binary: "application/gzip",
14
+ formData: "multipart/form-data"
15
+ };
16
+ var PUBLISH_FIELDS = {
17
+ locator: "locator",
18
+ manifest: "manifest",
19
+ content: "content"
20
+ };
21
+ var ERROR_CODES = {
22
+ LOCATOR_REQUIRED: "LOCATOR_REQUIRED",
23
+ MANIFEST_REQUIRED: "MANIFEST_REQUIRED",
24
+ CONTENT_REQUIRED: "CONTENT_REQUIRED",
25
+ ARCHIVE_REQUIRED: "ARCHIVE_REQUIRED",
26
+ INVALID_MANIFEST: "INVALID_MANIFEST",
27
+ INVALID_LOCATOR: "INVALID_LOCATOR",
28
+ MISSING_REQUIRED_FIELDS: "MISSING_REQUIRED_FIELDS",
29
+ RESOURCE_NOT_FOUND: "RESOURCE_NOT_FOUND",
30
+ INTERNAL_ERROR: "INTERNAL_ERROR"
31
+ };
32
+ var ERROR_STATUS = {
33
+ [ERROR_CODES.LOCATOR_REQUIRED]: 400,
34
+ [ERROR_CODES.MANIFEST_REQUIRED]: 400,
35
+ [ERROR_CODES.CONTENT_REQUIRED]: 400,
36
+ [ERROR_CODES.ARCHIVE_REQUIRED]: 400,
37
+ [ERROR_CODES.INVALID_MANIFEST]: 400,
38
+ [ERROR_CODES.INVALID_LOCATOR]: 400,
39
+ [ERROR_CODES.MISSING_REQUIRED_FIELDS]: 400,
40
+ [ERROR_CODES.RESOURCE_NOT_FOUND]: 404,
41
+ [ERROR_CODES.INTERNAL_ERROR]: 500
42
+ };
43
+ function buildResourceUrl(baseUrl, locator) {
44
+ return `${baseUrl.replace(/\/$/, "")}${ENDPOINTS.resource}/${encodeURIComponent(locator)}`;
45
+ }
46
+ function buildContentUrl(baseUrl, locator) {
47
+ return `${baseUrl.replace(/\/$/, "")}${ENDPOINTS.content}/${encodeURIComponent(locator)}`;
48
+ }
49
+ function buildPublishUrl(baseUrl) {
50
+ return `${baseUrl.replace(/\/$/, "")}${ENDPOINTS.publish}`;
51
+ }
52
+ function buildSearchUrl(baseUrl, params) {
53
+ const url = new URL(`${baseUrl.replace(/\/$/, "")}${ENDPOINTS.search}`);
54
+ if (params?.q)
55
+ url.searchParams.set("q", params.q);
56
+ if (params?.limit)
57
+ url.searchParams.set("limit", String(params.limit));
58
+ if (params?.offset)
59
+ url.searchParams.set("offset", String(params.offset));
60
+ return url.toString();
61
+ }
62
+ // src/handlers.ts
63
+ import { parse, format, manifest, wrap, resource } from "@resourcexjs/core";
64
+ function jsonResponse(data, status = 200) {
65
+ return new Response(JSON.stringify(data), {
66
+ status,
67
+ headers: { "Content-Type": "application/json" }
68
+ });
69
+ }
70
+ function errorResponse(error, code, status) {
71
+ const body = { error, code };
72
+ return new Response(JSON.stringify(body), {
73
+ status,
74
+ headers: { "Content-Type": "application/json" }
75
+ });
76
+ }
77
+ async function handlePublish(request, registry) {
78
+ try {
79
+ const formData = await request.formData();
80
+ const locatorStr = formData.get(PUBLISH_FIELDS.locator);
81
+ if (!locatorStr || typeof locatorStr !== "string") {
82
+ return errorResponse("Missing locator field", ERROR_CODES.LOCATOR_REQUIRED, 400);
83
+ }
84
+ const manifestFile = formData.get(PUBLISH_FIELDS.manifest);
85
+ if (!manifestFile || typeof manifestFile === "string") {
86
+ return errorResponse("Missing manifest file", ERROR_CODES.MANIFEST_REQUIRED, 400);
87
+ }
88
+ const contentFile = formData.get(PUBLISH_FIELDS.content);
89
+ if (!contentFile || typeof contentFile === "string") {
90
+ return errorResponse("Missing content file", ERROR_CODES.CONTENT_REQUIRED, 400);
91
+ }
92
+ const rxl = parse(locatorStr);
93
+ const manifestText = await manifestFile.text();
94
+ const manifestData = JSON.parse(manifestText);
95
+ const rxm = manifest({
96
+ registry: manifestData.registry ?? rxl.registry,
97
+ path: manifestData.path ?? rxl.path,
98
+ name: manifestData.name ?? rxl.name,
99
+ type: manifestData.type,
100
+ tag: manifestData.tag ?? rxl.tag ?? "latest",
101
+ files: manifestData.files
102
+ });
103
+ const contentBuffer = Buffer.from(await contentFile.arrayBuffer());
104
+ const rxa = wrap(contentBuffer);
105
+ const rxr = resource(rxm, rxa);
106
+ await registry.put(rxr);
107
+ const response = { locator: format(rxr.locator) };
108
+ return jsonResponse(response, 201);
109
+ } catch (error) {
110
+ const message = error instanceof Error ? error.message : "Unknown error";
111
+ return errorResponse(message, ERROR_CODES.INTERNAL_ERROR, 500);
112
+ }
113
+ }
114
+ async function handleGetResource(locator, registry) {
115
+ try {
116
+ const rxl = parse(locator);
117
+ const rxr = await registry.get(rxl);
118
+ const response = {
119
+ registry: rxr.manifest.registry,
120
+ path: rxr.manifest.path,
121
+ name: rxr.manifest.name,
122
+ type: rxr.manifest.type,
123
+ tag: rxr.manifest.tag
124
+ };
125
+ return jsonResponse(response);
126
+ } catch (error) {
127
+ const message = error instanceof Error ? error.message : "Unknown error";
128
+ if (message.includes("not found")) {
129
+ return errorResponse("Resource not found", ERROR_CODES.RESOURCE_NOT_FOUND, 404);
130
+ }
131
+ return errorResponse(message, ERROR_CODES.INTERNAL_ERROR, 500);
132
+ }
133
+ }
134
+ async function handleHeadResource(locator, registry) {
135
+ try {
136
+ const rxl = parse(locator);
137
+ const exists = await registry.has(rxl);
138
+ return new Response(null, { status: exists ? 200 : 404 });
139
+ } catch {
140
+ return new Response(null, { status: 500 });
141
+ }
142
+ }
143
+ async function handleDeleteResource(locator, registry) {
144
+ try {
145
+ const rxl = parse(locator);
146
+ const exists = await registry.has(rxl);
147
+ if (!exists) {
148
+ return errorResponse("Resource not found", ERROR_CODES.RESOURCE_NOT_FOUND, 404);
149
+ }
150
+ await registry.remove(rxl);
151
+ return new Response(null, { status: 204 });
152
+ } catch (error) {
153
+ const message = error instanceof Error ? error.message : "Unknown error";
154
+ return errorResponse(message, ERROR_CODES.INTERNAL_ERROR, 500);
155
+ }
156
+ }
157
+ async function handleGetContent(locator, registry) {
158
+ try {
159
+ const rxl = parse(locator);
160
+ const rxr = await registry.get(rxl);
161
+ const buffer = await rxr.archive.buffer();
162
+ return new Response(buffer, {
163
+ status: 200,
164
+ headers: {
165
+ "Content-Type": "application/gzip",
166
+ "Content-Disposition": `attachment; filename="archive.tar.gz"`,
167
+ "Content-Length": buffer.byteLength.toString()
168
+ }
169
+ });
170
+ } catch (error) {
171
+ const message = error instanceof Error ? error.message : "Unknown error";
172
+ if (message.includes("not found")) {
173
+ return errorResponse("Resource not found", ERROR_CODES.RESOURCE_NOT_FOUND, 404);
174
+ }
175
+ return errorResponse(message, ERROR_CODES.INTERNAL_ERROR, 500);
176
+ }
177
+ }
178
+ async function handleSearch(query, limit, offset, registry) {
179
+ try {
180
+ const results = await registry.list({
181
+ query: query || undefined,
182
+ limit,
183
+ offset
184
+ });
185
+ const response = {
186
+ results: results.map((rxl) => ({
187
+ locator: format(rxl),
188
+ registry: rxl.registry,
189
+ path: rxl.path,
190
+ name: rxl.name,
191
+ type: "",
192
+ tag: rxl.tag ?? "latest"
193
+ })),
194
+ total: results.length
195
+ };
196
+ return jsonResponse(response);
197
+ } catch (error) {
198
+ const message = error instanceof Error ? error.message : "Unknown error";
199
+ return errorResponse(message, ERROR_CODES.INTERNAL_ERROR, 500);
200
+ }
201
+ }
202
+ // src/hono.ts
203
+ import { Hono } from "hono";
204
+ import { cors } from "hono/cors";
205
+ import { FileSystemStorage } from "@resourcexjs/storage";
206
+ import { LocalRegistry } from "@resourcexjs/registry";
207
+ function createRegistryServer(config) {
208
+ const storagePath = config?.storagePath ?? "./data";
209
+ const basePath = config?.basePath ?? "";
210
+ const enableCors = config?.cors ?? true;
211
+ const storage = new FileSystemStorage(storagePath);
212
+ const registry = new LocalRegistry(storage);
213
+ const app = new Hono().basePath(basePath);
214
+ if (enableCors) {
215
+ app.use("*", cors());
216
+ }
217
+ app.get(ENDPOINTS.health, (c) => c.json({ status: "ok" }));
218
+ app.post(ENDPOINTS.publish, async (c) => {
219
+ return handlePublish(c.req.raw, registry);
220
+ });
221
+ app.get(`${ENDPOINTS.resource}/:locator`, async (c) => {
222
+ const locator = decodeURIComponent(c.req.param("locator"));
223
+ return handleGetResource(locator, registry);
224
+ });
225
+ app.on("HEAD", `${ENDPOINTS.resource}/:locator`, async (c) => {
226
+ const locator = decodeURIComponent(c.req.param("locator"));
227
+ return handleHeadResource(locator, registry);
228
+ });
229
+ app.delete(`${ENDPOINTS.resource}/:locator`, async (c) => {
230
+ const locator = decodeURIComponent(c.req.param("locator"));
231
+ return handleDeleteResource(locator, registry);
232
+ });
233
+ app.get(`${ENDPOINTS.content}/:locator`, async (c) => {
234
+ const locator = decodeURIComponent(c.req.param("locator"));
235
+ return handleGetContent(locator, registry);
236
+ });
237
+ app.get(ENDPOINTS.search, async (c) => {
238
+ const query = c.req.query("q");
239
+ const limit = parseInt(c.req.query("limit") ?? "100", 10);
240
+ const offset = parseInt(c.req.query("offset") ?? "0", 10);
241
+ return handleSearch(query, limit, offset, registry);
242
+ });
243
+ return app;
244
+ }
245
+
246
+ // src/index.ts
247
+ import { LocalRegistry as LocalRegistry2 } from "@resourcexjs/registry";
248
+ import { FileSystemStorage as FileSystemStorage2, MemoryStorage } from "@resourcexjs/storage";
249
+ import { FileSystemStorage as FileSystemStorage3 } from "@resourcexjs/storage";
250
+ import { LocalRegistry as LocalRegistry3 } from "@resourcexjs/registry";
251
+ function createRegistry(config) {
252
+ const storage = new FileSystemStorage3(config.storagePath);
253
+ return new LocalRegistry3(storage);
254
+ }
255
+ export {
256
+ handleSearch,
257
+ handlePublish,
258
+ handleHeadResource,
259
+ handleGetResource,
260
+ handleGetContent,
261
+ handleDeleteResource,
262
+ createRegistryServer,
263
+ createRegistry,
264
+ buildSearchUrl,
265
+ buildResourceUrl,
266
+ buildPublishUrl,
267
+ buildContentUrl,
268
+ PUBLISH_FIELDS,
269
+ MemoryStorage,
270
+ LocalRegistry2 as LocalRegistry,
271
+ FileSystemStorage2 as FileSystemStorage,
272
+ ERROR_STATUS,
273
+ ERROR_CODES,
274
+ ENDPOINTS,
275
+ CONTENT_TYPES,
276
+ API_VERSION,
277
+ API_PREFIX
278
+ };
279
+
280
+ //# debugId=DA345CD276F2BE2D64756E2164756E21
@@ -0,0 +1,13 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/protocol.ts", "../src/handlers.ts", "../src/hono.ts", "../src/index.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * ResourceX Registry HTTP API Protocol\n *\n * Defines the contract between ResourceX client and registry server.\n */\n\n// ============================================\n// API Endpoints\n// ============================================\n\nexport const API_VERSION: string = \"v1\";\nexport const API_PREFIX: string = `/api/${API_VERSION}`;\n\nexport const ENDPOINTS: {\n readonly publish: string;\n readonly resource: string;\n readonly content: string;\n readonly search: string;\n readonly health: string;\n} = {\n publish: `${API_PREFIX}/publish`,\n resource: `${API_PREFIX}/resource`,\n content: `${API_PREFIX}/content`,\n search: `${API_PREFIX}/search`,\n health: `${API_PREFIX}/health`,\n} as const;\n\nexport const CONTENT_TYPES = {\n json: \"application/json\",\n binary: \"application/gzip\",\n formData: \"multipart/form-data\",\n} as const;\n\n// ============================================\n// Request Types\n// ============================================\n\nexport interface ManifestData {\n registry?: string;\n path?: string;\n name: string;\n type: string;\n tag: string;\n}\n\nexport const PUBLISH_FIELDS = {\n locator: \"locator\",\n manifest: \"manifest\",\n content: \"content\",\n} as const;\n\nexport interface SearchQuery {\n q?: string;\n limit?: number;\n offset?: number;\n}\n\n// ============================================\n// Response Types\n// ============================================\n\nexport interface PublishResponse {\n locator: string;\n}\n\nexport type GetResourceResponse = ManifestData;\n\nexport interface SearchResultItem {\n locator: string;\n registry?: string;\n path?: string;\n name: string;\n type: string;\n tag: string;\n}\n\nexport interface SearchResponse {\n results: SearchResultItem[];\n total?: number;\n}\n\nexport interface ErrorResponse {\n error: string;\n code?: string;\n}\n\n// ============================================\n// Error Codes\n// ============================================\n\nexport const ERROR_CODES = {\n // 400 Bad Request\n LOCATOR_REQUIRED: \"LOCATOR_REQUIRED\",\n MANIFEST_REQUIRED: \"MANIFEST_REQUIRED\",\n CONTENT_REQUIRED: \"CONTENT_REQUIRED\",\n ARCHIVE_REQUIRED: \"ARCHIVE_REQUIRED\",\n INVALID_MANIFEST: \"INVALID_MANIFEST\",\n INVALID_LOCATOR: \"INVALID_LOCATOR\",\n MISSING_REQUIRED_FIELDS: \"MISSING_REQUIRED_FIELDS\",\n\n // 404 Not Found\n RESOURCE_NOT_FOUND: \"RESOURCE_NOT_FOUND\",\n\n // 500 Internal Server Error\n INTERNAL_ERROR: \"INTERNAL_ERROR\",\n} as const;\n\nexport type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];\n\nexport const ERROR_STATUS: Record<ErrorCode, number> = {\n [ERROR_CODES.LOCATOR_REQUIRED]: 400,\n [ERROR_CODES.MANIFEST_REQUIRED]: 400,\n [ERROR_CODES.CONTENT_REQUIRED]: 400,\n [ERROR_CODES.ARCHIVE_REQUIRED]: 400,\n [ERROR_CODES.INVALID_MANIFEST]: 400,\n [ERROR_CODES.INVALID_LOCATOR]: 400,\n [ERROR_CODES.MISSING_REQUIRED_FIELDS]: 400,\n [ERROR_CODES.RESOURCE_NOT_FOUND]: 404,\n [ERROR_CODES.INTERNAL_ERROR]: 500,\n};\n\n// ============================================\n// URL Builders\n// ============================================\n\nexport function buildResourceUrl(baseUrl: string, locator: string): string {\n return `${baseUrl.replace(/\\/$/, \"\")}${ENDPOINTS.resource}/${encodeURIComponent(locator)}`;\n}\n\nexport function buildContentUrl(baseUrl: string, locator: string): string {\n return `${baseUrl.replace(/\\/$/, \"\")}${ENDPOINTS.content}/${encodeURIComponent(locator)}`;\n}\n\nexport function buildPublishUrl(baseUrl: string): string {\n return `${baseUrl.replace(/\\/$/, \"\")}${ENDPOINTS.publish}`;\n}\n\nexport function buildSearchUrl(\n baseUrl: string,\n params?: { q?: string; limit?: number; offset?: number }\n): string {\n const url = new URL(`${baseUrl.replace(/\\/$/, \"\")}${ENDPOINTS.search}`);\n if (params?.q) url.searchParams.set(\"q\", params.q);\n if (params?.limit) url.searchParams.set(\"limit\", String(params.limit));\n if (params?.offset) url.searchParams.set(\"offset\", String(params.offset));\n return url.toString();\n}\n",
6
+ "/**\n * ResourceX Registry Handlers\n *\n * Handler functions for Next.js Route Handler or any other framework.\n */\n\nimport { parse, format, manifest, wrap, resource } from \"@resourcexjs/core\";\nimport type { Registry } from \"@resourcexjs/registry\";\nimport {\n PUBLISH_FIELDS,\n ERROR_CODES,\n type PublishResponse,\n type GetResourceResponse,\n type SearchResponse,\n type ErrorResponse,\n} from \"./protocol.js\";\n\n// ============================================\n// Helper Functions\n// ============================================\n\nfunction jsonResponse<T>(data: T, status = 200): Response {\n return new Response(JSON.stringify(data), {\n status,\n headers: { \"Content-Type\": \"application/json\" },\n });\n}\n\nfunction errorResponse(error: string, code: string, status: number): Response {\n const body: ErrorResponse = { error, code };\n return new Response(JSON.stringify(body), {\n status,\n headers: { \"Content-Type\": \"application/json\" },\n });\n}\n\n// ============================================\n// Handler Functions\n// ============================================\n\n/**\n * Handle POST /publish\n */\nexport async function handlePublish(request: Request, registry: Registry): Promise<Response> {\n try {\n const formData = await request.formData();\n\n const locatorStr = formData.get(PUBLISH_FIELDS.locator);\n if (!locatorStr || typeof locatorStr !== \"string\") {\n return errorResponse(\"Missing locator field\", ERROR_CODES.LOCATOR_REQUIRED, 400);\n }\n\n const manifestFile = formData.get(PUBLISH_FIELDS.manifest);\n if (!manifestFile || typeof manifestFile === \"string\") {\n return errorResponse(\"Missing manifest file\", ERROR_CODES.MANIFEST_REQUIRED, 400);\n }\n\n const contentFile = formData.get(PUBLISH_FIELDS.content);\n if (!contentFile || typeof contentFile === \"string\") {\n return errorResponse(\"Missing content file\", ERROR_CODES.CONTENT_REQUIRED, 400);\n }\n\n const rxl = parse(locatorStr);\n const manifestText = await manifestFile.text();\n const manifestData = JSON.parse(manifestText);\n\n const rxm = manifest({\n registry: manifestData.registry ?? rxl.registry,\n path: manifestData.path ?? rxl.path,\n name: manifestData.name ?? rxl.name,\n type: manifestData.type, // Type must come from manifest, not locator\n tag: manifestData.tag ?? rxl.tag ?? \"latest\",\n files: manifestData.files,\n });\n\n const contentBuffer = Buffer.from(await contentFile.arrayBuffer());\n const rxa = wrap(contentBuffer);\n const rxr = resource(rxm, rxa);\n\n await registry.put(rxr);\n\n const response: PublishResponse = { locator: format(rxr.locator) };\n return jsonResponse(response, 201);\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown error\";\n return errorResponse(message, ERROR_CODES.INTERNAL_ERROR, 500);\n }\n}\n\n/**\n * Handle GET /resource/:locator\n */\nexport async function handleGetResource(locator: string, registry: Registry): Promise<Response> {\n try {\n const rxl = parse(locator);\n const rxr = await registry.get(rxl);\n\n const response: GetResourceResponse = {\n registry: rxr.manifest.registry,\n path: rxr.manifest.path,\n name: rxr.manifest.name,\n type: rxr.manifest.type,\n tag: rxr.manifest.tag,\n };\n return jsonResponse(response);\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown error\";\n if (message.includes(\"not found\")) {\n return errorResponse(\"Resource not found\", ERROR_CODES.RESOURCE_NOT_FOUND, 404);\n }\n return errorResponse(message, ERROR_CODES.INTERNAL_ERROR, 500);\n }\n}\n\n/**\n * Handle HEAD /resource/:locator\n */\nexport async function handleHeadResource(locator: string, registry: Registry): Promise<Response> {\n try {\n const rxl = parse(locator);\n const exists = await registry.has(rxl);\n return new Response(null, { status: exists ? 200 : 404 });\n } catch {\n return new Response(null, { status: 500 });\n }\n}\n\n/**\n * Handle DELETE /resource/:locator\n */\nexport async function handleDeleteResource(locator: string, registry: Registry): Promise<Response> {\n try {\n const rxl = parse(locator);\n const exists = await registry.has(rxl);\n\n if (!exists) {\n return errorResponse(\"Resource not found\", ERROR_CODES.RESOURCE_NOT_FOUND, 404);\n }\n\n await registry.remove(rxl);\n return new Response(null, { status: 204 });\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown error\";\n return errorResponse(message, ERROR_CODES.INTERNAL_ERROR, 500);\n }\n}\n\n/**\n * Handle GET /content/:locator\n */\nexport async function handleGetContent(locator: string, registry: Registry): Promise<Response> {\n try {\n const rxl = parse(locator);\n const rxr = await registry.get(rxl);\n const buffer = await rxr.archive.buffer();\n\n return new Response(buffer, {\n status: 200,\n headers: {\n \"Content-Type\": \"application/gzip\",\n \"Content-Disposition\": `attachment; filename=\"archive.tar.gz\"`,\n \"Content-Length\": buffer.byteLength.toString(),\n },\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown error\";\n if (message.includes(\"not found\")) {\n return errorResponse(\"Resource not found\", ERROR_CODES.RESOURCE_NOT_FOUND, 404);\n }\n return errorResponse(message, ERROR_CODES.INTERNAL_ERROR, 500);\n }\n}\n\n/**\n * Handle GET /search\n */\nexport async function handleSearch(\n query: string | undefined,\n limit: number,\n offset: number,\n registry: Registry\n): Promise<Response> {\n try {\n const results = await registry.list({\n query: query || undefined,\n limit,\n offset,\n });\n\n const response: SearchResponse = {\n results: results.map((rxl) => ({\n locator: format(rxl),\n registry: rxl.registry,\n path: rxl.path,\n name: rxl.name,\n type: \"\", // Type not in RXL anymore, would need to read manifest\n tag: rxl.tag ?? \"latest\",\n })),\n total: results.length,\n };\n return jsonResponse(response);\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown error\";\n return errorResponse(message, ERROR_CODES.INTERNAL_ERROR, 500);\n }\n}\n",
7
+ "/**\n * ResourceX Registry Hono Server\n *\n * Ready-to-use Hono app implementing the ResourceX Registry Protocol.\n */\n\nimport { Hono } from \"hono\";\nimport { cors } from \"hono/cors\";\nimport { FileSystemStorage } from \"@resourcexjs/storage\";\nimport { LocalRegistry } from \"@resourcexjs/registry\";\nimport {\n handlePublish,\n handleGetResource,\n handleHeadResource,\n handleDeleteResource,\n handleGetContent,\n handleSearch,\n} from \"./handlers.js\";\nimport { ENDPOINTS } from \"./protocol.js\";\n\nexport interface RegistryServerConfig {\n /**\n * Path for storing resources.\n * @default \"./data\"\n */\n storagePath?: string;\n\n /**\n * Base path for API routes.\n * @default \"\"\n */\n basePath?: string;\n\n /**\n * Enable CORS.\n * @default true\n */\n cors?: boolean;\n}\n\n/**\n * Create a registry server Hono app.\n */\nexport function createRegistryServer(config?: RegistryServerConfig): Hono {\n const storagePath = config?.storagePath ?? \"./data\";\n const basePath = config?.basePath ?? \"\";\n const enableCors = config?.cors ?? true;\n\n const storage = new FileSystemStorage(storagePath);\n const registry = new LocalRegistry(storage);\n\n const app = new Hono().basePath(basePath);\n\n if (enableCors) {\n app.use(\"*\", cors());\n }\n\n // Health check\n app.get(ENDPOINTS.health, (c) => c.json({ status: \"ok\" }));\n\n // POST /publish\n app.post(ENDPOINTS.publish, async (c) => {\n return handlePublish(c.req.raw, registry);\n });\n\n // GET /resource/:locator\n app.get(`${ENDPOINTS.resource}/:locator`, async (c) => {\n const locator = decodeURIComponent(c.req.param(\"locator\"));\n return handleGetResource(locator, registry);\n });\n\n // HEAD /resource/:locator\n app.on(\"HEAD\", `${ENDPOINTS.resource}/:locator`, async (c) => {\n const locator = decodeURIComponent(c.req.param(\"locator\"));\n return handleHeadResource(locator, registry);\n });\n\n // DELETE /resource/:locator\n app.delete(`${ENDPOINTS.resource}/:locator`, async (c) => {\n const locator = decodeURIComponent(c.req.param(\"locator\"));\n return handleDeleteResource(locator, registry);\n });\n\n // GET /content/:locator\n app.get(`${ENDPOINTS.content}/:locator`, async (c) => {\n const locator = decodeURIComponent(c.req.param(\"locator\"));\n return handleGetContent(locator, registry);\n });\n\n // GET /search\n app.get(ENDPOINTS.search, async (c) => {\n const query = c.req.query(\"q\");\n const limit = parseInt(c.req.query(\"limit\") ?? \"100\", 10);\n const offset = parseInt(c.req.query(\"offset\") ?? \"0\", 10);\n return handleSearch(query, limit, offset, registry);\n });\n\n return app;\n}\n",
8
+ "/**\n * @resourcexjs/server\n *\n * ResourceX Registry Server - Protocol, Handlers, and Hono Server\n *\n * @example\n * ```typescript\n * // Option 1: Use Hono Server directly\n * import { createRegistryServer } from \"@resourcexjs/server\";\n * const server = createRegistryServer({ storagePath: \"./data\" });\n * Bun.serve({ fetch: server.fetch, port: 3000 });\n *\n * // Option 2: Use handlers with Next.js Route Handler\n * import { handlePublish, handleSearch, createRegistry } from \"@resourcexjs/server\";\n * const registry = createRegistry({ storagePath: \"./data\" });\n * export async function POST(req) { return handlePublish(req, registry); }\n *\n * // Option 3: Use protocol types only\n * import { ENDPOINTS, type PublishResponse } from \"@resourcexjs/server\";\n * ```\n *\n * @packageDocumentation\n */\n\n// Protocol\nexport {\n API_VERSION,\n API_PREFIX,\n ENDPOINTS,\n CONTENT_TYPES,\n PUBLISH_FIELDS,\n ERROR_CODES,\n ERROR_STATUS,\n buildResourceUrl,\n buildContentUrl,\n buildPublishUrl,\n buildSearchUrl,\n type ManifestData,\n type SearchQuery,\n type PublishResponse,\n type GetResourceResponse,\n type SearchResultItem,\n type SearchResponse,\n type ErrorResponse,\n type ErrorCode,\n} from \"./protocol.js\";\n\n// Handlers\nexport {\n handlePublish,\n handleGetResource,\n handleHeadResource,\n handleDeleteResource,\n handleGetContent,\n handleSearch,\n} from \"./handlers.js\";\n\n// Hono Server\nexport { createRegistryServer, type RegistryServerConfig } from \"./hono.js\";\n\n// Re-export Registry for convenience\nexport { LocalRegistry } from \"@resourcexjs/registry\";\nexport { FileSystemStorage, MemoryStorage } from \"@resourcexjs/storage\";\n\n/**\n * Convenience function to create a registry instance.\n */\nimport { FileSystemStorage } from \"@resourcexjs/storage\";\nimport { LocalRegistry } from \"@resourcexjs/registry\";\nimport type { Registry } from \"@resourcexjs/registry\";\n\nexport interface CreateRegistryConfig {\n storagePath: string;\n}\n\nexport function createRegistry(config: CreateRegistryConfig): Registry {\n const storage = new FileSystemStorage(config.storagePath);\n return new LocalRegistry(storage);\n}\n"
9
+ ],
10
+ "mappings": "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",
11
+ "debugId": "DA345CD276F2BE2D64756E2164756E21",
12
+ "names": []
13
+ }
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "@resourcexjs/server",
3
+ "version": "2.5.1",
4
+ "description": "ResourceX Registry Server - Protocol, Handlers, and Hono Server",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "default": "./dist/index.js"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "scripts": {
18
+ "build": "bun run build.ts",
19
+ "lint": "eslint .",
20
+ "typecheck": "tsc --noEmit",
21
+ "clean": "rm -rf dist"
22
+ },
23
+ "dependencies": {
24
+ "@resourcexjs/core": "^2.5.1",
25
+ "@resourcexjs/registry": "^2.5.1",
26
+ "@resourcexjs/storage": "^2.5.1",
27
+ "hono": "^4.7.10"
28
+ },
29
+ "devDependencies": {},
30
+ "publishConfig": {
31
+ "access": "public"
32
+ },
33
+ "license": "Apache-2.0"
34
+ }