@crvouga/mockingbird-service-fullscript 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 +10 -4
- package/dist/{chunk-UJ4A5HDU.js → chunk-K7FEFOOY.js} +75 -6
- package/dist/chunk-K7FEFOOY.js.map +7 -0
- package/dist/{chunk-2EVWG4QR.js → chunk-PJKILYOQ.js} +2 -2
- package/dist/cli.js +2 -2
- package/dist/index.js +1 -1
- package/dist/server.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-UJ4A5HDU.js.map +0 -7
- /package/dist/{chunk-2EVWG4QR.js.map → chunk-PJKILYOQ.js.map} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog — @crvouga/mockingbird-service-fullscript
|
|
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
|
|
@@ -1018,7 +1018,40 @@ var decodeBody = (contentType, bytes) => {
|
|
|
1018
1018
|
return { kind: "bytes", value: bytes };
|
|
1019
1019
|
};
|
|
1020
1020
|
var readBody = async (message) => {
|
|
1021
|
-
|
|
1021
|
+
if (!(message instanceof Request) || !message.body) {
|
|
1022
|
+
if (message instanceof Request)
|
|
1023
|
+
message.signal.throwIfAborted();
|
|
1024
|
+
return decodeBody(message.headers.get("content-type"), new Uint8Array(await message.arrayBuffer()));
|
|
1025
|
+
}
|
|
1026
|
+
message.signal.throwIfAborted();
|
|
1027
|
+
const reader = message.body.getReader();
|
|
1028
|
+
const cancel = () => {
|
|
1029
|
+
void reader.cancel(message.signal.reason).catch(() => {
|
|
1030
|
+
});
|
|
1031
|
+
};
|
|
1032
|
+
message.signal.addEventListener("abort", cancel, { once: true });
|
|
1033
|
+
const chunks = [];
|
|
1034
|
+
let size = 0;
|
|
1035
|
+
try {
|
|
1036
|
+
for (; ; ) {
|
|
1037
|
+
message.signal.throwIfAborted();
|
|
1038
|
+
const { done, value } = await reader.read();
|
|
1039
|
+
message.signal.throwIfAborted();
|
|
1040
|
+
if (done)
|
|
1041
|
+
break;
|
|
1042
|
+
chunks.push(value);
|
|
1043
|
+
size += value.byteLength;
|
|
1044
|
+
}
|
|
1045
|
+
} finally {
|
|
1046
|
+
message.signal.removeEventListener("abort", cancel);
|
|
1047
|
+
reader.releaseLock();
|
|
1048
|
+
}
|
|
1049
|
+
const bytes = new Uint8Array(size);
|
|
1050
|
+
let offset = 0;
|
|
1051
|
+
for (const chunk of chunks) {
|
|
1052
|
+
bytes.set(chunk, offset);
|
|
1053
|
+
offset += chunk.byteLength;
|
|
1054
|
+
}
|
|
1022
1055
|
return decodeBody(message.headers.get("content-type"), bytes);
|
|
1023
1056
|
};
|
|
1024
1057
|
|
|
@@ -1778,7 +1811,42 @@ var verifyOperations = (document2, handlers) => {
|
|
|
1778
1811
|
}
|
|
1779
1812
|
return problems;
|
|
1780
1813
|
};
|
|
1781
|
-
var
|
|
1814
|
+
var escapePattern = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1815
|
+
var serviceRoute = (template) => {
|
|
1816
|
+
const names = [];
|
|
1817
|
+
let pattern = "", end = 0;
|
|
1818
|
+
for (const match of template.matchAll(/\{([^}]+)\}/g)) {
|
|
1819
|
+
pattern += `${escapePattern(template.slice(end, match.index))}([^/]+?)`;
|
|
1820
|
+
const name = match[1];
|
|
1821
|
+
if (!name)
|
|
1822
|
+
throw new Error(`Invalid OpenAPI route template: ${template}`);
|
|
1823
|
+
names.push(name);
|
|
1824
|
+
end = match.index + match[0].length;
|
|
1825
|
+
}
|
|
1826
|
+
pattern += escapePattern(template.slice(end));
|
|
1827
|
+
const matcher = new RegExp(`^${pattern}$`);
|
|
1828
|
+
const path = template.split("/").map((segment, index) => {
|
|
1829
|
+
if (!segment.includes("{"))
|
|
1830
|
+
return segment;
|
|
1831
|
+
const literal = /^\{([^}]+)\}$/.exec(segment);
|
|
1832
|
+
if (literal)
|
|
1833
|
+
return `:${literal[1]}`;
|
|
1834
|
+
let expression = "", offset = 0;
|
|
1835
|
+
for (const match of segment.matchAll(/\{[^}]+\}/g)) {
|
|
1836
|
+
expression += `${escapePattern(segment.slice(offset, match.index))}[^/]+?`;
|
|
1837
|
+
offset = match.index + match[0].length;
|
|
1838
|
+
}
|
|
1839
|
+
expression += escapePattern(segment.slice(offset));
|
|
1840
|
+
return `:mockingbirdSegment${index}{${expression}}`;
|
|
1841
|
+
}).join("/");
|
|
1842
|
+
return {
|
|
1843
|
+
path,
|
|
1844
|
+
params: (pathname) => {
|
|
1845
|
+
const values = matcher.exec(pathname);
|
|
1846
|
+
return Object.fromEntries(names.map((name, index) => [name, decodeURIComponent(values?.[index + 1] ?? "")]));
|
|
1847
|
+
}
|
|
1848
|
+
};
|
|
1849
|
+
};
|
|
1782
1850
|
var routeOrder = (a, b) => {
|
|
1783
1851
|
const sa = a.path.split("/");
|
|
1784
1852
|
const sb = b.path.split("/");
|
|
@@ -1813,6 +1881,7 @@ var createService = (options) => {
|
|
|
1813
1881
|
for (const operation of operations) {
|
|
1814
1882
|
const metadata = operationMetadata(operation.operation);
|
|
1815
1883
|
const handler = options.handlers[operation.operationId];
|
|
1884
|
+
const registeredRoute = serviceRoute(operation.path);
|
|
1816
1885
|
const route = async (c) => {
|
|
1817
1886
|
const request = c.req.raw;
|
|
1818
1887
|
if (!metadata.supported || !handler) {
|
|
@@ -1822,7 +1891,7 @@ var createService = (options) => {
|
|
|
1822
1891
|
const context = {
|
|
1823
1892
|
request,
|
|
1824
1893
|
url,
|
|
1825
|
-
params:
|
|
1894
|
+
params: registeredRoute.params(url.pathname),
|
|
1826
1895
|
query: queryOf(url),
|
|
1827
1896
|
body: await readBody(request),
|
|
1828
1897
|
sqlite: options.sqlite,
|
|
@@ -1834,7 +1903,7 @@ var createService = (options) => {
|
|
|
1834
1903
|
const short = await options.before?.(context);
|
|
1835
1904
|
return withIssues(request, short ?? await handler(context));
|
|
1836
1905
|
};
|
|
1837
|
-
app.on(operation.method.toUpperCase(),
|
|
1906
|
+
app.on(operation.method.toUpperCase(), registeredRoute.path, route);
|
|
1838
1907
|
}
|
|
1839
1908
|
return {
|
|
1840
1909
|
app,
|
|
@@ -2303,7 +2372,7 @@ var stateAdminRoutes = (routes) => {
|
|
|
2303
2372
|
};
|
|
2304
2373
|
|
|
2305
2374
|
// ../core/dist/version.js
|
|
2306
|
-
var PACKAGE_VERSION = true ? "2.
|
|
2375
|
+
var PACKAGE_VERSION = true ? "2.2.0" : UNRELEASED_VERSION;
|
|
2307
2376
|
|
|
2308
2377
|
// ../core/dist/signing.js
|
|
2309
2378
|
var encoder = new TextEncoder();
|
|
@@ -4391,4 +4460,4 @@ export {
|
|
|
4391
4460
|
envelope,
|
|
4392
4461
|
FullscriptAPI
|
|
4393
4462
|
};
|
|
4394
|
-
//# sourceMappingURL=chunk-
|
|
4463
|
+
//# sourceMappingURL=chunk-K7FEFOOY.js.map
|