stitchkit 0.80.1 → 0.82.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 +6552 -0
- package/README.md +4 -0
- package/dist/agent-runtime/provider-failure.d.ts.map +1 -1
- package/dist/agent-runtime-coding-tools.js +1 -1
- package/dist/agent-runtime-harness.js +7 -5
- package/dist/agent-runtime.js +15 -19
- package/dist/application/notification-outbox.d.ts +80 -0
- package/dist/application/notification-outbox.d.ts.map +1 -0
- package/dist/application/process-lifecycle.d.ts +166 -0
- package/dist/application/process-lifecycle.d.ts.map +1 -0
- package/dist/application/state-store.d.ts +18 -0
- package/dist/application/state-store.d.ts.map +1 -0
- package/dist/application.d.ts +3 -0
- package/dist/application.d.ts.map +1 -1
- package/dist/application.js +568 -11
- package/dist/browser/http.d.ts +14 -0
- package/dist/browser/http.d.ts.map +1 -1
- package/dist/browser/resumable.d.ts +6 -0
- package/dist/browser/resumable.d.ts.map +1 -1
- package/dist/cli.js +9 -7
- package/dist/contract/define.d.ts +27 -4
- package/dist/contract/define.d.ts.map +1 -1
- package/dist/contract/errors-factory.d.ts +22 -3
- package/dist/contract/errors-factory.d.ts.map +1 -1
- package/dist/contract/index.d.ts +2 -2
- package/dist/contract/index.d.ts.map +1 -1
- package/dist/contract/index.js +1 -1
- package/dist/geo/index.d.ts +4 -0
- package/dist/geo/index.d.ts.map +1 -0
- package/dist/geo/maxmind.d.ts +4 -0
- package/dist/geo/maxmind.d.ts.map +1 -0
- package/dist/geo/resolver.d.ts +9 -0
- package/dist/geo/resolver.d.ts.map +1 -0
- package/dist/geo/types.d.ts +59 -0
- package/dist/geo/types.d.ts.map +1 -0
- package/dist/geo.d.ts +3 -0
- package/dist/geo.d.ts.map +1 -0
- package/dist/geo.js +245 -0
- package/dist/{index-9s6z8vgf.js → index-1dd82z59.js} +1 -1
- package/dist/{index-vwp69871.js → index-27487ay5.js} +4 -4
- package/dist/{index-7ag81v2f.js → index-27gm3d6g.js} +10 -321
- package/dist/{index-y01f4223.js → index-2bxcmqkb.js} +127 -43
- package/dist/{index-dxesg10d.js → index-3ds42w1w.js} +3 -3
- package/dist/index-3xwxfj4z.js +334 -0
- package/dist/{index-egaabxkz.js → index-5z8tezpx.js} +2 -2
- package/dist/{index-fxz0v7vg.js → index-7evdsyez.js} +1 -83
- package/dist/{index-xcetq6j3.js → index-90d7h2cr.js} +32 -13
- package/dist/{index-t0z5p5w6.js → index-apn8repm.js} +1 -1
- package/dist/{index-758zx2ha.js → index-dggwnnjv.js} +2 -2
- package/dist/{index-dwf1f2ap.js → index-f9mb610r.js} +1 -62
- package/dist/{index-5mtc969c.js → index-fwbkp2jn.js} +1 -1
- package/dist/index-p13mwz16.js +16 -0
- package/dist/{index-m9kzax52.js → index-p18f59zy.js} +21 -5
- package/dist/{index-hb5pf3s4.js → index-qmgs7y68.js} +1 -1
- package/dist/{index-2rwwmr7v.js → index-s4ckmrac.js} +1 -1
- package/dist/{index-h4pj6fta.js → index-s8cnx02s.js} +8 -5
- package/dist/{index-k9ay6v6d.js → index-vchzar7e.js} +74 -23
- package/dist/index-vsbzgd7b.js +84 -0
- package/dist/{index-dxjjv399.js → index-xbppf54a.js} +95 -15
- package/dist/index-y91ry9h2.js +4 -0
- package/dist/index-zcgf3gqf.js +83 -0
- package/dist/index.js +17 -13
- package/dist/internal/error-message.d.ts +3 -0
- package/dist/internal/error-message.d.ts.map +1 -0
- package/dist/internal/media-type.d.ts +8 -0
- package/dist/internal/media-type.d.ts.map +1 -0
- package/dist/internal/route-pattern.d.ts +21 -0
- package/dist/internal/route-pattern.d.ts.map +1 -1
- package/dist/internal/upgrade-plan.d.ts +18 -0
- package/dist/internal/upgrade-plan.d.ts.map +1 -0
- package/dist/node.js +9 -6
- package/dist/observability/audit.d.ts +28 -1
- package/dist/observability/audit.d.ts.map +1 -1
- package/dist/observability/bounded-logger.d.ts +20 -0
- package/dist/observability/bounded-logger.d.ts.map +1 -0
- package/dist/observability/context.d.ts +12 -3
- package/dist/observability/context.d.ts.map +1 -1
- package/dist/observability/index.d.ts +3 -2
- package/dist/observability/index.d.ts.map +1 -1
- package/dist/observability/index.js +138 -8
- package/dist/observability/sanitize.d.ts +17 -0
- package/dist/observability/sanitize.d.ts.map +1 -1
- package/dist/primitives.js +1 -1
- package/dist/react/query-client.d.ts +33 -0
- package/dist/react/query-client.d.ts.map +1 -0
- package/dist/react.d.ts +1 -0
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +83 -1
- package/dist/realtime/registry.d.ts +93 -0
- package/dist/realtime/registry.d.ts.map +1 -0
- package/dist/release/header.d.ts +9 -0
- package/dist/release/header.d.ts.map +1 -0
- package/dist/release/marker.d.ts +39 -0
- package/dist/release/marker.d.ts.map +1 -0
- package/dist/release/socket.d.ts +57 -0
- package/dist/release/socket.d.ts.map +1 -0
- package/dist/release/watcher.d.ts +66 -0
- package/dist/release/watcher.d.ts.map +1 -0
- package/dist/release.d.ts +15 -0
- package/dist/release.d.ts.map +1 -0
- package/dist/release.js +196 -0
- package/dist/remote.js +12 -7
- package/dist/server/context.d.ts +2 -1
- package/dist/server/context.d.ts.map +1 -1
- package/dist/server/create.d.ts.map +1 -1
- package/dist/server/error-hook.d.ts +17 -16
- package/dist/server/error-hook.d.ts.map +1 -1
- package/dist/server/file-state-store.d.ts +23 -0
- package/dist/server/file-state-store.d.ts.map +1 -0
- package/dist/server/implement.d.ts.map +1 -1
- package/dist/server/index.d.ts +5 -2
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +469 -11
- package/dist/server/middleware/cookies.d.ts +33 -1
- package/dist/server/middleware/cookies.d.ts.map +1 -1
- package/dist/server/middleware/cors.d.ts +16 -1
- package/dist/server/middleware/cors.d.ts.map +1 -1
- package/dist/server/openapi.d.ts.map +1 -1
- package/dist/server/release-signal.d.ts +35 -0
- package/dist/server/release-signal.d.ts.map +1 -0
- package/dist/server/router.d.ts.map +1 -1
- package/dist/server/types.d.ts +26 -2
- package/dist/server/types.d.ts.map +1 -1
- package/dist/testing/surface-manifest.d.ts.map +1 -1
- package/dist/testing.js +7 -4
- package/dist/tool-invoker.js +8 -6
- package/dist/tools/download-core.d.ts.map +1 -1
- package/dist/tools/remote.d.ts.map +1 -1
- package/dist/tools/view-file.d.ts.map +1 -1
- package/dist/tools.js +20 -16
- package/dist/tracking/attribution.d.ts +51 -0
- package/dist/tracking/attribution.d.ts.map +1 -0
- package/dist/tracking/beacon.d.ts +14 -0
- package/dist/tracking/beacon.d.ts.map +1 -0
- package/dist/tracking/clicks.d.ts +46 -0
- package/dist/tracking/clicks.d.ts.map +1 -0
- package/dist/tracking/client.d.ts +121 -0
- package/dist/tracking/client.d.ts.map +1 -0
- package/dist/tracking/contract.d.ts +57 -0
- package/dist/tracking/contract.d.ts.map +1 -0
- package/dist/tracking/delivery.d.ts +24 -0
- package/dist/tracking/delivery.d.ts.map +1 -0
- package/dist/tracking/host.d.ts +43 -0
- package/dist/tracking/host.d.ts.map +1 -0
- package/dist/tracking/once-per-page.d.ts +17 -0
- package/dist/tracking/once-per-page.d.ts.map +1 -0
- package/dist/tracking/outbox-storage-indexeddb.d.ts +12 -0
- package/dist/tracking/outbox-storage-indexeddb.d.ts.map +1 -0
- package/dist/tracking/outbox-storage-memory.d.ts +12 -0
- package/dist/tracking/outbox-storage-memory.d.ts.map +1 -0
- package/dist/tracking/outbox.d.ts +98 -0
- package/dist/tracking/outbox.d.ts.map +1 -0
- package/dist/tracking/schemas.d.ts +183 -0
- package/dist/tracking/schemas.d.ts.map +1 -0
- package/dist/tracking/scroll.d.ts +22 -0
- package/dist/tracking/scroll.d.ts.map +1 -0
- package/dist/tracking/sequence-reserve.d.ts +34 -0
- package/dist/tracking/sequence-reserve.d.ts.map +1 -0
- package/dist/tracking/server/active-interval.d.ts +26 -0
- package/dist/tracking/server/active-interval.d.ts.map +1 -0
- package/dist/tracking/server/bot.d.ts +9 -0
- package/dist/tracking/server/bot.d.ts.map +1 -0
- package/dist/tracking/server/disposition.d.ts +55 -0
- package/dist/tracking/server/disposition.d.ts.map +1 -0
- package/dist/tracking/server/hash.d.ts +13 -0
- package/dist/tracking/server/hash.d.ts.map +1 -0
- package/dist/tracking/server/presence.d.ts +27 -0
- package/dist/tracking/server/presence.d.ts.map +1 -0
- package/dist/tracking/server/visit-lease.d.ts +92 -0
- package/dist/tracking/server/visit-lease.d.ts.map +1 -0
- package/dist/tracking/visible-time.d.ts +38 -0
- package/dist/tracking/visible-time.d.ts.map +1 -0
- package/dist/tracking-server.d.ts +15 -0
- package/dist/tracking-server.d.ts.map +1 -0
- package/dist/tracking-server.js +173 -0
- package/dist/tracking.d.ts +24 -0
- package/dist/tracking.d.ts.map +1 -0
- package/dist/tracking.js +1091 -0
- package/dist/upgrade-cli.d.ts +27 -0
- package/dist/upgrade-cli.d.ts.map +1 -0
- package/dist/upgrade-cli.js +177 -0
- package/llms-full.txt +1001 -29
- package/llms.txt +4 -0
- package/package.json +30 -5
package/dist/geo.js
ADDED
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import {
|
|
2
|
+
messageOf
|
|
3
|
+
} from "./index-p13mwz16.js";
|
|
4
|
+
import {
|
|
5
|
+
isPublicIp
|
|
6
|
+
} from "./index-f9mb610r.js";
|
|
7
|
+
import"./index-kzfs85xp.js";
|
|
8
|
+
import {
|
|
9
|
+
isRecord
|
|
10
|
+
} from "./index-77fekveh.js";
|
|
11
|
+
|
|
12
|
+
// src/geo/maxmind.ts
|
|
13
|
+
import { realpath, stat } from "node:fs/promises";
|
|
14
|
+
var MAXMIND_PEER = "maxmind";
|
|
15
|
+
async function revisionOf(paths) {
|
|
16
|
+
try {
|
|
17
|
+
const entries = await Promise.all([paths.city, paths.asn].filter((path) => path !== undefined).map(async (path) => {
|
|
18
|
+
const [resolved, metadata] = await Promise.all([realpath(path), stat(path)]);
|
|
19
|
+
return [
|
|
20
|
+
resolved,
|
|
21
|
+
metadata.dev,
|
|
22
|
+
metadata.ino,
|
|
23
|
+
metadata.size,
|
|
24
|
+
Math.trunc(metadata.mtimeMs)
|
|
25
|
+
].join(":");
|
|
26
|
+
}));
|
|
27
|
+
return entries.join("|");
|
|
28
|
+
} catch {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function createMaxMindGeoIpLoader(options = {}) {
|
|
33
|
+
const loadPeer = options.loadPeer ?? (() => import(MAXMIND_PEER));
|
|
34
|
+
return {
|
|
35
|
+
revision: revisionOf,
|
|
36
|
+
async open(paths, expectedRevision) {
|
|
37
|
+
const before = await revisionOf(paths);
|
|
38
|
+
if (before === null)
|
|
39
|
+
throw new Error("GeoIP database is unavailable");
|
|
40
|
+
if (before !== expectedRevision) {
|
|
41
|
+
throw new Error("GeoIP database changed before opening a generation");
|
|
42
|
+
}
|
|
43
|
+
const peer = await loadPeer();
|
|
44
|
+
if (!peer || typeof peer.open !== "function") {
|
|
45
|
+
throw new Error("The optional maxmind peer does not expose open()");
|
|
46
|
+
}
|
|
47
|
+
const city = await peer.open(paths.city, { watchForUpdates: false });
|
|
48
|
+
let asn;
|
|
49
|
+
try {
|
|
50
|
+
if (paths.asn)
|
|
51
|
+
asn = await peer.open(paths.asn, { watchForUpdates: false });
|
|
52
|
+
const after = await revisionOf(paths);
|
|
53
|
+
if (after !== before)
|
|
54
|
+
throw new Error("GeoIP database changed while opening a generation");
|
|
55
|
+
return {
|
|
56
|
+
lookup(ip) {
|
|
57
|
+
const cityRecord = city.get(ip);
|
|
58
|
+
const asnRecord = asn?.get(ip);
|
|
59
|
+
if (!asnRecord || typeof asnRecord !== "object")
|
|
60
|
+
return cityRecord;
|
|
61
|
+
if (!cityRecord || typeof cityRecord !== "object")
|
|
62
|
+
return asnRecord;
|
|
63
|
+
return { ...cityRecord, ...asnRecord };
|
|
64
|
+
},
|
|
65
|
+
async close() {
|
|
66
|
+
await Promise.all([city.close?.(), asn?.close?.()]);
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
} catch (error) {
|
|
70
|
+
await Promise.allSettled([city.close?.(), asn?.close?.()]);
|
|
71
|
+
throw error;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
// src/geo/resolver.ts
|
|
77
|
+
function text(value) {
|
|
78
|
+
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
79
|
+
}
|
|
80
|
+
function finite(value) {
|
|
81
|
+
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
82
|
+
}
|
|
83
|
+
function record(value) {
|
|
84
|
+
return isRecord(value) ? value : undefined;
|
|
85
|
+
}
|
|
86
|
+
function mapGeoIpRecord(value) {
|
|
87
|
+
const root = record(value);
|
|
88
|
+
if (!root)
|
|
89
|
+
return null;
|
|
90
|
+
const country = record(root.country);
|
|
91
|
+
const subdivisions = Array.isArray(root.subdivisions) ? record(root.subdivisions[0]) : undefined;
|
|
92
|
+
const city = record(root.city);
|
|
93
|
+
const postal = record(root.postal);
|
|
94
|
+
const location = record(root.location);
|
|
95
|
+
const names = (entry) => record(entry?.names);
|
|
96
|
+
const result = {
|
|
97
|
+
countryCode: text(country?.iso_code),
|
|
98
|
+
countryName: text(names(country)?.en),
|
|
99
|
+
regionCode: text(subdivisions?.iso_code),
|
|
100
|
+
regionName: text(names(subdivisions)?.en),
|
|
101
|
+
city: text(names(city)?.en),
|
|
102
|
+
postalCode: text(postal?.code),
|
|
103
|
+
latitude: finite(location?.latitude),
|
|
104
|
+
longitude: finite(location?.longitude),
|
|
105
|
+
timezone: text(location?.time_zone),
|
|
106
|
+
autonomousSystemNumber: finite(root.autonomous_system_number),
|
|
107
|
+
autonomousSystemOrganization: text(root.autonomous_system_organization)
|
|
108
|
+
};
|
|
109
|
+
return Object.values(result).some((entry) => entry !== undefined) ? result : null;
|
|
110
|
+
}
|
|
111
|
+
var errorMessage = (error) => messageOf(error) || "unknown reload error";
|
|
112
|
+
function createGeoIpResolver(options) {
|
|
113
|
+
const clock = options.clock ?? Date.now;
|
|
114
|
+
const map = options.map ?? mapGeoIpRecord;
|
|
115
|
+
let generation = null;
|
|
116
|
+
let snapshot = Object.freeze({ state: "uninitialized" });
|
|
117
|
+
let reloadChain = Promise.resolve(false);
|
|
118
|
+
let timer;
|
|
119
|
+
let closed = false;
|
|
120
|
+
const finishRetire = async (current) => {
|
|
121
|
+
if (current.closing)
|
|
122
|
+
return current.closePromise ?? Promise.resolve();
|
|
123
|
+
current.closing = true;
|
|
124
|
+
try {
|
|
125
|
+
await current.reader.close?.();
|
|
126
|
+
} catch (error) {
|
|
127
|
+
options.onError?.(error);
|
|
128
|
+
} finally {
|
|
129
|
+
current.closeResolve?.();
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
const retire = (current) => {
|
|
133
|
+
current.retired = true;
|
|
134
|
+
if (current.closePromise)
|
|
135
|
+
return current.closePromise;
|
|
136
|
+
if (current.lookups > 0) {
|
|
137
|
+
current.closePromise = new Promise((resolve) => {
|
|
138
|
+
current.closeResolve = resolve;
|
|
139
|
+
});
|
|
140
|
+
return current.closePromise;
|
|
141
|
+
}
|
|
142
|
+
current.closePromise = finishRetire(current);
|
|
143
|
+
return current.closePromise;
|
|
144
|
+
};
|
|
145
|
+
const swap = async () => {
|
|
146
|
+
if (closed)
|
|
147
|
+
return false;
|
|
148
|
+
let revision;
|
|
149
|
+
try {
|
|
150
|
+
revision = await options.loader.revision(options.paths);
|
|
151
|
+
if (revision === null)
|
|
152
|
+
throw new Error("GeoIP database is unavailable");
|
|
153
|
+
if (generation && revision === generation.revision) {
|
|
154
|
+
if (snapshot.reloadError) {
|
|
155
|
+
snapshot = Object.freeze({
|
|
156
|
+
state: "ready",
|
|
157
|
+
revision,
|
|
158
|
+
loadedAt: snapshot.loadedAt
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
const next = await options.loader.open(options.paths, revision);
|
|
164
|
+
if (closed) {
|
|
165
|
+
await next.close?.();
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
const previous = generation;
|
|
169
|
+
generation = { reader: next, revision, lookups: 0, retired: false };
|
|
170
|
+
snapshot = Object.freeze({ state: "ready", revision, loadedAt: clock() });
|
|
171
|
+
if (previous)
|
|
172
|
+
await retire(previous);
|
|
173
|
+
return true;
|
|
174
|
+
} catch (error) {
|
|
175
|
+
options.onError?.(error);
|
|
176
|
+
snapshot = generation ? Object.freeze({
|
|
177
|
+
state: "ready",
|
|
178
|
+
revision: generation.revision,
|
|
179
|
+
loadedAt: snapshot.loadedAt,
|
|
180
|
+
reloadError: errorMessage(error)
|
|
181
|
+
}) : Object.freeze({ state: "unavailable", reloadError: errorMessage(error) });
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
const reload = () => {
|
|
186
|
+
reloadChain = reloadChain.then(swap, swap);
|
|
187
|
+
return reloadChain;
|
|
188
|
+
};
|
|
189
|
+
const close = async () => {
|
|
190
|
+
closed = true;
|
|
191
|
+
if (timer)
|
|
192
|
+
clearInterval(timer);
|
|
193
|
+
timer = undefined;
|
|
194
|
+
await reloadChain.catch(() => {
|
|
195
|
+
return;
|
|
196
|
+
});
|
|
197
|
+
const current = generation;
|
|
198
|
+
generation = null;
|
|
199
|
+
if (current)
|
|
200
|
+
await retire(current);
|
|
201
|
+
snapshot = Object.freeze({ state: "uninitialized" });
|
|
202
|
+
};
|
|
203
|
+
return {
|
|
204
|
+
id: options.id ?? "geoip",
|
|
205
|
+
async start() {
|
|
206
|
+
closed = false;
|
|
207
|
+
await reload();
|
|
208
|
+
return { value: this };
|
|
209
|
+
},
|
|
210
|
+
activate() {
|
|
211
|
+
const intervalMs = options.reload === false ? undefined : options.reload?.intervalMs;
|
|
212
|
+
if (intervalMs !== undefined && intervalMs > 0 && !timer) {
|
|
213
|
+
timer = setInterval(() => void reload(), intervalMs);
|
|
214
|
+
timer.unref?.();
|
|
215
|
+
}
|
|
216
|
+
},
|
|
217
|
+
close,
|
|
218
|
+
force: close,
|
|
219
|
+
async resolve(ip) {
|
|
220
|
+
if (!isPublicIp(ip))
|
|
221
|
+
return null;
|
|
222
|
+
const current = generation;
|
|
223
|
+
if (!current)
|
|
224
|
+
return null;
|
|
225
|
+
current.lookups += 1;
|
|
226
|
+
try {
|
|
227
|
+
return map(await current.reader.lookup(ip));
|
|
228
|
+
} catch (error) {
|
|
229
|
+
options.onError?.(error);
|
|
230
|
+
return null;
|
|
231
|
+
} finally {
|
|
232
|
+
current.lookups -= 1;
|
|
233
|
+
if (current.retired && current.lookups === 0)
|
|
234
|
+
await finishRetire(current);
|
|
235
|
+
}
|
|
236
|
+
},
|
|
237
|
+
reload,
|
|
238
|
+
snapshot: () => snapshot
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
export {
|
|
242
|
+
mapGeoIpRecord,
|
|
243
|
+
createMaxMindGeoIpLoader,
|
|
244
|
+
createGeoIpResolver
|
|
245
|
+
};
|
|
@@ -3,14 +3,14 @@ import {
|
|
|
3
3
|
} from "./index-sbdmyz75.js";
|
|
4
4
|
import {
|
|
5
5
|
collectToolSurface
|
|
6
|
-
} from "./index-
|
|
6
|
+
} from "./index-s4ckmrac.js";
|
|
7
7
|
import {
|
|
8
8
|
createToolRunner,
|
|
9
9
|
formatToolError
|
|
10
|
-
} from "./index-
|
|
10
|
+
} from "./index-fwbkp2jn.js";
|
|
11
11
|
import {
|
|
12
12
|
toolResultFromError
|
|
13
|
-
} from "./index-
|
|
13
|
+
} from "./index-dggwnnjv.js";
|
|
14
14
|
import {
|
|
15
15
|
assertUniqueToolName,
|
|
16
16
|
buildToolPresentationSchema,
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
import {
|
|
26
26
|
formatZodError,
|
|
27
27
|
validateDeclaredOutput
|
|
28
|
-
} from "./index-
|
|
28
|
+
} from "./index-7evdsyez.js";
|
|
29
29
|
import {
|
|
30
30
|
isUnsafeKey,
|
|
31
31
|
safeJsonParse
|
|
@@ -3,336 +3,25 @@ import {
|
|
|
3
3
|
inputIsQuery,
|
|
4
4
|
parseSSE,
|
|
5
5
|
readBoundedUtf8Lines
|
|
6
|
-
} from "./index-
|
|
6
|
+
} from "./index-qmgs7y68.js";
|
|
7
7
|
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
ApiError,
|
|
9
|
+
RequestCancellationError,
|
|
10
|
+
createRequestCancellation,
|
|
11
|
+
parseApiErrorBody,
|
|
12
|
+
refuseLocally,
|
|
13
|
+
responseTraceId
|
|
14
|
+
} from "./index-3xwxfj4z.js";
|
|
11
15
|
import {
|
|
12
16
|
ContractStreamFrameSchema,
|
|
13
17
|
DEFAULT_CONTRACT_STREAM_FRAME_BYTES,
|
|
14
18
|
parseTrailingWildcard
|
|
15
|
-
} from "./index-
|
|
19
|
+
} from "./index-2bxcmqkb.js";
|
|
16
20
|
import {
|
|
17
21
|
isRecord,
|
|
18
22
|
mapObject,
|
|
19
|
-
transportResult,
|
|
20
23
|
typedEntries
|
|
21
24
|
} from "./index-77fekveh.js";
|
|
22
|
-
|
|
23
|
-
// src/browser/http.ts
|
|
24
|
-
import ky, {
|
|
25
|
-
isHTTPError,
|
|
26
|
-
isNetworkError,
|
|
27
|
-
isTimeoutError
|
|
28
|
-
} from "ky";
|
|
29
|
-
|
|
30
|
-
// src/browser/cancellation.ts
|
|
31
|
-
class RequestCancellationError extends Error {
|
|
32
|
-
cause;
|
|
33
|
-
constructor(cause) {
|
|
34
|
-
super(cause === "caller" ? "Request was aborted" : "Request timed out");
|
|
35
|
-
this.cause = cause;
|
|
36
|
-
this.name = "RequestCancellationError";
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
function createRequestCancellation(caller, timeoutMs) {
|
|
40
|
-
if (!caller && timeoutMs === undefined) {
|
|
41
|
-
return { signal: undefined, run: (operation) => operation() };
|
|
42
|
-
}
|
|
43
|
-
const timeoutController = timeoutMs === undefined ? undefined : new AbortController;
|
|
44
|
-
const signal = caller && timeoutController ? AbortSignal.any([caller, timeoutController.signal]) : caller ?? timeoutController?.signal;
|
|
45
|
-
let cause;
|
|
46
|
-
let timer;
|
|
47
|
-
const abortFromCaller = () => {
|
|
48
|
-
if (cause)
|
|
49
|
-
return;
|
|
50
|
-
cause = "caller";
|
|
51
|
-
};
|
|
52
|
-
if (caller?.aborted)
|
|
53
|
-
abortFromCaller();
|
|
54
|
-
else
|
|
55
|
-
caller?.addEventListener("abort", abortFromCaller, { once: true });
|
|
56
|
-
if (timeoutMs !== undefined && timeoutController) {
|
|
57
|
-
timer = setTimeout(() => {
|
|
58
|
-
if (cause)
|
|
59
|
-
return;
|
|
60
|
-
cause = "timeout";
|
|
61
|
-
timeoutController.abort(new DOMException("Request timed out", "TimeoutError"));
|
|
62
|
-
}, timeoutMs);
|
|
63
|
-
}
|
|
64
|
-
return {
|
|
65
|
-
signal,
|
|
66
|
-
async run(operation) {
|
|
67
|
-
try {
|
|
68
|
-
if (cause === "caller")
|
|
69
|
-
throw cancellationError(cause);
|
|
70
|
-
return await operation(signal);
|
|
71
|
-
} catch (error) {
|
|
72
|
-
if (cause)
|
|
73
|
-
throw cancellationError(cause);
|
|
74
|
-
throw error;
|
|
75
|
-
} finally {
|
|
76
|
-
if (timer !== undefined)
|
|
77
|
-
clearTimeout(timer);
|
|
78
|
-
caller?.removeEventListener("abort", abortFromCaller);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
function cancellationError(cause) {
|
|
84
|
-
return new RequestCancellationError(cause);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// src/browser/request-id.ts
|
|
88
|
-
var REQUEST_ID_HEADER = "x-request-id";
|
|
89
|
-
function responseTraceId(response) {
|
|
90
|
-
return response?.headers.get(REQUEST_ID_HEADER) ?? undefined;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// src/browser/http.ts
|
|
94
|
-
var API_ERROR_BRAND = Symbol.for("stitchkit.ApiError");
|
|
95
|
-
function messageForCode(code, message) {
|
|
96
|
-
return message !== undefined && message.length > 0 ? message : `${code} (no message supplied)`;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
class ApiError extends Error {
|
|
100
|
-
code;
|
|
101
|
-
status;
|
|
102
|
-
details;
|
|
103
|
-
hint;
|
|
104
|
-
traceId;
|
|
105
|
-
constructor(code, status = 0, details, message, hint, traceId, options) {
|
|
106
|
-
super(messageForCode(code, message), options);
|
|
107
|
-
this.code = code;
|
|
108
|
-
this.status = status;
|
|
109
|
-
this.details = details;
|
|
110
|
-
this.hint = hint;
|
|
111
|
-
this.traceId = traceId;
|
|
112
|
-
this.name = "ApiError";
|
|
113
|
-
Object.defineProperty(this, API_ERROR_BRAND, { value: true });
|
|
114
|
-
}
|
|
115
|
-
static is(error) {
|
|
116
|
-
return typeof error === "object" && error !== null && API_ERROR_BRAND in error;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
function refuseLocally(path, message) {
|
|
120
|
-
return new ApiError("VALIDATION_ERROR", 0, { issues: [{ path, code: "invalid_type", message }] }, message);
|
|
121
|
-
}
|
|
122
|
-
function shouldRetryBunNetworkError(error) {
|
|
123
|
-
if (ApiError.is(error) || isHTTPError(error) || isNetworkError(error) || isTimeoutError(error) || error instanceof RequestCancellationError || error instanceof DOMException && (error.name === "AbortError" || error.name === "TimeoutError")) {
|
|
124
|
-
return;
|
|
125
|
-
}
|
|
126
|
-
if (!(error instanceof Error))
|
|
127
|
-
return;
|
|
128
|
-
const code = Object.getOwnPropertyDescriptor(error, "code");
|
|
129
|
-
return code && "value" in code && code.value === "ConnectionRefused" ? true : undefined;
|
|
130
|
-
}
|
|
131
|
-
function parseApiErrorBody(body) {
|
|
132
|
-
if (!isRecord(body) || !isRecord(body.error))
|
|
133
|
-
return null;
|
|
134
|
-
const error = body.error;
|
|
135
|
-
if (typeof error.code !== "string")
|
|
136
|
-
return null;
|
|
137
|
-
return {
|
|
138
|
-
code: error.code,
|
|
139
|
-
message: typeof error.message === "string" ? error.message : undefined,
|
|
140
|
-
details: error.details,
|
|
141
|
-
hint: typeof error.hint === "string" ? error.hint : undefined
|
|
142
|
-
};
|
|
143
|
-
}
|
|
144
|
-
function createRetryAwareFetch(transportFetch, unix) {
|
|
145
|
-
const runtimeFetch = transportFetch;
|
|
146
|
-
let attempt = 0;
|
|
147
|
-
return (input, init) => {
|
|
148
|
-
attempt += 1;
|
|
149
|
-
if (unix === undefined && attempt === 1) {
|
|
150
|
-
return runtimeFetch(input, init);
|
|
151
|
-
}
|
|
152
|
-
if (!(input instanceof Request)) {
|
|
153
|
-
if (unix === undefined)
|
|
154
|
-
return runtimeFetch(input, init);
|
|
155
|
-
const unixInit = { ...init, unix };
|
|
156
|
-
return runtimeFetch(input, unixInit);
|
|
157
|
-
}
|
|
158
|
-
const streamedBody = input.body ? { body: input.body, duplex: "half" } : {};
|
|
159
|
-
const materialized = {
|
|
160
|
-
...init,
|
|
161
|
-
...unix !== undefined && { unix },
|
|
162
|
-
method: input.method,
|
|
163
|
-
headers: input.headers,
|
|
164
|
-
...streamedBody,
|
|
165
|
-
cache: input.cache,
|
|
166
|
-
credentials: input.credentials,
|
|
167
|
-
integrity: input.integrity,
|
|
168
|
-
keepalive: input.keepalive,
|
|
169
|
-
mode: input.mode,
|
|
170
|
-
redirect: input.redirect,
|
|
171
|
-
referrer: input.referrer,
|
|
172
|
-
referrerPolicy: input.referrerPolicy,
|
|
173
|
-
signal: input.signal
|
|
174
|
-
};
|
|
175
|
-
return runtimeFetch(input.url, materialized);
|
|
176
|
-
};
|
|
177
|
-
}
|
|
178
|
-
function createHttpClient(config) {
|
|
179
|
-
if (config.fetch && config.unix) {
|
|
180
|
-
throw new TypeError("HttpClientConfig.fetch and unix are mutually exclusive");
|
|
181
|
-
}
|
|
182
|
-
if (config.unix !== undefined) {
|
|
183
|
-
if (!config.unix.startsWith("/") || config.unix.includes("\x00")) {
|
|
184
|
-
throw new TypeError("HttpClientConfig.unix must be an absolute Unix socket path");
|
|
185
|
-
}
|
|
186
|
-
if (typeof Reflect.get(globalThis, "Bun") !== "object") {
|
|
187
|
-
throw new TypeError("HttpClientConfig.unix requires Bun; on Bun or Node use createUnixClientTransport().fetch for an explicit portable transport");
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
let ssrCookies = null;
|
|
191
|
-
let isLoggedOut = false;
|
|
192
|
-
const listeners = new Set;
|
|
193
|
-
const suppressUnauthorizedFor = config.suppressUnauthorizedFor ?? [];
|
|
194
|
-
const parseError = config.parseError ?? parseApiErrorBody;
|
|
195
|
-
function emit(event) {
|
|
196
|
-
for (const fn of listeners) {
|
|
197
|
-
try {
|
|
198
|
-
fn(event);
|
|
199
|
-
} catch {}
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
const client = ky.create({
|
|
203
|
-
prefix: config.baseUrl,
|
|
204
|
-
credentials: config.credentials ?? "include",
|
|
205
|
-
timeout: false,
|
|
206
|
-
retry: {
|
|
207
|
-
limit: config.retry?.limit ?? 2,
|
|
208
|
-
methods: config.retry?.methods ?? ["get"],
|
|
209
|
-
statusCodes: config.retry?.statusCodes ?? [],
|
|
210
|
-
shouldRetry: ({ error }) => shouldRetryBunNetworkError(error)
|
|
211
|
-
},
|
|
212
|
-
hooks: {
|
|
213
|
-
beforeRequest: [
|
|
214
|
-
({ request: request2 }) => {
|
|
215
|
-
if (ssrCookies) {
|
|
216
|
-
request2.headers.set("Cookie", ssrCookies);
|
|
217
|
-
}
|
|
218
|
-
const extra = typeof config.headers === "function" ? config.headers() : config.headers;
|
|
219
|
-
if (extra) {
|
|
220
|
-
for (const [key, value] of Object.entries(extra)) {
|
|
221
|
-
request2.headers.set(key, value);
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
if (config.trace && !request2.headers.has("traceparent")) {
|
|
225
|
-
request2.headers.set("traceparent", formatTraceparent(createTraceContext()));
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
],
|
|
229
|
-
afterResponse: [
|
|
230
|
-
async ({ request: request2, response }) => {
|
|
231
|
-
if (response.status === 401) {
|
|
232
|
-
const url = new URL(request2.url).pathname;
|
|
233
|
-
if (!isLoggedOut && !suppressUnauthorizedFor.some((matches) => matches(url))) {
|
|
234
|
-
isLoggedOut = true;
|
|
235
|
-
emit({ type: "unauthorized" });
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
if (!response.ok) {
|
|
239
|
-
const body = await response.clone().json().catch(() => null);
|
|
240
|
-
if (body) {
|
|
241
|
-
const parsed = parseError(body);
|
|
242
|
-
if (parsed) {
|
|
243
|
-
throw new ApiError(parsed.code, response.status, parsed.details, parsed.message, parsed.hint, responseTraceId(response));
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
]
|
|
249
|
-
}
|
|
250
|
-
});
|
|
251
|
-
async function request(method, url, data, options = {}) {
|
|
252
|
-
const cancellation = createRequestCancellation(options.signal, options.timeout ?? config.timeout ?? 30000);
|
|
253
|
-
const kyOptions = {
|
|
254
|
-
fetch: createRetryAwareFetch(config.fetch ?? globalThis.fetch.bind(globalThis), config.unix),
|
|
255
|
-
timeout: false,
|
|
256
|
-
signal: cancellation.signal
|
|
257
|
-
};
|
|
258
|
-
if (options.params) {
|
|
259
|
-
const searchParams = new URLSearchParams;
|
|
260
|
-
for (const [key, value] of Object.entries(options.params)) {
|
|
261
|
-
if (value === undefined)
|
|
262
|
-
continue;
|
|
263
|
-
if (Array.isArray(value)) {
|
|
264
|
-
for (const item of value)
|
|
265
|
-
searchParams.append(key, String(item));
|
|
266
|
-
} else {
|
|
267
|
-
searchParams.set(key, String(value));
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
if (searchParams.size > 0) {
|
|
271
|
-
kyOptions.searchParams = searchParams;
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
if (data instanceof FormData) {
|
|
275
|
-
kyOptions.body = data;
|
|
276
|
-
} else if (data !== undefined) {
|
|
277
|
-
kyOptions.json = data;
|
|
278
|
-
}
|
|
279
|
-
try {
|
|
280
|
-
return await cancellation.run(async () => {
|
|
281
|
-
if (options.responseType === "blob") {
|
|
282
|
-
return transportResult(await client[method](url, kyOptions).blob());
|
|
283
|
-
}
|
|
284
|
-
if (options.responseType === "response") {
|
|
285
|
-
return transportResult(await client[method](url, kyOptions));
|
|
286
|
-
}
|
|
287
|
-
const response = await client[method](url, kyOptions);
|
|
288
|
-
if (options.responseType === "void") {
|
|
289
|
-
const text = await response.text();
|
|
290
|
-
if (text.length > 0) {
|
|
291
|
-
throw new Error("Server returned data for an endpoint with no output contract");
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
if (options.responseType === "void" || response.status === 204 || response.headers.get("content-length") === "0") {
|
|
295
|
-
return transportResult(undefined);
|
|
296
|
-
}
|
|
297
|
-
return await response.json();
|
|
298
|
-
});
|
|
299
|
-
} catch (error) {
|
|
300
|
-
if (error instanceof RequestCancellationError) {
|
|
301
|
-
throw new ApiError(error.cause === "caller" ? "REQUEST_ABORTED" : "REQUEST_TIMEOUT", 0, undefined, error.message);
|
|
302
|
-
}
|
|
303
|
-
if (ApiError.is(error))
|
|
304
|
-
throw error;
|
|
305
|
-
emit({ type: "network_error" });
|
|
306
|
-
const response = isHTTPError(error) ? error.response : undefined;
|
|
307
|
-
const status = response?.status ?? 0;
|
|
308
|
-
const msg = error instanceof Error ? error.message : undefined;
|
|
309
|
-
throw new ApiError("UNKNOWN_ERROR", status, msg ? { message: msg } : undefined, msg, undefined, responseTraceId(response), { cause: error });
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
return {
|
|
313
|
-
baseUrl: config.baseUrl,
|
|
314
|
-
get: (url, options) => request("get", url, undefined, options),
|
|
315
|
-
head: (url, options) => request("head", url, undefined, options),
|
|
316
|
-
post: (url, data, options) => request("post", url, data, options),
|
|
317
|
-
put: (url, data, options) => request("put", url, data, options),
|
|
318
|
-
patch: (url, data, options) => request("patch", url, data, options),
|
|
319
|
-
delete: (url, options) => request("delete", url, undefined, options),
|
|
320
|
-
setServerContext(cookies) {
|
|
321
|
-
ssrCookies = cookies;
|
|
322
|
-
},
|
|
323
|
-
subscribe(listener) {
|
|
324
|
-
listeners.add(listener);
|
|
325
|
-
return () => listeners.delete(listener);
|
|
326
|
-
},
|
|
327
|
-
logout() {
|
|
328
|
-
isLoggedOut = true;
|
|
329
|
-
emit({ type: "logout" });
|
|
330
|
-
},
|
|
331
|
-
resetLogoutState() {
|
|
332
|
-
isLoggedOut = false;
|
|
333
|
-
}
|
|
334
|
-
};
|
|
335
|
-
}
|
|
336
25
|
// src/browser/stream.ts
|
|
337
26
|
function parseFailure(raw, error, onParseError) {
|
|
338
27
|
const failure = error instanceof Error ? error : new Error(String(error));
|
|
@@ -955,4 +644,4 @@ function createScopedUrlBuilders(contracts, source, scopeConfigs) {
|
|
|
955
644
|
return buildScopedRegistry(contracts, scopeConfigs, "URL builder", (contract, config) => createUrlBuilder(contract, source, config));
|
|
956
645
|
}
|
|
957
646
|
|
|
958
|
-
export {
|
|
647
|
+
export { parseNDJSON, contractEndpointMatchers, createClient, createClients, createScopedClients, createUrlBuilder, createUrlBuilders, createScopedUrlBuilders };
|