@papercraneai/cli 1.9.0-beta.0 → 1.9.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/lib/dev-server.js +47 -59
  2. package/package.json +1 -1
package/lib/dev-server.js CHANGED
@@ -394,16 +394,44 @@ export async function startDevServer(workspaceDir, port) {
394
394
  // ---- Local handler routes ----
395
395
  server.use(express.json());
396
396
 
397
- // POST /function/local.* execute a local handler
398
- server.post('/function/local.:rest(*)', async (req, res) => {
397
+ // Local handler routes — match /function/local or /function/local.*
398
+ // Uses a middleware pattern since Express 5 path-to-regexp doesn't support .:param(*)
399
+ server.use('/function', async (req, res, next) => {
400
+ // Only handle paths starting with /local
401
+ if (!req.path.startsWith('/local')) return next();
402
+
403
+ const fullPath = req.path.slice(1); // remove leading /
404
+ const segments = fullPath.split('.'); // ['local', 'handler', 'method', ...]
405
+
406
+ // GET /function/local — list all local handlers
407
+ if (segments.length === 1 && req.method === 'GET') {
408
+ try {
409
+ const { loadHandlers, clearHandlerCache } = await import('./handler-loader.js');
410
+ clearHandlerCache(projectDir);
411
+ const handlers = loadHandlers(projectDir);
412
+ const items = [];
413
+ for (const [name, node] of handlers) {
414
+ items.push({
415
+ path: `local.${name}`,
416
+ description: node.description,
417
+ isGroup: !!node.next,
418
+ });
419
+ }
420
+ return res.json({ items });
421
+ } catch (err) {
422
+ return res.status(500).json({ error: err.message });
423
+ }
424
+ }
425
+
426
+ if (segments.length < 2) return next();
427
+
428
+ const handlerName = segments[1];
429
+ const methodPath = segments.slice(2);
430
+
399
431
  try {
400
432
  const { resolve } = await import('./resolver.js');
401
433
  const { loadHandler, clearHandlerCache } = await import('./handler-loader.js');
402
434
 
403
- const segments = req.params.rest.split('.');
404
- const handlerName = segments[0];
405
- const methodPath = segments.slice(1);
406
-
407
435
  // Clear cache on each request during dev for hot-reload
408
436
  clearHandlerCache(projectDir);
409
437
 
@@ -413,45 +441,25 @@ export async function startDevServer(workspaceDir, port) {
413
441
  }
414
442
 
415
443
  const ctx = { credentials: {}, pathParams: {}, cleanup: [] };
416
- const params = req.body?.params || req.body || {};
417
-
418
- const result = await resolve(node, methodPath, ctx, params, 'POST');
419
444
 
420
- // Run cleanup functions
421
- for (const fn of ctx.cleanup || []) {
422
- try { await fn(); } catch {}
423
- }
445
+ if (req.method === 'POST') {
446
+ const params = req.body?.params || req.body || {};
447
+ const result = await resolve(node, methodPath, ctx, params, 'POST');
424
448
 
425
- if (!result.ok) {
426
- const response = { error: result.error };
427
- if (result.schema) response.schema = result.schema;
428
- return res.status(result.status || 500).json(response);
429
- }
449
+ for (const fn of ctx.cleanup || []) {
450
+ try { await fn(); } catch {}
451
+ }
430
452
 
431
- return res.json({ result: result.result });
432
- } catch (err) {
433
- return res.status(500).json({ error: err.message });
434
- }
435
- });
453
+ if (!result.ok) {
454
+ const response = { error: result.error };
455
+ if (result.schema) response.schema = result.schema;
456
+ return res.status(result.status || 500).json(response);
457
+ }
436
458
 
437
- // GET /function/local.* describe a local handler
438
- server.get('/function/local.:rest(*)', async (req, res) => {
439
- try {
440
- const { resolve } = await import('./resolver.js');
441
- const { loadHandler, clearHandlerCache } = await import('./handler-loader.js');
442
-
443
- const segments = req.params.rest.split('.');
444
- const handlerName = segments[0];
445
- const methodPath = segments.slice(1);
446
-
447
- clearHandlerCache(projectDir);
448
-
449
- const node = loadHandler(projectDir, handlerName);
450
- if (!node) {
451
- return res.status(404).json({ error: `Local handler not found: ${handlerName}` });
459
+ return res.json({ result: result.result });
452
460
  }
453
461
 
454
- const ctx = { credentials: {}, pathParams: {}, cleanup: [] };
462
+ // GET describe
455
463
  const result = await resolve(node, methodPath, ctx, {}, 'GET');
456
464
 
457
465
  for (const fn of ctx.cleanup || []) {
@@ -468,26 +476,6 @@ export async function startDevServer(workspaceDir, port) {
468
476
  }
469
477
  });
470
478
 
471
- // GET /function/local — list all local handlers
472
- server.get('/function/local', async (req, res) => {
473
- try {
474
- const { loadHandlers, clearHandlerCache } = await import('./handler-loader.js');
475
- clearHandlerCache(projectDir);
476
- const handlers = loadHandlers(projectDir);
477
- const items = [];
478
- for (const [name, node] of handlers) {
479
- items.push({
480
- path: `local.${name}`,
481
- description: node.description,
482
- isGroup: !!node.next,
483
- });
484
- }
485
- return res.json({ items });
486
- } catch (err) {
487
- return res.status(500).json({ error: err.message });
488
- }
489
- });
490
-
491
479
  // Everything else -> Next.js
492
480
  server.all('/{*path}', (req, res) => handle(req, res));
493
481
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@papercraneai/cli",
3
- "version": "1.9.0-beta.0",
3
+ "version": "1.9.0-beta.1",
4
4
  "description": "CLI tool for managing OAuth credentials for LLM integrations",
5
5
  "main": "index.js",
6
6
  "type": "module",