@kb-labs/marketplace-api 2.32.0 → 2.34.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 +44 -45
- package/dist/index.js.map +1 -1
- package/package.json +8 -8
package/dist/index.js
CHANGED
|
@@ -100,7 +100,7 @@ function registerPackagesRoutes(app) {
|
|
|
100
100
|
);
|
|
101
101
|
return reply.send({ entries, total: entries.length });
|
|
102
102
|
});
|
|
103
|
-
app.post("/packages", {
|
|
103
|
+
app.post("/packages/install", {
|
|
104
104
|
schema: {
|
|
105
105
|
tags: ["Marketplace"],
|
|
106
106
|
summary: "Install package(s)",
|
|
@@ -123,7 +123,7 @@ function registerPackagesRoutes(app) {
|
|
|
123
123
|
);
|
|
124
124
|
return reply.code(201).send(result);
|
|
125
125
|
});
|
|
126
|
-
app.
|
|
126
|
+
app.post("/packages/uninstall", {
|
|
127
127
|
schema: {
|
|
128
128
|
tags: ["Marketplace"],
|
|
129
129
|
summary: "Uninstall package(s)",
|
|
@@ -145,72 +145,75 @@ function registerPackagesRoutes(app) {
|
|
|
145
145
|
);
|
|
146
146
|
return reply.code(204).send();
|
|
147
147
|
});
|
|
148
|
-
app.
|
|
148
|
+
app.post("/packages/enable", {
|
|
149
149
|
schema: {
|
|
150
150
|
tags: ["Marketplace"],
|
|
151
|
-
summary: "
|
|
152
|
-
|
|
151
|
+
summary: "Enable a package",
|
|
152
|
+
body: {
|
|
153
153
|
type: "object",
|
|
154
|
-
required: ["
|
|
154
|
+
required: ["packageId"],
|
|
155
155
|
properties: {
|
|
156
|
-
|
|
156
|
+
packageId: { type: "string" },
|
|
157
|
+
...scopeBodySchemaFragment
|
|
157
158
|
}
|
|
158
|
-
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}, async (request, reply) => {
|
|
162
|
+
const body = request.body;
|
|
163
|
+
const ctx = parseMutatingScope(body);
|
|
164
|
+
await app.observability.observeOperation(
|
|
165
|
+
"marketplace.enable",
|
|
166
|
+
() => app.marketplace.enable(ctx, body.packageId)
|
|
167
|
+
);
|
|
168
|
+
return reply.send({ id: body.packageId, enabled: true, scope: ctx.scope });
|
|
169
|
+
});
|
|
170
|
+
app.post("/packages/disable", {
|
|
171
|
+
schema: {
|
|
172
|
+
tags: ["Marketplace"],
|
|
173
|
+
summary: "Disable a package",
|
|
159
174
|
body: {
|
|
160
175
|
type: "object",
|
|
161
|
-
required: ["
|
|
176
|
+
required: ["packageId"],
|
|
162
177
|
properties: {
|
|
163
|
-
|
|
178
|
+
packageId: { type: "string" },
|
|
164
179
|
...scopeBodySchemaFragment
|
|
165
180
|
}
|
|
166
181
|
}
|
|
167
182
|
}
|
|
168
183
|
}, async (request, reply) => {
|
|
169
|
-
const { id } = request.params;
|
|
170
184
|
const body = request.body;
|
|
171
185
|
const ctx = parseMutatingScope(body);
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
186
|
+
await app.observability.observeOperation(
|
|
187
|
+
"marketplace.disable",
|
|
188
|
+
() => app.marketplace.disable(ctx, body.packageId)
|
|
189
|
+
);
|
|
190
|
+
return reply.send({ id: body.packageId, enabled: false, scope: ctx.scope });
|
|
176
191
|
});
|
|
177
|
-
app.post("/packages
|
|
192
|
+
app.post("/packages/update", {
|
|
178
193
|
schema: {
|
|
179
194
|
tags: ["Marketplace"],
|
|
180
|
-
summary: "Update package to latest version",
|
|
181
|
-
|
|
195
|
+
summary: "Update package(s) to latest version",
|
|
196
|
+
body: {
|
|
182
197
|
type: "object",
|
|
183
|
-
required: ["id"],
|
|
184
198
|
properties: {
|
|
185
|
-
|
|
199
|
+
packageIds: { type: "array", items: { type: "string" }, description: 'Specific ids to update; omit for "all installed"' },
|
|
200
|
+
...scopeBodySchemaFragment
|
|
186
201
|
}
|
|
187
|
-
},
|
|
188
|
-
body: {
|
|
189
|
-
type: "object",
|
|
190
|
-
properties: scopeBodySchemaFragment
|
|
191
202
|
}
|
|
192
203
|
}
|
|
193
204
|
}, async (request, reply) => {
|
|
194
|
-
const { id } = request.params;
|
|
195
205
|
const body = request.body ?? {};
|
|
196
206
|
const ctx = parseMutatingScope(body);
|
|
197
207
|
const result = await app.observability.observeOperation(
|
|
198
208
|
"marketplace.update",
|
|
199
|
-
() => app.marketplace.update(ctx,
|
|
209
|
+
() => app.marketplace.update(ctx, body.packageIds)
|
|
200
210
|
);
|
|
201
211
|
return reply.send(result);
|
|
202
212
|
});
|
|
203
|
-
app.post("/packages
|
|
213
|
+
app.post("/packages/link", {
|
|
204
214
|
schema: {
|
|
205
215
|
tags: ["Marketplace"],
|
|
206
216
|
summary: "Link a local package path for development",
|
|
207
|
-
params: {
|
|
208
|
-
type: "object",
|
|
209
|
-
required: ["id"],
|
|
210
|
-
properties: {
|
|
211
|
-
id: { type: "string" }
|
|
212
|
-
}
|
|
213
|
-
},
|
|
214
217
|
body: {
|
|
215
218
|
type: "object",
|
|
216
219
|
required: ["path"],
|
|
@@ -229,29 +232,25 @@ function registerPackagesRoutes(app) {
|
|
|
229
232
|
);
|
|
230
233
|
return reply.send(result);
|
|
231
234
|
});
|
|
232
|
-
app.
|
|
235
|
+
app.post("/packages/unlink", {
|
|
233
236
|
schema: {
|
|
234
237
|
tags: ["Marketplace"],
|
|
235
238
|
summary: "Unlink a local package",
|
|
236
|
-
|
|
239
|
+
body: {
|
|
237
240
|
type: "object",
|
|
238
|
-
required: ["
|
|
241
|
+
required: ["packageId"],
|
|
239
242
|
properties: {
|
|
240
|
-
|
|
243
|
+
packageId: { type: "string" },
|
|
244
|
+
...scopeBodySchemaFragment
|
|
241
245
|
}
|
|
242
|
-
},
|
|
243
|
-
body: {
|
|
244
|
-
type: "object",
|
|
245
|
-
properties: scopeBodySchemaFragment
|
|
246
246
|
}
|
|
247
247
|
}
|
|
248
248
|
}, async (request, reply) => {
|
|
249
|
-
const
|
|
250
|
-
const body = request.body ?? {};
|
|
249
|
+
const body = request.body;
|
|
251
250
|
const ctx = parseMutatingScope(body);
|
|
252
251
|
await app.observability.observeOperation(
|
|
253
252
|
"marketplace.unlink",
|
|
254
|
-
() => app.marketplace.unlink(ctx,
|
|
253
|
+
() => app.marketplace.unlink(ctx, body.packageId)
|
|
255
254
|
);
|
|
256
255
|
return reply.code(204).send();
|
|
257
256
|
});
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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"]}
|
|
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 * The URL surface is intentionally action-oriented (\"POST /packages/link\")\n * rather than resource-style (\"POST /packages/:id/link\"). Plugin IDs carry\n * `@` and `/` (`@kb-labs/demo-entry`), which round-trip badly through proxies\n * and API gateways as URL-encoded path segments. Every action takes its\n * target id from the request body instead, eliminating an entire class of\n * routing failures.\n *\n * GET /packages — list installed packages (query: scope, projectRoot, kind)\n * POST /packages/install — install package(s)\n * POST /packages/uninstall— uninstall package(s)\n * POST /packages/link — link a local path\n * POST /packages/unlink — unlink a package\n * POST /packages/enable — mark a package enabled\n * POST /packages/disable — mark a package disabled\n * POST /packages/update — update package(s) to latest\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 — install one or more packages\n app.post('/packages/install', {\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 // POST /packages/uninstall — uninstall one or more packages\n app.post('/packages/uninstall', {\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 // POST /packages/enable — enable a package\n app.post('/packages/enable', {\n schema: {\n tags: ['Marketplace'],\n summary: 'Enable a package',\n body: {\n type: 'object',\n required: ['packageId'],\n properties: {\n packageId: { type: 'string' },\n ...scopeBodySchemaFragment,\n },\n },\n },\n }, async (request, reply) => {\n const body = request.body as { packageId: string } & Record<string, unknown>;\n const ctx = parseMutatingScope(body);\n await app.observability.observeOperation(\n 'marketplace.enable',\n () => app.marketplace.enable(ctx, body.packageId),\n );\n return reply.send({ id: body.packageId, enabled: true, scope: ctx.scope });\n });\n\n // POST /packages/disable — disable a package\n app.post('/packages/disable', {\n schema: {\n tags: ['Marketplace'],\n summary: 'Disable a package',\n body: {\n type: 'object',\n required: ['packageId'],\n properties: {\n packageId: { type: 'string' },\n ...scopeBodySchemaFragment,\n },\n },\n },\n }, async (request, reply) => {\n const body = request.body as { packageId: string } & Record<string, unknown>;\n const ctx = parseMutatingScope(body);\n await app.observability.observeOperation(\n 'marketplace.disable',\n () => app.marketplace.disable(ctx, body.packageId),\n );\n return reply.send({ id: body.packageId, enabled: false, scope: ctx.scope });\n });\n\n // POST /packages/update — update package(s) to latest version\n app.post('/packages/update', {\n schema: {\n tags: ['Marketplace'],\n summary: 'Update package(s) to latest version',\n body: {\n type: 'object',\n properties: {\n packageIds: { type: 'array', items: { type: 'string' }, description: 'Specific ids to update; omit for \"all installed\"' },\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 const result = await app.observability.observeOperation(\n 'marketplace.update',\n () => app.marketplace.update(ctx, body.packageIds),\n );\n return reply.send(result);\n });\n\n // POST /packages/link — link a local path for development\n app.post('/packages/link', {\n schema: {\n tags: ['Marketplace'],\n summary: 'Link a local package path for development',\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 // POST /packages/unlink — unlink a local package\n app.post('/packages/unlink', {\n schema: {\n tags: ['Marketplace'],\n summary: 'Unlink a local package',\n body: {\n type: 'object',\n required: ['packageId'],\n properties: {\n packageId: { type: 'string' },\n ...scopeBodySchemaFragment,\n },\n },\n },\n }, async (request, reply) => {\n const body = request.body as { packageId: string } & Record<string, unknown>;\n const ctx = parseMutatingScope(body);\n await app.observability.observeOperation(\n 'marketplace.unlink',\n () => app.marketplace.unlink(ctx, body.packageId),\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/core-
|
|
9
|
-
"@kb-labs/
|
|
10
|
-
"@kb-labs/
|
|
11
|
-
"@kb-labs/marketplace-
|
|
12
|
-
"@kb-labs/core
|
|
13
|
-
"@kb-labs/
|
|
8
|
+
"@kb-labs/core-contracts": "2.34.0",
|
|
9
|
+
"@kb-labs/core-discovery": "2.34.0",
|
|
10
|
+
"@kb-labs/core-platform": "2.34.0",
|
|
11
|
+
"@kb-labs/marketplace-contracts": "2.34.0",
|
|
12
|
+
"@kb-labs/marketplace-core": "2.34.0",
|
|
13
|
+
"@kb-labs/shared-http": "2.34.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.
|
|
21
|
+
"@kb-labs/devkit": "2.34.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.
|
|
41
|
+
"version": "2.34.0",
|
|
42
42
|
"scripts": {
|
|
43
43
|
"build": "tsup",
|
|
44
44
|
"clean": "rimraf dist",
|