@kb-labs/marketplace-api 2.31.0 → 2.32.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/index.js CHANGED
@@ -1,8 +1,80 @@
1
1
  import Fastify from 'fastify';
2
2
  import { HttpObservabilityCollector, registerOpenAPI, createCorrelatedLogger, createServiceReadyResponse } from '@kb-labs/shared-http';
3
+ import * as path from 'path';
4
+ import { ScopeResolutionError, AdapterScopeError } from '@kb-labs/marketplace-core';
3
5
  import { randomUUID } from 'crypto';
4
6
 
5
7
  // src/server.ts
8
+ var MUTATING_SCOPES = ["platform", "project"];
9
+ var QUERY_SCOPES = ["platform", "project", "all"];
10
+ var ScopeRequestError = class extends Error {
11
+ statusCode = 400;
12
+ code;
13
+ constructor(code, message) {
14
+ super(message);
15
+ this.name = "ScopeRequestError";
16
+ this.code = code;
17
+ }
18
+ };
19
+ function parseMutatingScope(input) {
20
+ const rawScope = input?.scope;
21
+ const scope = normalizeScope(rawScope, MUTATING_SCOPES, "platform");
22
+ const projectRoot = normalizeProjectRoot(input?.projectRoot, scope);
23
+ return { scope, projectRoot };
24
+ }
25
+ function parseQueryScope(input) {
26
+ const rawScope = input?.scope;
27
+ const scope = normalizeScope(rawScope, QUERY_SCOPES, "platform");
28
+ const projectRoot = normalizeProjectRoot(input?.projectRoot, scope);
29
+ return { scope, projectRoot };
30
+ }
31
+ function normalizeScope(raw, allowed, fallback) {
32
+ if (raw === void 0 || raw === null || raw === "") {
33
+ return fallback;
34
+ }
35
+ if (typeof raw !== "string" || !allowed.includes(raw)) {
36
+ throw new ScopeRequestError(
37
+ "SCOPE_INVALID",
38
+ `scope must be one of: ${allowed.join(", ")} (got ${JSON.stringify(raw)})`
39
+ );
40
+ }
41
+ return raw;
42
+ }
43
+ function normalizeProjectRoot(raw, scope) {
44
+ if (raw === void 0 || raw === null || raw === "") {
45
+ if (scope === "project") {
46
+ throw new ScopeRequestError(
47
+ "SCOPE_PROJECT_ROOT_REQUIRED",
48
+ 'projectRoot is required when scope="project"'
49
+ );
50
+ }
51
+ return void 0;
52
+ }
53
+ if (typeof raw !== "string") {
54
+ throw new ScopeRequestError("SCOPE_PROJECT_ROOT_TYPE", "projectRoot must be a string");
55
+ }
56
+ if (!path.isAbsolute(raw)) {
57
+ throw new ScopeRequestError(
58
+ "SCOPE_PROJECT_ROOT_NOT_ABSOLUTE",
59
+ `projectRoot must be absolute, got "${raw}"`
60
+ );
61
+ }
62
+ if (raw.includes("..")) {
63
+ throw new ScopeRequestError(
64
+ "SCOPE_PROJECT_ROOT_TRAVERSAL",
65
+ 'projectRoot must not contain ".." segments'
66
+ );
67
+ }
68
+ return path.resolve(raw);
69
+ }
70
+ var scopeBodySchemaFragment = {
71
+ scope: { type: "string", enum: MUTATING_SCOPES, description: "Target scope. Default: platform." },
72
+ projectRoot: { type: "string", description: 'Absolute project root (required when scope="project").' }
73
+ };
74
+ var queryScopeBodySchemaFragment = {
75
+ scope: { type: "string", enum: QUERY_SCOPES, description: "Query scope. Default: platform." },
76
+ projectRoot: { type: "string", description: 'Absolute project root (required when scope="project", recommended for scope="all").' }
77
+ };
6
78
 
7
79
  // src/routes/packages.ts
8
80
  function registerPackagesRoutes(app) {
@@ -13,15 +85,18 @@ function registerPackagesRoutes(app) {
13
85
  querystring: {
14
86
  type: "object",
15
87
  properties: {
16
- kind: { type: "string", description: "Filter by entity kind (plugin, adapter, \u2026)" }
88
+ kind: { type: "string", description: "Filter by entity kind (plugin, adapter, \u2026)" },
89
+ ...queryScopeBodySchemaFragment
17
90
  }
18
91
  }
19
92
  }
20
93
  }, async (request, reply) => {
21
- const { kind } = request.query;
94
+ const query = request.query;
95
+ const ctx = parseQueryScope(query);
96
+ const kind = typeof query.kind === "string" ? query.kind : void 0;
22
97
  const entries = await app.observability.observeOperation(
23
98
  "marketplace.list",
24
- () => app.marketplace.list(kind ? { kind } : void 0)
99
+ () => app.marketplace.list(ctx, kind ? { kind } : void 0)
25
100
  );
26
101
  return reply.send({ entries, total: entries.length });
27
102
  });
@@ -34,15 +109,17 @@ function registerPackagesRoutes(app) {
34
109
  required: ["specs"],
35
110
  properties: {
36
111
  specs: { type: "array", items: { type: "string" }, description: "Package specs (name, name@version, etc.)" },
37
- dev: { type: "boolean", description: "Install as dev dependency" }
112
+ dev: { type: "boolean", description: "Install as dev dependency" },
113
+ ...scopeBodySchemaFragment
38
114
  }
39
115
  }
40
116
  }
41
117
  }, async (request, reply) => {
42
- const { specs, dev } = request.body;
118
+ const body = request.body;
119
+ const ctx = parseMutatingScope(body);
43
120
  const result = await app.observability.observeOperation(
44
121
  "marketplace.install",
45
- () => app.marketplace.install(specs, { dev })
122
+ () => app.marketplace.install(ctx, body.specs, { dev: body.dev })
46
123
  );
47
124
  return reply.code(201).send(result);
48
125
  });
@@ -54,15 +131,17 @@ function registerPackagesRoutes(app) {
54
131
  type: "object",
55
132
  required: ["packageIds"],
56
133
  properties: {
57
- packageIds: { type: "array", items: { type: "string" } }
134
+ packageIds: { type: "array", items: { type: "string" } },
135
+ ...scopeBodySchemaFragment
58
136
  }
59
137
  }
60
138
  }
61
139
  }, async (request, reply) => {
62
- const { packageIds } = request.body;
140
+ const body = request.body;
141
+ const ctx = parseMutatingScope(body);
63
142
  await app.observability.observeOperation(
64
143
  "marketplace.uninstall",
65
- () => app.marketplace.uninstall(packageIds)
144
+ () => app.marketplace.uninstall(ctx, body.packageIds)
66
145
  );
67
146
  return reply.code(204).send();
68
147
  });
@@ -81,17 +160,19 @@ function registerPackagesRoutes(app) {
81
160
  type: "object",
82
161
  required: ["enabled"],
83
162
  properties: {
84
- enabled: { type: "boolean" }
163
+ enabled: { type: "boolean" },
164
+ ...scopeBodySchemaFragment
85
165
  }
86
166
  }
87
167
  }
88
168
  }, async (request, reply) => {
89
169
  const { id } = request.params;
90
- const { enabled } = request.body;
91
- const operation = enabled ? "marketplace.enable" : "marketplace.disable";
92
- const method = enabled ? () => app.marketplace.enable(id) : () => app.marketplace.disable(id);
170
+ const body = request.body;
171
+ const ctx = parseMutatingScope(body);
172
+ const operation = body.enabled ? "marketplace.enable" : "marketplace.disable";
173
+ const method = body.enabled ? () => app.marketplace.enable(ctx, id) : () => app.marketplace.disable(ctx, id);
93
174
  await app.observability.observeOperation(operation, method);
94
- return reply.send({ id, enabled });
175
+ return reply.send({ id, enabled: body.enabled, scope: ctx.scope });
95
176
  });
96
177
  app.post("/packages/:id/update", {
97
178
  schema: {
@@ -103,13 +184,19 @@ function registerPackagesRoutes(app) {
103
184
  properties: {
104
185
  id: { type: "string" }
105
186
  }
187
+ },
188
+ body: {
189
+ type: "object",
190
+ properties: scopeBodySchemaFragment
106
191
  }
107
192
  }
108
193
  }, async (request, reply) => {
109
194
  const { id } = request.params;
195
+ const body = request.body ?? {};
196
+ const ctx = parseMutatingScope(body);
110
197
  const result = await app.observability.observeOperation(
111
198
  "marketplace.update",
112
- () => app.marketplace.update([id])
199
+ () => app.marketplace.update(ctx, [id])
113
200
  );
114
201
  return reply.send(result);
115
202
  });
@@ -128,15 +215,17 @@ function registerPackagesRoutes(app) {
128
215
  type: "object",
129
216
  required: ["path"],
130
217
  properties: {
131
- path: { type: "string", description: "Absolute path to local package" }
218
+ path: { type: "string", description: "Absolute path to local package" },
219
+ ...scopeBodySchemaFragment
132
220
  }
133
221
  }
134
222
  }
135
223
  }, async (request, reply) => {
136
- const { path } = request.body;
224
+ const body = request.body;
225
+ const ctx = parseMutatingScope(body);
137
226
  const result = await app.observability.observeOperation(
138
227
  "marketplace.link",
139
- () => app.marketplace.link(path)
228
+ () => app.marketplace.link(ctx, body.path)
140
229
  );
141
230
  return reply.send(result);
142
231
  });
@@ -150,13 +239,19 @@ function registerPackagesRoutes(app) {
150
239
  properties: {
151
240
  id: { type: "string" }
152
241
  }
242
+ },
243
+ body: {
244
+ type: "object",
245
+ properties: scopeBodySchemaFragment
153
246
  }
154
247
  }
155
248
  }, async (request, reply) => {
156
249
  const { id } = request.params;
250
+ const body = request.body ?? {};
251
+ const ctx = parseMutatingScope(body);
157
252
  await app.observability.observeOperation(
158
253
  "marketplace.unlink",
159
- () => app.marketplace.unlink(id)
254
+ () => app.marketplace.unlink(ctx, id)
160
255
  );
161
256
  return reply.code(204).send();
162
257
  });
@@ -175,7 +270,7 @@ function registerWorkspaceRoutes(app) {
175
270
  include: {
176
271
  type: "array",
177
272
  items: { type: "string" },
178
- description: "Glob patterns to scan (relative to workspace root)"
273
+ description: "Glob patterns to scan (relative to the scope root)"
179
274
  },
180
275
  exclude: {
181
276
  type: "array",
@@ -185,15 +280,21 @@ function registerWorkspaceRoutes(app) {
185
280
  autoEnable: {
186
281
  type: "boolean",
187
282
  description: "Auto-enable newly discovered entries (default: false)"
188
- }
283
+ },
284
+ ...scopeBodySchemaFragment
189
285
  }
190
286
  }
191
287
  }
192
288
  }, async (request, reply) => {
193
289
  const body = request.body;
290
+ const ctx = parseMutatingScope(body);
194
291
  const result = await app.observability.observeOperation(
195
292
  "marketplace.sync",
196
- () => app.marketplace.sync(body)
293
+ () => app.marketplace.sync(ctx, {
294
+ include: body.include,
295
+ exclude: body.exclude,
296
+ autoEnable: body.autoEnable
297
+ })
197
298
  );
198
299
  return reply.send(result);
199
300
  });
@@ -204,12 +305,17 @@ function registerDiagnosticsRoutes(app) {
204
305
  app.get("/diagnostics", {
205
306
  schema: {
206
307
  tags: ["Marketplace"],
207
- summary: "Marketplace health and diagnostics report"
308
+ summary: "Marketplace health and diagnostics report",
309
+ querystring: {
310
+ type: "object",
311
+ properties: scopeBodySchemaFragment
312
+ }
208
313
  }
209
- }, async (_request, reply) => {
314
+ }, async (request, reply) => {
315
+ const ctx = parseMutatingScope(request.query);
210
316
  const report = await app.observability.observeOperation(
211
317
  "marketplace.doctor",
212
- () => app.marketplace.doctor()
318
+ () => app.marketplace.doctor(ctx)
213
319
  );
214
320
  return reply.send(report);
215
321
  });
@@ -267,6 +373,16 @@ async function createServer(opts) {
267
373
  server.decorate("marketplace", opts.service);
268
374
  server.decorate("observability", observability);
269
375
  observability.register(server);
376
+ server.setErrorHandler((err, _request, reply) => {
377
+ if (err instanceof ScopeRequestError || err instanceof ScopeResolutionError || err instanceof AdapterScopeError) {
378
+ return reply.code(400).send({
379
+ error: err.name,
380
+ code: err.code,
381
+ message: err.message
382
+ });
383
+ }
384
+ throw err;
385
+ });
270
386
  server.addHook("onRequest", async (request, reply) => {
271
387
  const requestId = request.headers["x-request-id"] || randomUUID();
272
388
  const traceId = request.headers["x-trace-id"] || randomUUID();
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/routes/packages.ts","../src/routes/workspace.ts","../src/routes/diagnostics.ts","../src/routes/index.ts","../src/server.ts"],"names":["logger"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @module @kb-labs/marketplace-api/routes/packages\n * REST routes for marketplace packages (plugins, adapters, etc.)\n *\n * GET /packages — list installed packages\n * POST /packages — install package(s)\n * DELETE /packages — uninstall package(s)\n * PATCH /packages/:id — update state (enabled/disabled)\n * POST /packages/:id/update — update to latest version\n * POST /packages/:id/link — link local path for development\n * DELETE /packages/:id/link — unlink\n */\n\nimport '../types.js';\nimport type { FastifyInstance } from 'fastify';\nimport type { EntityKind } from '@kb-labs/core-discovery';\n\nexport function registerPackagesRoutes(app: FastifyInstance): void {\n // GET /packages — list installed packages\n app.get('/packages', {\n schema: {\n tags: ['Marketplace'],\n summary: 'List installed packages',\n querystring: {\n type: 'object',\n properties: {\n kind: { type: 'string', description: 'Filter by entity kind (plugin, adapter, …)' },\n },\n },\n },\n }, async (request, reply) => {\n const { kind } = request.query as { kind?: string };\n const entries = await app.observability.observeOperation(\n 'marketplace.list',\n () => app.marketplace.list(kind ? { kind: kind as EntityKind } : undefined),\n );\n return reply.send({ entries, total: entries.length });\n });\n\n // POST /packages — install one or more packages\n app.post('/packages', {\n schema: {\n tags: ['Marketplace'],\n summary: 'Install package(s)',\n body: {\n type: 'object',\n required: ['specs'],\n properties: {\n specs: { type: 'array', items: { type: 'string' }, description: 'Package specs (name, name@version, etc.)' },\n dev: { type: 'boolean', description: 'Install as dev dependency' },\n },\n },\n },\n }, async (request, reply) => {\n const { specs, dev } = request.body as { specs: string[]; dev?: boolean };\n const result = await app.observability.observeOperation(\n 'marketplace.install',\n () => app.marketplace.install(specs, { dev }),\n );\n return reply.code(201).send(result);\n });\n\n // DELETE /packages — uninstall one or more packages\n app.delete('/packages', {\n schema: {\n tags: ['Marketplace'],\n summary: 'Uninstall package(s)',\n body: {\n type: 'object',\n required: ['packageIds'],\n properties: {\n packageIds: { type: 'array', items: { type: 'string' } },\n },\n },\n },\n }, async (request, reply) => {\n const { packageIds } = request.body as { packageIds: string[] };\n await app.observability.observeOperation(\n 'marketplace.uninstall',\n () => app.marketplace.uninstall(packageIds),\n );\n return reply.code(204).send();\n });\n\n // PATCH /packages/:id — update package state (enable/disable)\n app.patch('/packages/:id', {\n schema: {\n tags: ['Marketplace'],\n summary: 'Update package state (enable or disable)',\n params: {\n type: 'object',\n required: ['id'],\n properties: {\n id: { type: 'string' },\n },\n },\n body: {\n type: 'object',\n required: ['enabled'],\n properties: {\n enabled: { type: 'boolean' },\n },\n },\n },\n }, async (request, reply) => {\n const { id } = request.params as { id: string };\n const { enabled } = request.body as { enabled: boolean };\n const operation = enabled ? 'marketplace.enable' : 'marketplace.disable';\n const method = enabled\n ? () => app.marketplace.enable(id)\n : () => app.marketplace.disable(id);\n await app.observability.observeOperation(operation, method);\n return reply.send({ id, enabled });\n });\n\n // POST /packages/:id/update — update package to latest version\n app.post('/packages/:id/update', {\n schema: {\n tags: ['Marketplace'],\n summary: 'Update package to latest version',\n params: {\n type: 'object',\n required: ['id'],\n properties: {\n id: { type: 'string' },\n },\n },\n },\n }, async (request, reply) => {\n const { id } = request.params as { id: string };\n const result = await app.observability.observeOperation(\n 'marketplace.update',\n () => app.marketplace.update([id]),\n );\n return reply.send(result);\n });\n\n // POST /packages/:id/link — link a local path for development\n app.post('/packages/:id/link', {\n schema: {\n tags: ['Marketplace'],\n summary: 'Link a local package path for development',\n params: {\n type: 'object',\n required: ['id'],\n properties: {\n id: { type: 'string' },\n },\n },\n body: {\n type: 'object',\n required: ['path'],\n properties: {\n path: { type: 'string', description: 'Absolute path to local package' },\n },\n },\n },\n }, async (request, reply) => {\n const { path } = request.body as { path: string };\n const result = await app.observability.observeOperation(\n 'marketplace.link',\n () => app.marketplace.link(path),\n );\n return reply.send(result);\n });\n\n // DELETE /packages/:id/link — unlink a local package\n app.delete('/packages/:id/link', {\n schema: {\n tags: ['Marketplace'],\n summary: 'Unlink a local package',\n params: {\n type: 'object',\n required: ['id'],\n properties: {\n id: { type: 'string' },\n },\n },\n },\n }, async (request, reply) => {\n const { id } = request.params as { id: string };\n await app.observability.observeOperation(\n 'marketplace.unlink',\n () => app.marketplace.unlink(id),\n );\n return reply.code(204).send();\n });\n}\n","/**\n * @module @kb-labs/marketplace-api/routes/workspace\n * Workspace-level operations (not tied to a specific package).\n *\n * POST /workspace/sync — scan workspace and populate lock\n */\n\nimport '../types.js';\nimport type { FastifyInstance } from 'fastify';\n\nexport function registerWorkspaceRoutes(app: FastifyInstance): void {\n // POST /workspace/sync — scan for plugins/adapters and populate lock\n app.post('/workspace/sync', {\n schema: {\n tags: ['Marketplace'],\n summary: 'Sync workspace — scan for plugins/adapters and populate lock',\n body: {\n type: 'object',\n required: ['include'],\n properties: {\n include: {\n type: 'array',\n items: { type: 'string' },\n description: 'Glob patterns to scan (relative to workspace root)',\n },\n exclude: {\n type: 'array',\n items: { type: 'string' },\n description: 'Patterns to skip',\n },\n autoEnable: {\n type: 'boolean',\n description: 'Auto-enable newly discovered entries (default: false)',\n },\n },\n },\n },\n }, async (request, reply) => {\n const body = request.body as {\n include: string[];\n exclude?: string[];\n autoEnable?: boolean;\n };\n const result = await app.observability.observeOperation(\n 'marketplace.sync',\n () => app.marketplace.sync(body),\n );\n return reply.send(result);\n });\n}\n","/**\n * @module @kb-labs/marketplace-api/routes/diagnostics\n * Service-level diagnostic endpoints.\n *\n * GET /diagnostics — marketplace health report\n */\n\nimport '../types.js';\nimport type { FastifyInstance } from 'fastify';\n\nexport function registerDiagnosticsRoutes(app: FastifyInstance): void {\n app.get('/diagnostics', {\n schema: {\n tags: ['Marketplace'],\n summary: 'Marketplace health and diagnostics report',\n },\n }, async (_request, reply) => {\n const report = await app.observability.observeOperation(\n 'marketplace.doctor',\n () => app.marketplace.doctor(),\n );\n return reply.send(report);\n });\n}\n","/**\n * @module @kb-labs/marketplace-api/routes\n * Register all marketplace API routes.\n */\n\nimport type { FastifyInstance } from 'fastify';\nimport { registerPackagesRoutes } from './packages.js';\nimport { registerWorkspaceRoutes } from './workspace.js';\nimport { registerDiagnosticsRoutes } from './diagnostics.js';\n\nexport async function registerRoutes(server: FastifyInstance): Promise<void> {\n await server.register(async (app) => {\n registerPackagesRoutes(app);\n registerWorkspaceRoutes(app);\n registerDiagnosticsRoutes(app);\n }, { prefix: '/api/v1/marketplace' });\n}\n","/**\n * @module @kb-labs/marketplace-api/server\n * Fastify server factory for marketplace service.\n */\n\nimport Fastify, { type FastifyInstance } from 'fastify';\nimport {\n createCorrelatedLogger,\n HttpObservabilityCollector,\n createServiceReadyResponse,\n registerOpenAPI,\n} from '@kb-labs/shared-http';\nimport type { ILogger } from '@kb-labs/core-platform';\nimport { registerRoutes } from './routes/index.js';\nimport type { MarketplaceService } from '@kb-labs/marketplace-core';\nimport { randomUUID } from 'node:crypto';\n\nconst DEFAULT_PORT = 5070;\n\nfunction createFallbackLogger(): ILogger {\n const child = (_bindings: Record<string, unknown>): ILogger => createFallbackLogger();\n return {\n trace: () => {},\n debug: () => {},\n info: () => {},\n warn: () => {},\n error: () => {},\n fatal: () => {},\n child,\n };\n}\n\nexport interface CreateServerOptions {\n service: MarketplaceService;\n logger?: ILogger;\n port?: number;\n host?: string;\n}\n\nexport async function createServer(opts: CreateServerOptions): Promise<FastifyInstance> {\n const port = opts.port ?? DEFAULT_PORT;\n const logger = opts.logger ?? createFallbackLogger();\n const observability = new HttpObservabilityCollector({\n serviceId: 'marketplace',\n serviceType: 'http-api',\n version: '0.1.0',\n logsSource: 'marketplace',\n });\n const server = Fastify({\n logger: false, // using platform.logger\n });\n\n // OpenAPI docs\n await registerOpenAPI(server, {\n title: 'KB Labs Marketplace',\n version: '0.1.0',\n description: 'Unified marketplace for plugins, adapters, workflows, and more',\n servers: [\n { url: `http://localhost:${port}`, description: 'Local dev' },\n ],\n ui: process.env.NODE_ENV !== 'production',\n });\n\n // Decorate with service instance\n server.decorate('marketplace', opts.service);\n server.decorate('observability', observability);\n observability.register(server);\n\n server.addHook('onRequest', async (request, reply) => {\n const requestId = (request.headers['x-request-id'] as string | undefined) || randomUUID();\n const traceId = (request.headers['x-trace-id'] as string | undefined) || randomUUID();\n\n request.id = requestId;\n reply.header('X-Request-Id', requestId);\n reply.header('X-Trace-Id', traceId);\n\n (request as any).kbLogger = createCorrelatedLogger(logger, {\n serviceId: 'marketplace',\n logsSource: 'marketplace',\n layer: 'marketplace',\n service: 'request',\n requestId,\n traceId,\n method: request.method,\n url: request.url,\n operation: 'http.request',\n });\n (request as any).kbLogger.info(`→ ${request.method.toUpperCase()} ${request.url}`);\n });\n\n server.addHook('onResponse', async (request, reply) => {\n const logger = (request as any).kbLogger as { info: (message: string, meta?: Record<string, unknown>) => void } | undefined;\n if (!logger) {\n return;\n }\n\n logger.info(`✓ ${request.method.toUpperCase()} ${request.url} ${reply.statusCode}`, {\n statusCode: reply.statusCode,\n });\n });\n\n server.get('/health', async () => ({\n status: 'ok',\n service: 'marketplace',\n ts: Date.now(),\n }));\n\n server.get('/ready', async () =>\n createServiceReadyResponse({\n ready: true,\n components: {\n marketplaceService: {\n ready: true,\n },\n },\n })\n );\n\n server.get('/metrics', async (_request, reply) => {\n reply.header('Content-Type', 'text/plain; version=0.0.4; charset=utf-8');\n return observability.renderPrometheusMetrics('healthy');\n });\n\n server.get('/observability/describe', async () => observability.buildDescribe());\n\n server.get('/observability/health', async () =>\n observability.buildHealth({\n status: 'healthy',\n checks: [\n {\n id: 'marketplace-service',\n status: 'ok',\n message: 'Marketplace service registered',\n },\n ],\n meta: {\n serviceHealthEndpoint: '/health',\n },\n })\n );\n\n // Register routes\n await observability.observeOperation('marketplace.bootstrap', () => registerRoutes(server));\n\n return server;\n}\n"]}
1
+ {"version":3,"sources":["../src/scope-parser.ts","../src/routes/packages.ts","../src/routes/workspace.ts","../src/routes/diagnostics.ts","../src/routes/index.ts","../src/server.ts"],"names":["logger"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @module @kb-labs/marketplace-api/scope-parser\n *\n * Parses scope + projectRoot from HTTP request body/query into the\n * typed context shapes the marketplace service expects. Centralising this\n * logic guarantees the same validation rules (allowed values, required\n * fields, absolute paths, no traversal) are applied uniformly across routes.\n */\n\nimport * as path from 'node:path';\nimport type {\n ScopeContext,\n QueryScopeContext,\n MarketplaceScope,\n MarketplaceQueryScope,\n} from '@kb-labs/marketplace-contracts';\n\nconst MUTATING_SCOPES: readonly MarketplaceScope[] = ['platform', 'project'];\nconst QUERY_SCOPES: readonly MarketplaceQueryScope[] = ['platform', 'project', 'all'];\n\nexport class ScopeRequestError extends Error {\n readonly statusCode = 400;\n readonly code: string;\n constructor(code: string, message: string) {\n super(message);\n this.name = 'ScopeRequestError';\n this.code = code;\n }\n}\n\n/**\n * Extract a `ScopeContext` (mutating calls) from an untyped field map.\n * Server-side default is `platform` — glue layer for callers that don't\n * care about scope (e.g. health-check style tools).\n */\nexport function parseMutatingScope(input: Record<string, unknown> | undefined): ScopeContext {\n const rawScope = input?.scope;\n const scope = normalizeScope(rawScope, MUTATING_SCOPES, 'platform') as MarketplaceScope;\n const projectRoot = normalizeProjectRoot(input?.projectRoot, scope);\n return { scope, projectRoot };\n}\n\n/**\n * Extract a `QueryScopeContext` (read calls). Allows `scope: 'all'`.\n */\nexport function parseQueryScope(input: Record<string, unknown> | undefined): QueryScopeContext {\n const rawScope = input?.scope;\n const scope = normalizeScope(rawScope, QUERY_SCOPES, 'platform') as MarketplaceQueryScope;\n const projectRoot = normalizeProjectRoot(input?.projectRoot, scope);\n return { scope, projectRoot };\n}\n\nfunction normalizeScope<T extends string>(\n raw: unknown,\n allowed: readonly T[],\n fallback: T,\n): T {\n if (raw === undefined || raw === null || raw === '') {\n return fallback;\n }\n if (typeof raw !== 'string' || !allowed.includes(raw as T)) {\n throw new ScopeRequestError(\n 'SCOPE_INVALID',\n `scope must be one of: ${allowed.join(', ')} (got ${JSON.stringify(raw)})`,\n );\n }\n return raw as T;\n}\n\nfunction normalizeProjectRoot(\n raw: unknown,\n scope: MarketplaceScope | MarketplaceQueryScope,\n): string | undefined {\n if (raw === undefined || raw === null || raw === '') {\n // Required only for `project`. For `all`, if absent the service silently\n // degrades to platform-only — callers that want strictness should pass it.\n if (scope === 'project') {\n throw new ScopeRequestError(\n 'SCOPE_PROJECT_ROOT_REQUIRED',\n 'projectRoot is required when scope=\"project\"',\n );\n }\n return undefined;\n }\n if (typeof raw !== 'string') {\n throw new ScopeRequestError('SCOPE_PROJECT_ROOT_TYPE', 'projectRoot must be a string');\n }\n if (!path.isAbsolute(raw)) {\n throw new ScopeRequestError(\n 'SCOPE_PROJECT_ROOT_NOT_ABSOLUTE',\n `projectRoot must be absolute, got \"${raw}\"`,\n );\n }\n if (raw.includes('..')) {\n throw new ScopeRequestError(\n 'SCOPE_PROJECT_ROOT_TRAVERSAL',\n 'projectRoot must not contain \"..\" segments',\n );\n }\n return path.resolve(raw);\n}\n\n/** Fragment added to route body schemas so OpenAPI documents the scope fields. */\nexport const scopeBodySchemaFragment = {\n scope: { type: 'string', enum: MUTATING_SCOPES, description: 'Target scope. Default: platform.' },\n projectRoot: { type: 'string', description: 'Absolute project root (required when scope=\"project\").' },\n} as const;\n\nexport const queryScopeBodySchemaFragment = {\n scope: { type: 'string', enum: QUERY_SCOPES, description: 'Query scope. Default: platform.' },\n projectRoot: { type: 'string', description: 'Absolute project root (required when scope=\"project\", recommended for scope=\"all\").' },\n} as const;\n","/**\n * @module @kb-labs/marketplace-api/routes/packages\n * REST routes for marketplace packages (plugins, adapters, etc.)\n *\n * Every mutating route accepts `{ scope, projectRoot? }` in its body.\n * `GET /packages` accepts the same pair in its query. Default scope is\n * `platform` — CLI clients always pass the explicit scope. Project scope\n * additionally requires an absolute `projectRoot` (validated by\n * `parseMutatingScope` / `parseQueryScope`).\n *\n * GET /packages — list installed packages (supports scope=all)\n * POST /packages — install package(s)\n * DELETE /packages — uninstall package(s)\n * PATCH /packages/:id — update state (enabled/disabled)\n * POST /packages/:id/update — update to latest version\n * POST /packages/:id/link — link local path for development\n * DELETE /packages/:id/link — unlink\n */\n\nimport '../types.js';\nimport type { FastifyInstance } from 'fastify';\nimport type { EntityKind } from '@kb-labs/core-discovery';\nimport {\n parseMutatingScope,\n parseQueryScope,\n queryScopeBodySchemaFragment,\n scopeBodySchemaFragment,\n} from '../scope-parser.js';\n\nexport function registerPackagesRoutes(app: FastifyInstance): void {\n // GET /packages — list installed packages\n app.get('/packages', {\n schema: {\n tags: ['Marketplace'],\n summary: 'List installed packages',\n querystring: {\n type: 'object',\n properties: {\n kind: { type: 'string', description: 'Filter by entity kind (plugin, adapter, …)' },\n ...queryScopeBodySchemaFragment,\n },\n },\n },\n }, async (request, reply) => {\n const query = request.query as Record<string, unknown>;\n const ctx = parseQueryScope(query);\n const kind = typeof query.kind === 'string' ? (query.kind as EntityKind) : undefined;\n const entries = await app.observability.observeOperation(\n 'marketplace.list',\n () => app.marketplace.list(ctx, kind ? { kind } : undefined),\n );\n return reply.send({ entries, total: entries.length });\n });\n\n // POST /packages — install one or more packages\n app.post('/packages', {\n schema: {\n tags: ['Marketplace'],\n summary: 'Install package(s)',\n body: {\n type: 'object',\n required: ['specs'],\n properties: {\n specs: { type: 'array', items: { type: 'string' }, description: 'Package specs (name, name@version, etc.)' },\n dev: { type: 'boolean', description: 'Install as dev dependency' },\n ...scopeBodySchemaFragment,\n },\n },\n },\n }, async (request, reply) => {\n const body = request.body as { specs: string[]; dev?: boolean } & Record<string, unknown>;\n const ctx = parseMutatingScope(body);\n const result = await app.observability.observeOperation(\n 'marketplace.install',\n () => app.marketplace.install(ctx, body.specs, { dev: body.dev }),\n );\n return reply.code(201).send(result);\n });\n\n // DELETE /packages — uninstall one or more packages\n app.delete('/packages', {\n schema: {\n tags: ['Marketplace'],\n summary: 'Uninstall package(s)',\n body: {\n type: 'object',\n required: ['packageIds'],\n properties: {\n packageIds: { type: 'array', items: { type: 'string' } },\n ...scopeBodySchemaFragment,\n },\n },\n },\n }, async (request, reply) => {\n const body = request.body as { packageIds: string[] } & Record<string, unknown>;\n const ctx = parseMutatingScope(body);\n await app.observability.observeOperation(\n 'marketplace.uninstall',\n () => app.marketplace.uninstall(ctx, body.packageIds),\n );\n return reply.code(204).send();\n });\n\n // PATCH /packages/:id — update package state (enable/disable)\n app.patch('/packages/:id', {\n schema: {\n tags: ['Marketplace'],\n summary: 'Update package state (enable or disable)',\n params: {\n type: 'object',\n required: ['id'],\n properties: {\n id: { type: 'string' },\n },\n },\n body: {\n type: 'object',\n required: ['enabled'],\n properties: {\n enabled: { type: 'boolean' },\n ...scopeBodySchemaFragment,\n },\n },\n },\n }, async (request, reply) => {\n const { id } = request.params as { id: string };\n const body = request.body as { enabled: boolean } & Record<string, unknown>;\n const ctx = parseMutatingScope(body);\n const operation = body.enabled ? 'marketplace.enable' : 'marketplace.disable';\n const method = body.enabled\n ? () => app.marketplace.enable(ctx, id)\n : () => app.marketplace.disable(ctx, id);\n await app.observability.observeOperation(operation, method);\n return reply.send({ id, enabled: body.enabled, scope: ctx.scope });\n });\n\n // POST /packages/:id/update — update package to latest version\n app.post('/packages/:id/update', {\n schema: {\n tags: ['Marketplace'],\n summary: 'Update package to latest version',\n params: {\n type: 'object',\n required: ['id'],\n properties: {\n id: { type: 'string' },\n },\n },\n body: {\n type: 'object',\n properties: scopeBodySchemaFragment,\n },\n },\n }, async (request, reply) => {\n const { id } = request.params as { id: string };\n const body = (request.body ?? {}) as Record<string, unknown>;\n const ctx = parseMutatingScope(body);\n const result = await app.observability.observeOperation(\n 'marketplace.update',\n () => app.marketplace.update(ctx, [id]),\n );\n return reply.send(result);\n });\n\n // POST /packages/:id/link — link a local path for development\n app.post('/packages/:id/link', {\n schema: {\n tags: ['Marketplace'],\n summary: 'Link a local package path for development',\n params: {\n type: 'object',\n required: ['id'],\n properties: {\n id: { type: 'string' },\n },\n },\n body: {\n type: 'object',\n required: ['path'],\n properties: {\n path: { type: 'string', description: 'Absolute path to local package' },\n ...scopeBodySchemaFragment,\n },\n },\n },\n }, async (request, reply) => {\n const body = request.body as { path: string } & Record<string, unknown>;\n const ctx = parseMutatingScope(body);\n const result = await app.observability.observeOperation(\n 'marketplace.link',\n () => app.marketplace.link(ctx, body.path),\n );\n return reply.send(result);\n });\n\n // DELETE /packages/:id/link — unlink a local package\n app.delete('/packages/:id/link', {\n schema: {\n tags: ['Marketplace'],\n summary: 'Unlink a local package',\n params: {\n type: 'object',\n required: ['id'],\n properties: {\n id: { type: 'string' },\n },\n },\n body: {\n type: 'object',\n properties: scopeBodySchemaFragment,\n },\n },\n }, async (request, reply) => {\n const { id } = request.params as { id: string };\n const body = (request.body ?? {}) as Record<string, unknown>;\n const ctx = parseMutatingScope(body);\n await app.observability.observeOperation(\n 'marketplace.unlink',\n () => app.marketplace.unlink(ctx, id),\n );\n return reply.code(204).send();\n });\n}\n","/**\n * @module @kb-labs/marketplace-api/routes/workspace\n * Workspace-level operations (not tied to a specific package).\n *\n * POST /workspace/sync — scan workspace and populate lock. Scope-bound:\n * globs resolve against the selected scope root and results land in that\n * scope's lock. Adapter entries are rejected in project scope by the core.\n */\n\nimport '../types.js';\nimport type { FastifyInstance } from 'fastify';\nimport { parseMutatingScope, scopeBodySchemaFragment } from '../scope-parser.js';\n\nexport function registerWorkspaceRoutes(app: FastifyInstance): void {\n // POST /workspace/sync — scan for plugins/adapters and populate lock\n app.post('/workspace/sync', {\n schema: {\n tags: ['Marketplace'],\n summary: 'Sync workspace — scan for plugins/adapters and populate lock',\n body: {\n type: 'object',\n required: ['include'],\n properties: {\n include: {\n type: 'array',\n items: { type: 'string' },\n description: 'Glob patterns to scan (relative to the scope root)',\n },\n exclude: {\n type: 'array',\n items: { type: 'string' },\n description: 'Patterns to skip',\n },\n autoEnable: {\n type: 'boolean',\n description: 'Auto-enable newly discovered entries (default: false)',\n },\n ...scopeBodySchemaFragment,\n },\n },\n },\n }, async (request, reply) => {\n const body = request.body as {\n include: string[];\n exclude?: string[];\n autoEnable?: boolean;\n } & Record<string, unknown>;\n const ctx = parseMutatingScope(body);\n const result = await app.observability.observeOperation(\n 'marketplace.sync',\n () => app.marketplace.sync(ctx, {\n include: body.include,\n exclude: body.exclude,\n autoEnable: body.autoEnable,\n }),\n );\n return reply.send(result);\n });\n}\n","/**\n * @module @kb-labs/marketplace-api/routes/diagnostics\n * Service-level diagnostic endpoints.\n *\n * GET /diagnostics — marketplace health report. Accepts scope + projectRoot\n * in query so callers can probe either scope's lock health.\n */\n\nimport '../types.js';\nimport type { FastifyInstance } from 'fastify';\nimport { parseMutatingScope, scopeBodySchemaFragment } from '../scope-parser.js';\n\nexport function registerDiagnosticsRoutes(app: FastifyInstance): void {\n app.get('/diagnostics', {\n schema: {\n tags: ['Marketplace'],\n summary: 'Marketplace health and diagnostics report',\n querystring: {\n type: 'object',\n properties: scopeBodySchemaFragment,\n },\n },\n }, async (request, reply) => {\n const ctx = parseMutatingScope(request.query as Record<string, unknown>);\n const report = await app.observability.observeOperation(\n 'marketplace.doctor',\n () => app.marketplace.doctor(ctx),\n );\n return reply.send(report);\n });\n}\n","/**\n * @module @kb-labs/marketplace-api/routes\n * Register all marketplace API routes.\n */\n\nimport type { FastifyInstance } from 'fastify';\nimport { registerPackagesRoutes } from './packages.js';\nimport { registerWorkspaceRoutes } from './workspace.js';\nimport { registerDiagnosticsRoutes } from './diagnostics.js';\n\nexport async function registerRoutes(server: FastifyInstance): Promise<void> {\n await server.register(async (app) => {\n registerPackagesRoutes(app);\n registerWorkspaceRoutes(app);\n registerDiagnosticsRoutes(app);\n }, { prefix: '/api/v1/marketplace' });\n}\n","/**\n * @module @kb-labs/marketplace-api/server\n * Fastify server factory for marketplace service.\n */\n\nimport Fastify, { type FastifyInstance } from 'fastify';\nimport {\n createCorrelatedLogger,\n HttpObservabilityCollector,\n createServiceReadyResponse,\n registerOpenAPI,\n} from '@kb-labs/shared-http';\nimport type { ILogger } from '@kb-labs/core-platform';\nimport { registerRoutes } from './routes/index.js';\nimport type { MarketplaceService } from '@kb-labs/marketplace-core';\nimport { ScopeResolutionError, AdapterScopeError } from '@kb-labs/marketplace-core';\nimport { ScopeRequestError } from './scope-parser.js';\nimport { randomUUID } from 'node:crypto';\n\nconst DEFAULT_PORT = 5070;\n\nfunction createFallbackLogger(): ILogger {\n const child = (_bindings: Record<string, unknown>): ILogger => createFallbackLogger();\n return {\n trace: () => {},\n debug: () => {},\n info: () => {},\n warn: () => {},\n error: () => {},\n fatal: () => {},\n child,\n };\n}\n\nexport interface CreateServerOptions {\n service: MarketplaceService;\n logger?: ILogger;\n port?: number;\n host?: string;\n}\n\nexport async function createServer(opts: CreateServerOptions): Promise<FastifyInstance> {\n const port = opts.port ?? DEFAULT_PORT;\n const logger = opts.logger ?? createFallbackLogger();\n const observability = new HttpObservabilityCollector({\n serviceId: 'marketplace',\n serviceType: 'http-api',\n version: '0.1.0',\n logsSource: 'marketplace',\n });\n const server = Fastify({\n logger: false, // using platform.logger\n });\n\n // OpenAPI docs\n await registerOpenAPI(server, {\n title: 'KB Labs Marketplace',\n version: '0.1.0',\n description: 'Unified marketplace for plugins, adapters, workflows, and more',\n servers: [\n { url: `http://localhost:${port}`, description: 'Local dev' },\n ],\n ui: process.env.NODE_ENV !== 'production',\n });\n\n // Decorate with service instance\n server.decorate('marketplace', opts.service);\n server.decorate('observability', observability);\n observability.register(server);\n\n // Scope-related errors → 400. All three share a `code` property so clients\n // can discriminate (SCOPE_INVALID, SCOPE_PROJECT_ROOT_REQUIRED,\n // SCOPE_PROJECT_EQUALS_PLATFORM, MARKETPLACE_ADAPTER_PROJECT_SCOPE, ...).\n server.setErrorHandler((err, _request, reply) => {\n if (\n err instanceof ScopeRequestError ||\n err instanceof ScopeResolutionError ||\n err instanceof AdapterScopeError\n ) {\n return reply.code(400).send({\n error: err.name,\n code: err.code,\n message: err.message,\n });\n }\n // Fallback to Fastify default behaviour.\n throw err;\n });\n\n server.addHook('onRequest', async (request, reply) => {\n const requestId = (request.headers['x-request-id'] as string | undefined) || randomUUID();\n const traceId = (request.headers['x-trace-id'] as string | undefined) || randomUUID();\n\n request.id = requestId;\n reply.header('X-Request-Id', requestId);\n reply.header('X-Trace-Id', traceId);\n\n (request as any).kbLogger = createCorrelatedLogger(logger, {\n serviceId: 'marketplace',\n logsSource: 'marketplace',\n layer: 'marketplace',\n service: 'request',\n requestId,\n traceId,\n method: request.method,\n url: request.url,\n operation: 'http.request',\n });\n (request as any).kbLogger.info(`→ ${request.method.toUpperCase()} ${request.url}`);\n });\n\n server.addHook('onResponse', async (request, reply) => {\n const logger = (request as any).kbLogger as { info: (message: string, meta?: Record<string, unknown>) => void } | undefined;\n if (!logger) {\n return;\n }\n\n logger.info(`✓ ${request.method.toUpperCase()} ${request.url} ${reply.statusCode}`, {\n statusCode: reply.statusCode,\n });\n });\n\n server.get('/health', async () => ({\n status: 'ok',\n service: 'marketplace',\n ts: Date.now(),\n }));\n\n server.get('/ready', async () =>\n createServiceReadyResponse({\n ready: true,\n components: {\n marketplaceService: {\n ready: true,\n },\n },\n })\n );\n\n server.get('/metrics', async (_request, reply) => {\n reply.header('Content-Type', 'text/plain; version=0.0.4; charset=utf-8');\n return observability.renderPrometheusMetrics('healthy');\n });\n\n server.get('/observability/describe', async () => observability.buildDescribe());\n\n server.get('/observability/health', async () =>\n observability.buildHealth({\n status: 'healthy',\n checks: [\n {\n id: 'marketplace-service',\n status: 'ok',\n message: 'Marketplace service registered',\n },\n ],\n meta: {\n serviceHealthEndpoint: '/health',\n },\n })\n );\n\n // Register routes\n await observability.observeOperation('marketplace.bootstrap', () => registerRoutes(server));\n\n return server;\n}\n"]}
package/package.json CHANGED
@@ -5,12 +5,12 @@
5
5
  "fastify": "^5.3.3",
6
6
  "fastify-type-provider-zod": "^6.0.0",
7
7
  "zod": "^3.25.76",
8
- "@kb-labs/marketplace-contracts": "2.31.0",
9
- "@kb-labs/core-contracts": "2.31.0",
10
- "@kb-labs/marketplace-core": "2.31.0",
11
- "@kb-labs/core-platform": "2.31.0",
12
- "@kb-labs/shared-http": "2.31.0",
13
- "@kb-labs/core-discovery": "2.31.0"
8
+ "@kb-labs/core-discovery": "2.32.0",
9
+ "@kb-labs/marketplace-contracts": "2.32.0",
10
+ "@kb-labs/shared-http": "2.32.0",
11
+ "@kb-labs/marketplace-core": "2.32.0",
12
+ "@kb-labs/core-contracts": "2.32.0",
13
+ "@kb-labs/core-platform": "2.32.0"
14
14
  },
15
15
  "description": "Fastify routes for KB Labs marketplace service",
16
16
  "devDependencies": {
@@ -18,7 +18,7 @@
18
18
  "tsup": "^8.5.0",
19
19
  "typescript": "^5",
20
20
  "vitest": "^3.2.4",
21
- "@kb-labs/devkit": "2.31.0"
21
+ "@kb-labs/devkit": "2.32.0"
22
22
  },
23
23
  "engines": {
24
24
  "node": ">=20.0.0",
@@ -38,7 +38,7 @@
38
38
  "sideEffects": false,
39
39
  "type": "module",
40
40
  "types": "./dist/index.d.ts",
41
- "version": "2.31.0",
41
+ "version": "2.32.0",
42
42
  "scripts": {
43
43
  "build": "tsup",
44
44
  "clean": "rimraf dist",