@yrest/cli 0.7.0 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,4 +1,8 @@
1
- # yRest
1
+ <div align="center">
2
+ <img src="assets/yRest-banner.png" alt="yRest" width="100%" />
3
+ </div>
4
+
5
+ <br/>
2
6
 
3
7
  [![npm version](https://img.shields.io/npm/v/@yrest/cli)](https://www.npmjs.com/package/@yrest/cli)
4
8
  [![npm downloads](https://img.shields.io/npm/dw/@yrest/cli)](https://www.npmjs.com/package/@yrest/cli)
@@ -6,6 +10,7 @@
6
10
  [![CI](https://github.com/aggiovato/yRest/actions/workflows/ci.yml/badge.svg)](https://github.com/aggiovato/yRest/actions)
7
11
  [![Node](https://img.shields.io/node/v/@yrest/cli)](https://www.npmjs.com/package/@yrest/cli)
8
12
  [![TypeScript](https://img.shields.io/badge/TypeScript-ready-blue)](https://www.typescriptlang.org/)
13
+ [![Socket](https://badge.socket.dev/npm/package/@yrest/cli/0.8.1)](https://socket.dev/npm/package/@yrest/cli)
9
14
 
10
15
  YAML-powered json-server alternative. Zero-config REST API mock server with full CRUD, relations, filters and snapshots from a `db.yml` file.
11
16
 
@@ -157,6 +162,7 @@ npx @yrest/cli serve db.yml --handlers yrest.handlers.js
157
162
  | `--pageable [n]` | `false` | Wrap GET collection responses in `{ data, pagination }`. Optional limit |
158
163
  | `--snapshot` | `false` | Save initial state snapshot and expose `/_snapshot` endpoints |
159
164
  | `--handlers <file>` | _(none)_ | Path to a JS file exporting handler functions for custom routes |
165
+ | `--id-strategy` | `increment` | Id generation for new items: `increment` (auto-int) or `uuid` |
160
166
 
161
167
  All flags can also be set in `yrest.config.yml` (see below). CLI flags always take priority over the config file.
162
168
 
@@ -178,6 +184,7 @@ host: localhost
178
184
  # pageable: false # true (limit 10), or a number (custom limit)
179
185
  # snapshot: false
180
186
  # handlers: yrest.handlers.js
187
+ # idStrategy: increment # increment or uuid
181
188
  ```
182
189
 
183
190
  **Priority order** (highest wins): CLI flags → `yrest.config.yml` → schema defaults.
@@ -595,6 +602,36 @@ _routes:
595
602
  body: { data: loaded }
596
603
  ```
597
604
 
605
+ ### Error injection
606
+
607
+ Force a custom route to always return a specific HTTP error, regardless of handlers, scenarios or the static response. Useful for simulating outages, payment failures or auth errors:
608
+
609
+ ```yaml
610
+ _routes:
611
+ - method: GET
612
+ path: /payments
613
+ error: 503
614
+ errorBody:
615
+ message: Service temporarily unavailable
616
+ retryAfter: 30
617
+
618
+ - method: POST
619
+ path: /checkout
620
+ error: 402
621
+ errorBody:
622
+ error: Payment required
623
+
624
+ - method: GET
625
+ path: /slow-failure
626
+ delay: 400
627
+ error: 500
628
+ ```
629
+
630
+ - `error` takes priority over `handler`, `scenarios` and `response` — the route always returns this status.
631
+ - `errorBody` is optional. If omitted, the default body is `{ "error": "Forced error NNN" }`.
632
+ - `delay` still applies before the error is returned.
633
+ - Shown in `/_about` with a red `error·NNN` badge.
634
+
598
635
  ### Handler functions
599
636
 
600
637
  For routes that need real logic (conditional responses, stateful mocks, request inspection), reference a JavaScript function via the `handler:` field:
@@ -960,6 +997,8 @@ const server = createYrestServer({
960
997
  | Request validation with JSON Schema | 🔜 |
961
998
  | Conditional scenarios (`scenarios:`, `otherwise:`) | ✅ |
962
999
  | Per-route delay (`delay:`) | ✅ |
1000
+ | Error injection (`error:` in `_routes`) | ✅ |
1001
+ | Configurable ID strategy (`idStrategy`) | ✅ |
963
1002
 
964
1003
  ---
965
1004
 
Binary file
Binary file
Binary file
Binary file
Binary file
package/dist/cli/index.js CHANGED
@@ -132,8 +132,8 @@ function registerInit(program2) {
132
132
  }
133
133
 
134
134
  // src/cli/commands/serve.ts
135
- var import_node_fs5 = require("fs");
136
- var import_node_path3 = require("path");
135
+ var import_node_fs6 = require("fs");
136
+ var import_node_path4 = require("path");
137
137
 
138
138
  // src/storage/yrestStorage.ts
139
139
  var import_node_fs2 = require("fs");
@@ -223,6 +223,11 @@ function createYrestStorage(filePath) {
223
223
  var import_fastify = __toESM(require("fastify"));
224
224
  var import_cors = __toESM(require("@fastify/cors"));
225
225
 
226
+ // src/router/templates/about.template.ts
227
+ var import_node_fs3 = require("fs");
228
+ var import_node_path3 = require("path");
229
+ var import_node_url = require("url");
230
+
226
231
  // src/utils/interpolate.ts
227
232
  var import_node_crypto2 = require("crypto");
228
233
  function getPath(obj, path) {
@@ -270,6 +275,15 @@ function hasTemplates(value) {
270
275
  }
271
276
 
272
277
  // src/router/templates/about.template.ts
278
+ var _dir = (0, import_node_path3.dirname)((0, import_node_url.fileURLToPath)(importMetaUrl));
279
+ var LOGO_SRC = (() => {
280
+ try {
281
+ const buf = (0, import_node_fs3.readFileSync)((0, import_node_path3.join)(_dir, "../../assets/logo-color.png"));
282
+ return `data:image/png;base64,${buf.toString("base64")}`;
283
+ } catch {
284
+ return "";
285
+ }
286
+ })();
273
287
  var METHOD_COLOR = {
274
288
  GET: "#3fb950",
275
289
  POST: "#58a6ff",
@@ -278,8 +292,11 @@ var METHOD_COLOR = {
278
292
  DELETE: "#f85149",
279
293
  fn: "#f0883e"
280
294
  };
295
+ function escapeHtml(str) {
296
+ return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
297
+ }
281
298
  function badge(label, color, bg) {
282
- return `<span class="badge" style="background:${bg};color:${color};border:1px solid ${color}40">${label}</span>`;
299
+ return `<span class="badge" style="background:${bg};color:${color};border:1px solid ${color}40">${escapeHtml(label)}</span>`;
283
300
  }
284
301
  function methodBadge(method) {
285
302
  const color = METHOD_COLOR[method] ?? "#7d8590";
@@ -289,7 +306,7 @@ function endpointRow(method, path, desc) {
289
306
  return `
290
307
  <tr>
291
308
  <td class="method-cell">${methodBadge(method)}</td>
292
- <td class="path-cell"><code>${path}</code></td>
309
+ <td class="path-cell"><code>${escapeHtml(path)}</code></td>
293
310
  <td class="desc-cell">${desc}</td>
294
311
  </tr>`;
295
312
  }
@@ -323,7 +340,7 @@ function resourceAccordion(name, base, isOpen) {
323
340
  return `
324
341
  <details class="resource-card" ${isOpen ? "open" : ""}>
325
342
  <summary>
326
- <span class="resource-name">/${name}</span>
343
+ <span class="resource-name">/${escapeHtml(name)}</span>
327
344
  <span class="route-count">6 routes</span>
328
345
  </summary>
329
346
  <table>
@@ -407,7 +424,7 @@ curl -X POST ${host}/_snapshot/reset`
407
424
  }
408
425
  if (firstCustomRoute) {
409
426
  const method = firstCustomRoute.method?.toUpperCase() ?? "GET";
410
- const fullPath = `${host}${base}${firstCustomRoute.path}`;
427
+ const fullPath = `${host}${base}${escapeHtml(firstCustomRoute.path ?? "")}`;
411
428
  const curlFlag = method === "GET" ? "" : `-X ${method} `;
412
429
  examples.push(`# Custom route
413
430
  curl ${curlFlag}${fullPath}`);
@@ -428,6 +445,8 @@ function generateAboutHtml(storage, options, handlers = /* @__PURE__ */ new Map(
428
445
  modes.push(badge(`pageable \xB7 limit ${options.pageable.limit}`, "#34d399", "#34d39918"));
429
446
  if (options.snapshot) modes.push(badge("snapshot", "#c084fc", "#c084fc18"));
430
447
  if (handlers.size > 0) modes.push(badge(`handlers \xB7 ${handlers.size}`, "#f0883e", "#f0883e18"));
448
+ if (options.idStrategy !== "increment")
449
+ modes.push(badge(`id \xB7 ${options.idStrategy}`, "#a371f7", "#a371f718"));
431
450
  const accordions = collections.map((col, i) => resourceAccordion(col, base, i === 0)).join("");
432
451
  const nestedRows = [];
433
452
  for (const [child, fields] of Object.entries(relations)) {
@@ -470,6 +489,9 @@ function generateAboutHtml(storage, options, handlers = /* @__PURE__ */ new Map(
470
489
  ${customRoutes.map((r) => {
471
490
  const fullPath = `${base}${r.path}`;
472
491
  const tags = [];
492
+ if (r.error) {
493
+ tags.push(`<span style="color:#f85149;font-size:11px">error\xB7${r.error}</span>`);
494
+ }
473
495
  if (r.delay && r.delay > 0) {
474
496
  tags.push(`<span style="color:#fb923c;font-size:11px">delay\xB7${r.delay}ms</span>`);
475
497
  }
@@ -483,9 +505,12 @@ function generateAboutHtml(storage, options, handlers = /* @__PURE__ */ new Map(
483
505
  tags.push(`<span style="color:var(--text-muted);font-size:11px">otherwise</span>`);
484
506
  }
485
507
  let desc;
486
- if (r.handler) {
508
+ if (r.error) {
509
+ desc = `Error injection \u2014 <code>${r.error}</code>`;
510
+ } else if (r.handler) {
487
511
  const found = handlers.has(r.handler);
488
- desc = found ? `Handler \u2014 <code>${r.handler}()</code>` : `Handler \u2014 <code>${r.handler}()</code> <span style="color:#f85149">(not loaded)</span>`;
512
+ const handlerName = escapeHtml(r.handler);
513
+ desc = found ? `Handler \u2014 <code>${handlerName}()</code>` : `Handler \u2014 <code>${handlerName}()</code> <span style="color:#f85149">(not loaded)</span>`;
489
514
  } else if (r.scenarios?.length) {
490
515
  const hasTemplateInScenarios = r.scenarios.some((s) => s.response.body != null && hasTemplates(s.response.body)) || r.otherwise?.body != null && hasTemplates(r.otherwise.body);
491
516
  desc = hasTemplateInScenarios ? `Scenarios \u2014 <code>{{\u2026}}</code>` : `Scenarios`;
@@ -647,7 +672,7 @@ function generateAboutHtml(storage, options, handlers = /* @__PURE__ */ new Map(
647
672
 
648
673
  <div class="banner">
649
674
  <div class="banner-inner">
650
- <h1><span class="y">y</span><span class="rest">Rest</span></h1>
675
+ ${LOGO_SRC ? `<img src="${LOGO_SRC}" alt="yRest" height="68" style="display:block;margin-bottom:0px" />` : `<h1><span class="y">y</span><span class="rest">Rest</span></h1>`}
651
676
  <p>Zero-config REST API mock server</p>
652
677
  <div class="banner-meta">
653
678
  <span>URL <strong>${host}</strong></span>
@@ -730,6 +755,10 @@ function nextId(items) {
730
755
  const ids = items.map((i) => i["id"]).filter((id) => typeof id === "number");
731
756
  return ids.length > 0 ? Math.max(...ids) + 1 : 1;
732
757
  }
758
+ function generateId(items, strategy) {
759
+ if (strategy === "uuid") return crypto.randomUUID();
760
+ return nextId(items);
761
+ }
733
762
  function firstParam(value) {
734
763
  if (value === void 0) return void 0;
735
764
  return Array.isArray(value) ? value[0] : value;
@@ -754,6 +783,7 @@ function applyOperator(itemValue, op, filterValue) {
754
783
  case "_start":
755
784
  return strItem.toLowerCase().startsWith(filterValue.toLowerCase());
756
785
  case "_regex": {
786
+ if (filterValue.length > 200) return false;
757
787
  try {
758
788
  return new RegExp(filterValue, "i").test(strItem);
759
789
  } catch {
@@ -817,10 +847,10 @@ function findById(items, id) {
817
847
  function findIndexById(items, id) {
818
848
  return items.findIndex((i) => String(i["id"]) === id);
819
849
  }
820
- function createItem(storage, resource, body) {
850
+ function createItem(storage, resource, body, idStrategy = "increment") {
821
851
  const collection = storage.getCollection(resource) ?? [];
822
852
  const item = {
823
- id: body["id"] !== void 0 ? body["id"] : nextId(collection),
853
+ id: body["id"] !== void 0 ? body["id"] : generateId(collection, idStrategy),
824
854
  ...body
825
855
  };
826
856
  storage.setCollection(resource, [...collection, item]);
@@ -998,7 +1028,12 @@ var CollectionRouteCommand = class {
998
1028
  if (!req.body || typeof req.body !== "object" || Array.isArray(req.body)) {
999
1029
  return reply.status(400).send({ error: "Request body must be a JSON object" });
1000
1030
  }
1001
- const item = createItem(this.storage, this.resource, req.body);
1031
+ const item = createItem(
1032
+ this.storage,
1033
+ this.resource,
1034
+ req.body,
1035
+ this.options.idStrategy
1036
+ );
1002
1037
  return reply.status(201).send(expandItems(item, req.query, this.resource, this.storage));
1003
1038
  });
1004
1039
  }
@@ -1088,6 +1123,10 @@ var CustomRouteCommand = class {
1088
1123
  if (route.delay && route.delay > 0) {
1089
1124
  await new Promise((resolve5) => setTimeout(resolve5, route.delay));
1090
1125
  }
1126
+ if (route.error) {
1127
+ const body2 = route.errorBody ?? { error: `Forced error ${route.error}` };
1128
+ return reply.status(route.error).send(body2);
1129
+ }
1091
1130
  for (const [key, value] of Object.entries(headers)) {
1092
1131
  reply.header(key, value);
1093
1132
  }
@@ -1384,22 +1423,36 @@ var yrestOptionsSchema = import_zod.z.object({
1384
1423
  pageable: import_zod.z.union([import_zod.z.boolean(), import_zod.z.coerce.number().int().positive()]).default(false).transform((v) => ({
1385
1424
  enabled: v !== false,
1386
1425
  limit: v === false || v === true ? 10 : v
1387
- }))
1426
+ })),
1427
+ /**
1428
+ * Strategy used to generate `id` values for new items when no `id` is provided in the body.
1429
+ *
1430
+ * - `"increment"` (default) — next integer above the current max id in the collection.
1431
+ * - `"uuid"` — a random UUID v4 string (`crypto.randomUUID()`).
1432
+ */
1433
+ idStrategy: import_zod.z.enum(["increment", "uuid"]).default("increment")
1388
1434
  });
1389
1435
 
1390
1436
  // src/config/loadConfigFile.ts
1391
- var import_node_fs3 = require("fs");
1437
+ var import_node_fs4 = require("fs");
1392
1438
  var import_yaml2 = require("yaml");
1393
1439
  function loadConfigFile(configPath) {
1394
- if (!(0, import_node_fs3.existsSync)(configPath)) return {};
1395
- const raw = (0, import_node_fs3.readFileSync)(configPath, "utf8");
1440
+ if (!(0, import_node_fs4.existsSync)(configPath)) return {};
1441
+ const raw = (0, import_node_fs4.readFileSync)(configPath, "utf8");
1396
1442
  return (0, import_yaml2.parse)(raw) ?? {};
1397
1443
  }
1398
1444
 
1399
1445
  // src/utils/handlers.ts
1400
- var import_node_fs4 = require("fs");
1446
+ var import_node_fs5 = require("fs");
1447
+ var ALLOWED_EXTENSIONS = [".js", ".mjs", ".cjs"];
1401
1448
  async function loadHandlers(filePath) {
1402
- if (!(0, import_node_fs4.existsSync)(filePath)) return /* @__PURE__ */ new Map();
1449
+ if (!(0, import_node_fs5.existsSync)(filePath)) return /* @__PURE__ */ new Map();
1450
+ if (!ALLOWED_EXTENSIONS.some((ext) => filePath.endsWith(ext))) {
1451
+ console.error(
1452
+ ` \x1B[31m[handlers] ${filePath} \u2014 only .js, .mjs and .cjs files are allowed\x1B[0m`
1453
+ );
1454
+ return /* @__PURE__ */ new Map();
1455
+ }
1403
1456
  try {
1404
1457
  const mod = await import(filePath);
1405
1458
  const map = /* @__PURE__ */ new Map();
@@ -1429,8 +1482,12 @@ function registerServe(program2) {
1429
1482
  ).option(
1430
1483
  "--handlers <file>",
1431
1484
  "Path to a JavaScript file exporting custom route handler functions"
1485
+ ).option(
1486
+ "--id-strategy <strategy>",
1487
+ "Id generation strategy for new items: increment (default) or uuid",
1488
+ "increment"
1432
1489
  ).action(async (file, flags, cmd) => {
1433
- const fileConfig = loadConfigFile((0, import_node_path3.join)(process.cwd(), "yrest.config.yml"));
1490
+ const fileConfig = loadConfigFile((0, import_node_path4.join)(process.cwd(), "yrest.config.yml"));
1434
1491
  const cliOverrides = Object.fromEntries(
1435
1492
  Object.entries(flags).filter(([key]) => cmd.getOptionValueSource(key) === "cli")
1436
1493
  );
@@ -1449,7 +1506,7 @@ function registerServe(program2) {
1449
1506
  console.error(`Error: cannot load "${options.file}" \u2014 ${msg}`);
1450
1507
  process.exit(1);
1451
1508
  }
1452
- const handlers = options.handlers ? await loadHandlers((0, import_node_path3.resolve)(options.handlers)) : /* @__PURE__ */ new Map();
1509
+ const handlers = options.handlers ? await loadHandlers((0, import_node_path4.resolve)(options.handlers)) : /* @__PURE__ */ new Map();
1453
1510
  const yrestServer = createYrestServerFromStorage(storage, options, handlers);
1454
1511
  await yrestServer.start();
1455
1512
  const collections = Object.keys(storage.getData());
@@ -1511,9 +1568,9 @@ function registerServe(program2) {
1511
1568
  ${dim(modes.map((m) => `[${m}]`).join(" "))}`);
1512
1569
  console.log("");
1513
1570
  if (options.watch) {
1514
- const absFile = (0, import_node_path3.resolve)(options.file);
1571
+ const absFile = (0, import_node_path4.resolve)(options.file);
1515
1572
  let debounce;
1516
- (0, import_node_fs5.watchFile)(absFile, { interval: 300 }, (curr, prev) => {
1573
+ (0, import_node_fs6.watchFile)(absFile, { interval: 300 }, (curr, prev) => {
1517
1574
  if (curr.mtimeMs === prev.mtimeMs) return;
1518
1575
  clearTimeout(debounce);
1519
1576
  debounce = setTimeout(() => {
@@ -1533,8 +1590,8 @@ function registerServe(program2) {
1533
1590
  }
1534
1591
 
1535
1592
  // src/cli/commands/handler.ts
1536
- var import_node_fs6 = require("fs");
1537
- var import_node_path4 = require("path");
1593
+ var import_node_fs7 = require("fs");
1594
+ var import_node_path5 = require("path");
1538
1595
  var import_yaml3 = require("yaml");
1539
1596
  var HANDLERS_FILE_HEADER = `// yrest handlers \u2014 loaded via "handlers:" in yrest.config.yml
1540
1597
  // Handler signature: (req: HandlerRequest) => HandlerResponse | Promise<HandlerResponse>
@@ -1561,44 +1618,44 @@ function registerHandler(program2) {
1561
1618
  "--register",
1562
1619
  "Also add a _routes entry to db.yml linking this handler to method + path"
1563
1620
  ).action((name, flags) => {
1564
- const fileConfig = loadConfigFile((0, import_node_path4.join)(process.cwd(), "yrest.config.yml"));
1565
- const handlersPath = (0, import_node_path4.resolve)(
1621
+ const fileConfig = loadConfigFile((0, import_node_path5.join)(process.cwd(), "yrest.config.yml"));
1622
+ const handlersPath = (0, import_node_path5.resolve)(
1566
1623
  fileConfig.handlers ?? "yrest.handlers.js"
1567
1624
  );
1568
- const dbPath = (0, import_node_path4.resolve)(fileConfig.file ?? "db.yml");
1569
- if (!(0, import_node_fs6.existsSync)(handlersPath)) {
1570
- (0, import_node_fs6.writeFileSync)(
1625
+ const dbPath = (0, import_node_path5.resolve)(fileConfig.file ?? "db.yml");
1626
+ if (!(0, import_node_fs7.existsSync)(handlersPath)) {
1627
+ (0, import_node_fs7.writeFileSync)(
1571
1628
  handlersPath,
1572
1629
  HANDLERS_FILE_HEADER + buildStub(name, flags.method, flags.path),
1573
1630
  "utf8"
1574
1631
  );
1575
- console.log(` Created ${(0, import_node_path4.basename)(handlersPath)}`);
1632
+ console.log(` Created ${(0, import_node_path5.basename)(handlersPath)}`);
1576
1633
  } else {
1577
- const existing = (0, import_node_fs6.readFileSync)(handlersPath, "utf8");
1634
+ const existing = (0, import_node_fs7.readFileSync)(handlersPath, "utf8");
1578
1635
  if (existing.includes(`function ${name}(`)) {
1579
- console.error(` Error: handler "${name}" already exists in ${(0, import_node_path4.basename)(handlersPath)}`);
1636
+ console.error(` Error: handler "${name}" already exists in ${(0, import_node_path5.basename)(handlersPath)}`);
1580
1637
  process.exit(1);
1581
1638
  }
1582
- (0, import_node_fs6.appendFileSync)(handlersPath, buildStub(name, flags.method, flags.path), "utf8");
1583
- console.log(` Added handler "${name}" to ${(0, import_node_path4.basename)(handlersPath)}`);
1639
+ (0, import_node_fs7.appendFileSync)(handlersPath, buildStub(name, flags.method, flags.path), "utf8");
1640
+ console.log(` Added handler "${name}" to ${(0, import_node_path5.basename)(handlersPath)}`);
1584
1641
  }
1585
1642
  if (flags.register) {
1586
1643
  if (!flags.method || !flags.path) {
1587
1644
  console.error(" Error: --register requires --method and --path");
1588
1645
  process.exit(1);
1589
1646
  }
1590
- if (!(0, import_node_fs6.existsSync)(dbPath)) {
1647
+ if (!(0, import_node_fs7.existsSync)(dbPath)) {
1591
1648
  console.error(` Error: database file not found at ${dbPath}`);
1592
1649
  process.exit(1);
1593
1650
  }
1594
- const raw = (0, import_yaml3.parse)((0, import_node_fs6.readFileSync)(dbPath, "utf8")) ?? {};
1651
+ const raw = (0, import_yaml3.parse)((0, import_node_fs7.readFileSync)(dbPath, "utf8")) ?? {};
1595
1652
  if (!Array.isArray(raw["_routes"])) raw["_routes"] = [];
1596
1653
  const routes = raw["_routes"];
1597
1654
  const alreadyRegistered = routes.some((r) => r["handler"] === name);
1598
1655
  if (!alreadyRegistered) {
1599
1656
  routes.push({ method: flags.method.toUpperCase(), path: flags.path, handler: name });
1600
- (0, import_node_fs6.writeFileSync)(dbPath, (0, import_yaml3.stringify)(raw), "utf8");
1601
- console.log(` Added _routes entry to ${(0, import_node_path4.basename)(dbPath)}`);
1657
+ (0, import_node_fs7.writeFileSync)(dbPath, (0, import_yaml3.stringify)(raw), "utf8");
1658
+ console.log(` Added _routes entry to ${(0, import_node_path5.basename)(dbPath)}`);
1602
1659
  } else {
1603
1660
  console.log(` Handler "${name}" already in _routes \u2014 skipped`);
1604
1661
  }
@@ -1606,10 +1663,10 @@ function registerHandler(program2) {
1606
1663
  console.log(`
1607
1664
  Next steps:`);
1608
1665
  if (!fileConfig.handlers) {
1609
- console.log(` 1. Add handlers: ${(0, import_node_path4.basename)(handlersPath)} to yrest.config.yml`);
1610
- console.log(` 2. Implement the "${name}" function in ${(0, import_node_path4.basename)(handlersPath)}`);
1666
+ console.log(` 1. Add handlers: ${(0, import_node_path5.basename)(handlersPath)} to yrest.config.yml`);
1667
+ console.log(` 2. Implement the "${name}" function in ${(0, import_node_path5.basename)(handlersPath)}`);
1611
1668
  } else {
1612
- console.log(` 1. Implement the "${name}" function in ${(0, import_node_path4.basename)(handlersPath)}`);
1669
+ console.log(` 1. Implement the "${name}" function in ${(0, import_node_path5.basename)(handlersPath)}`);
1613
1670
  }
1614
1671
  if (!flags.register) {
1615
1672
  console.log(