@crvouga/mockingbird-service-otel 2.1.0 → 2.2.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/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Changelog — @crvouga/mockingbird-service-otel
2
2
 
3
+ ## 2.2.0 (2026-10-05)
4
+
5
+ ### Features
6
+
7
+ - add scripted local API mock ([4a76a11](https://github.com/crvouga/mockingbird/commit/4a76a114e2efad45934e0a93cf29576fd418e15c))
8
+
9
+ ### Fixes and improvements
10
+
11
+ - support embedded route parameters ([127cad9](https://github.com/crvouga/mockingbird/commit/127cad997ef106950c1b866070eea191ba54403f))
12
+
3
13
  ## 2.1.0 (2026-10-04)
4
14
 
5
15
  ### Features
@@ -12,10 +22,6 @@
12
22
  - fill the embedded viewport ([c1a35a4](https://github.com/crvouga/mockingbird/commit/c1a35a4789389ee9cd06c286d09bd47c4d06c71e))
13
23
  - make dialog cleanup immediate ([0c1a3c5](https://github.com/crvouga/mockingbird/commit/0c1a3c5b12584d50c19dcae595b951b8e5417b9c))
14
24
 
15
- ### Dependencies
16
-
17
- - `@crvouga/mockingbird-service-sqlite`
18
-
19
25
  ## 2.0.0 (2026-10-04)
20
26
 
21
27
  ### ⚠️ Breaking changes
@@ -845,7 +845,40 @@ var decodeBody = (contentType, bytes) => {
845
845
  return { kind: "bytes", value: bytes };
846
846
  };
847
847
  var readBody = async (message) => {
848
- const bytes = new Uint8Array(await message.arrayBuffer());
848
+ if (!(message instanceof Request) || !message.body) {
849
+ if (message instanceof Request)
850
+ message.signal.throwIfAborted();
851
+ return decodeBody(message.headers.get("content-type"), new Uint8Array(await message.arrayBuffer()));
852
+ }
853
+ message.signal.throwIfAborted();
854
+ const reader = message.body.getReader();
855
+ const cancel = () => {
856
+ void reader.cancel(message.signal.reason).catch(() => {
857
+ });
858
+ };
859
+ message.signal.addEventListener("abort", cancel, { once: true });
860
+ const chunks = [];
861
+ let size = 0;
862
+ try {
863
+ for (; ; ) {
864
+ message.signal.throwIfAborted();
865
+ const { done, value } = await reader.read();
866
+ message.signal.throwIfAborted();
867
+ if (done)
868
+ break;
869
+ chunks.push(value);
870
+ size += value.byteLength;
871
+ }
872
+ } finally {
873
+ message.signal.removeEventListener("abort", cancel);
874
+ reader.releaseLock();
875
+ }
876
+ const bytes = new Uint8Array(size);
877
+ let offset = 0;
878
+ for (const chunk of chunks) {
879
+ bytes.set(chunk, offset);
880
+ offset += chunk.byteLength;
881
+ }
849
882
  return decodeBody(message.headers.get("content-type"), bytes);
850
883
  };
851
884
 
@@ -1464,7 +1497,42 @@ var verifyOperations = (document2, handlers) => {
1464
1497
  }
1465
1498
  return problems;
1466
1499
  };
1467
- var honoPath = (template) => template.replace(/\{([^}]+)\}/g, ":$1");
1500
+ var escapePattern = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1501
+ var serviceRoute = (template) => {
1502
+ const names = [];
1503
+ let pattern = "", end = 0;
1504
+ for (const match of template.matchAll(/\{([^}]+)\}/g)) {
1505
+ pattern += `${escapePattern(template.slice(end, match.index))}([^/]+?)`;
1506
+ const name = match[1];
1507
+ if (!name)
1508
+ throw new Error(`Invalid OpenAPI route template: ${template}`);
1509
+ names.push(name);
1510
+ end = match.index + match[0].length;
1511
+ }
1512
+ pattern += escapePattern(template.slice(end));
1513
+ const matcher = new RegExp(`^${pattern}$`);
1514
+ const path = template.split("/").map((segment, index) => {
1515
+ if (!segment.includes("{"))
1516
+ return segment;
1517
+ const literal = /^\{([^}]+)\}$/.exec(segment);
1518
+ if (literal)
1519
+ return `:${literal[1]}`;
1520
+ let expression = "", offset = 0;
1521
+ for (const match of segment.matchAll(/\{[^}]+\}/g)) {
1522
+ expression += `${escapePattern(segment.slice(offset, match.index))}[^/]+?`;
1523
+ offset = match.index + match[0].length;
1524
+ }
1525
+ expression += escapePattern(segment.slice(offset));
1526
+ return `:mockingbirdSegment${index}{${expression}}`;
1527
+ }).join("/");
1528
+ return {
1529
+ path,
1530
+ params: (pathname) => {
1531
+ const values = matcher.exec(pathname);
1532
+ return Object.fromEntries(names.map((name, index) => [name, decodeURIComponent(values?.[index + 1] ?? "")]));
1533
+ }
1534
+ };
1535
+ };
1468
1536
  var routeOrder = (a, b) => {
1469
1537
  const sa = a.path.split("/");
1470
1538
  const sb = b.path.split("/");
@@ -1499,6 +1567,7 @@ var createService = (options) => {
1499
1567
  for (const operation of operations) {
1500
1568
  const metadata = operationMetadata(operation.operation);
1501
1569
  const handler = options.handlers[operation.operationId];
1570
+ const registeredRoute = serviceRoute(operation.path);
1502
1571
  const route = async (c) => {
1503
1572
  const request = c.req.raw;
1504
1573
  if (!metadata.supported || !handler) {
@@ -1508,7 +1577,7 @@ var createService = (options) => {
1508
1577
  const context = {
1509
1578
  request,
1510
1579
  url,
1511
- params: c.req.param(),
1580
+ params: registeredRoute.params(url.pathname),
1512
1581
  query: queryOf(url),
1513
1582
  body: await readBody(request),
1514
1583
  sqlite: options.sqlite,
@@ -1520,7 +1589,7 @@ var createService = (options) => {
1520
1589
  const short = await options.before?.(context);
1521
1590
  return withIssues(request, short ?? await handler(context));
1522
1591
  };
1523
- app.on(operation.method.toUpperCase(), honoPath(operation.path), route);
1592
+ app.on(operation.method.toUpperCase(), registeredRoute.path, route);
1524
1593
  }
1525
1594
  return {
1526
1595
  app,
@@ -1989,7 +2058,7 @@ var stateAdminRoutes = (routes) => {
1989
2058
  };
1990
2059
 
1991
2060
  // ../core/dist/version.js
1992
- var PACKAGE_VERSION = true ? "2.1.0" : UNRELEASED_VERSION;
2061
+ var PACKAGE_VERSION = true ? "2.2.0" : UNRELEASED_VERSION;
1993
2062
 
1994
2063
  // ../core/dist/webhooks.js
1995
2064
  var json4 = (status, body) => new Response(JSON.stringify(body), {
@@ -4455,4 +4524,4 @@ export {
4455
4524
  OtelAPI,
4456
4525
  adminRow
4457
4526
  };
4458
- //# sourceMappingURL=chunk-2VJBDTKS.js.map
4527
+ //# sourceMappingURL=chunk-25BPUIO3.js.map