@crvouga/mockingbird-service-bedrock 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-bedrock
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
@@ -1019,7 +1019,40 @@ var decodeBody = (contentType, bytes) => {
1019
1019
  return { kind: "bytes", value: bytes };
1020
1020
  };
1021
1021
  var readBody = async (message) => {
1022
- const bytes = new Uint8Array(await message.arrayBuffer());
1022
+ if (!(message instanceof Request) || !message.body) {
1023
+ if (message instanceof Request)
1024
+ message.signal.throwIfAborted();
1025
+ return decodeBody(message.headers.get("content-type"), new Uint8Array(await message.arrayBuffer()));
1026
+ }
1027
+ message.signal.throwIfAborted();
1028
+ const reader = message.body.getReader();
1029
+ const cancel = () => {
1030
+ void reader.cancel(message.signal.reason).catch(() => {
1031
+ });
1032
+ };
1033
+ message.signal.addEventListener("abort", cancel, { once: true });
1034
+ const chunks = [];
1035
+ let size = 0;
1036
+ try {
1037
+ for (; ; ) {
1038
+ message.signal.throwIfAborted();
1039
+ const { done, value } = await reader.read();
1040
+ message.signal.throwIfAborted();
1041
+ if (done)
1042
+ break;
1043
+ chunks.push(value);
1044
+ size += value.byteLength;
1045
+ }
1046
+ } finally {
1047
+ message.signal.removeEventListener("abort", cancel);
1048
+ reader.releaseLock();
1049
+ }
1050
+ const bytes = new Uint8Array(size);
1051
+ let offset = 0;
1052
+ for (const chunk2 of chunks) {
1053
+ bytes.set(chunk2, offset);
1054
+ offset += chunk2.byteLength;
1055
+ }
1023
1056
  return decodeBody(message.headers.get("content-type"), bytes);
1024
1057
  };
1025
1058
 
@@ -1757,7 +1790,42 @@ var verifyOperations = (document2, handlers) => {
1757
1790
  }
1758
1791
  return problems;
1759
1792
  };
1760
- var honoPath = (template) => template.replace(/\{([^}]+)\}/g, ":$1");
1793
+ var escapePattern = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1794
+ var serviceRoute = (template) => {
1795
+ const names = [];
1796
+ let pattern = "", end = 0;
1797
+ for (const match of template.matchAll(/\{([^}]+)\}/g)) {
1798
+ pattern += `${escapePattern(template.slice(end, match.index))}([^/]+?)`;
1799
+ const name = match[1];
1800
+ if (!name)
1801
+ throw new Error(`Invalid OpenAPI route template: ${template}`);
1802
+ names.push(name);
1803
+ end = match.index + match[0].length;
1804
+ }
1805
+ pattern += escapePattern(template.slice(end));
1806
+ const matcher = new RegExp(`^${pattern}$`);
1807
+ const path = template.split("/").map((segment, index) => {
1808
+ if (!segment.includes("{"))
1809
+ return segment;
1810
+ const literal = /^\{([^}]+)\}$/.exec(segment);
1811
+ if (literal)
1812
+ return `:${literal[1]}`;
1813
+ let expression = "", offset = 0;
1814
+ for (const match of segment.matchAll(/\{[^}]+\}/g)) {
1815
+ expression += `${escapePattern(segment.slice(offset, match.index))}[^/]+?`;
1816
+ offset = match.index + match[0].length;
1817
+ }
1818
+ expression += escapePattern(segment.slice(offset));
1819
+ return `:mockingbirdSegment${index}{${expression}}`;
1820
+ }).join("/");
1821
+ return {
1822
+ path,
1823
+ params: (pathname) => {
1824
+ const values = matcher.exec(pathname);
1825
+ return Object.fromEntries(names.map((name, index) => [name, decodeURIComponent(values?.[index + 1] ?? "")]));
1826
+ }
1827
+ };
1828
+ };
1761
1829
  var routeOrder = (a, b) => {
1762
1830
  const sa = a.path.split("/");
1763
1831
  const sb = b.path.split("/");
@@ -1792,6 +1860,7 @@ var createService = (options) => {
1792
1860
  for (const operation of operations) {
1793
1861
  const metadata = operationMetadata(operation.operation);
1794
1862
  const handler = options.handlers[operation.operationId];
1863
+ const registeredRoute = serviceRoute(operation.path);
1795
1864
  const route = async (c) => {
1796
1865
  const request = c.req.raw;
1797
1866
  if (!metadata.supported || !handler) {
@@ -1801,7 +1870,7 @@ var createService = (options) => {
1801
1870
  const context = {
1802
1871
  request,
1803
1872
  url,
1804
- params: c.req.param(),
1873
+ params: registeredRoute.params(url.pathname),
1805
1874
  query: queryOf(url),
1806
1875
  body: await readBody(request),
1807
1876
  sqlite: options.sqlite,
@@ -1813,7 +1882,7 @@ var createService = (options) => {
1813
1882
  const short = await options.before?.(context);
1814
1883
  return withIssues(request, short ?? await handler(context));
1815
1884
  };
1816
- app.on(operation.method.toUpperCase(), honoPath(operation.path), route);
1885
+ app.on(operation.method.toUpperCase(), registeredRoute.path, route);
1817
1886
  }
1818
1887
  return {
1819
1888
  app,
@@ -2282,7 +2351,7 @@ var stateAdminRoutes = (routes) => {
2282
2351
  };
2283
2352
 
2284
2353
  // ../core/dist/version.js
2285
- var PACKAGE_VERSION = true ? "2.1.0" : UNRELEASED_VERSION;
2354
+ var PACKAGE_VERSION = true ? "2.2.0" : UNRELEASED_VERSION;
2286
2355
 
2287
2356
  // ../core/dist/signing.js
2288
2357
  var encoder = new TextEncoder();
@@ -5569,4 +5638,4 @@ export {
5569
5638
  titanEmbedding,
5570
5639
  BedrockAPI
5571
5640
  };
5572
- //# sourceMappingURL=chunk-WBDRLPM7.js.map
5641
+ //# sourceMappingURL=chunk-45N5S3V3.js.map