@crvouga/mockingbird-service-junction 1.0.1 → 1.0.2
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 +8 -0
- package/README.md +26 -23
- package/dist/{chunk-2YNUCD2S.js → chunk-A4KJJ5V3.js} +5 -3
- package/dist/{chunk-2YNUCD2S.js.map → chunk-A4KJJ5V3.js.map} +2 -2
- package/dist/{chunk-KEP42KKR.js → chunk-GWXEPT6A.js} +67 -31
- package/dist/chunk-GWXEPT6A.js.map +7 -0
- package/dist/cli.js +5 -5
- package/dist/cli.js.map +2 -2
- package/dist/index.d.ts +120 -92
- package/dist/index.js +1 -1
- package/dist/server.d.ts +221 -165
- package/dist/server.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-KEP42KKR.js.map +0 -7
package/dist/cli.js
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
runCli,
|
|
5
5
|
serveCommand,
|
|
6
6
|
serveTarget
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-A4KJJ5V3.js";
|
|
8
8
|
import {
|
|
9
9
|
DEFAULT_JUNCTION_BASE_URL,
|
|
10
10
|
createRuntime,
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
isSandboxKey,
|
|
13
13
|
pullCorpus,
|
|
14
14
|
verifyAgainstReal
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-GWXEPT6A.js";
|
|
16
16
|
import {
|
|
17
17
|
defaultCorpus
|
|
18
18
|
} from "./chunk-C2UGIPPM.js";
|
|
@@ -23,11 +23,11 @@ import {
|
|
|
23
23
|
// src/cli.ts
|
|
24
24
|
import { readFile, writeFile } from "node:fs/promises";
|
|
25
25
|
var asString = (value) => typeof value === "string" && value !== "" ? value : void 0;
|
|
26
|
-
var realKeyOf = (values) => asString(values["real-key"]) ?? asString(process.env.
|
|
26
|
+
var realKeyOf = (values) => asString(values["real-key"]) ?? asString(process.env.JUNCTION_API_KEY) ?? asString(process.env.JUNCTION_API_KEY);
|
|
27
27
|
var readCorpus = async (source) => source === "default" ? defaultCorpus : parseSealedCorpus(JSON.parse(await readFile(source, "utf8")));
|
|
28
28
|
var guardKey = (key, values) => {
|
|
29
29
|
if (key === void 0) {
|
|
30
|
-
console.error("missing --real-key (or env
|
|
30
|
+
console.error("missing --real-key (or env JUNCTION_API_KEY)");
|
|
31
31
|
return void 0;
|
|
32
32
|
}
|
|
33
33
|
if (!isSandboxKey(key) && values["allow-any-key"] !== true) {
|
|
@@ -42,7 +42,7 @@ var REAL_OPTIONS = {
|
|
|
42
42
|
"real-key": {
|
|
43
43
|
type: "string",
|
|
44
44
|
value: "<key>",
|
|
45
|
-
description: "Junction API key (env
|
|
45
|
+
description: "Junction API key (env JUNCTION_API_KEY)"
|
|
46
46
|
},
|
|
47
47
|
"real-url": {
|
|
48
48
|
type: "string",
|
package/dist/cli.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/cli.ts"],
|
|
4
|
-
"sourcesContent": ["#!/usr/bin/env node\n/// <reference types=\"node\" />\nimport { readFile, writeFile } from \"node:fs/promises\"\nimport { type CliValues, runCli, serveCommand } from \"@crvouga/mockingbird-adapter-node\"\nimport { defaultCorpus } from \"./corpus.js\"\nimport { DEFAULT_JUNCTION_BASE_URL, diffCorpus, isSandboxKey, pullCorpus } from \"./corpus-tools.js\"\nimport { createRuntime } from \"./runtime.js\"\nimport { parseSealedCorpus, type SealedCorpus } from \"./sealed-corpus.js\"\nimport { loadCorpus, serveTarget } from \"./server.js\"\nimport { verifyAgainstReal } from \"./verify.js\"\n\nconst asString = (value: string | boolean | undefined): string | undefined =>\n typeof value === \"string\" && value !== \"\" ? value : undefined\n\nconst realKeyOf = (values: CliValues): string | undefined =>\n asString(values[\"real-key\"]) ??\n asString(process.env.
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;AAEA,SAAS,UAAU,iBAAiB;AASpC,IAAM,WAAW,CAAC,UAChB,OAAO,UAAU,YAAY,UAAU,KAAK,QAAQ;AAEtD,IAAM,YAAY,CAAC,WACjB,SAAS,OAAO,UAAU,CAAC,KAC3B,SAAS,QAAQ,IAAI,
|
|
4
|
+
"sourcesContent": ["#!/usr/bin/env node\n/// <reference types=\"node\" />\nimport { readFile, writeFile } from \"node:fs/promises\"\nimport { type CliValues, runCli, serveCommand } from \"@crvouga/mockingbird-adapter-node\"\nimport { defaultCorpus } from \"./corpus.js\"\nimport { DEFAULT_JUNCTION_BASE_URL, diffCorpus, isSandboxKey, pullCorpus } from \"./corpus-tools.js\"\nimport { createRuntime } from \"./runtime.js\"\nimport { parseSealedCorpus, type SealedCorpus } from \"./sealed-corpus.js\"\nimport { loadCorpus, serveTarget } from \"./server.js\"\nimport { verifyAgainstReal } from \"./verify.js\"\n\nconst asString = (value: string | boolean | undefined): string | undefined =>\n typeof value === \"string\" && value !== \"\" ? value : undefined\n\nconst realKeyOf = (values: CliValues): string | undefined =>\n asString(values[\"real-key\"]) ??\n asString(process.env.JUNCTION_API_KEY) ??\n asString(process.env.JUNCTION_API_KEY)\n\nconst readCorpus = async (source: string): Promise<SealedCorpus> =>\n source === \"default\"\n ? defaultCorpus\n : parseSealedCorpus(JSON.parse(await readFile(source, \"utf8\")))\n\nconst guardKey = (key: string | undefined, values: CliValues): string | undefined => {\n if (key === undefined) {\n console.error(\"missing --real-key (or env JUNCTION_API_KEY)\")\n return undefined\n }\n if (!isSandboxKey(key) && values[\"allow-any-key\"] !== true) {\n console.error(\n \"refusing a key that is not a sandbox team key (sk_us_\u2026 / sk_eu_\u2026); pass --allow-any-key to override\",\n )\n return undefined\n }\n return key\n}\n\nconst REAL_OPTIONS = {\n \"real-key\": {\n type: \"string\",\n value: \"<key>\",\n description: \"Junction API key (env JUNCTION_API_KEY)\",\n },\n \"real-url\": {\n type: \"string\",\n value: \"<url>\",\n description: \"Junction API base URL\",\n default: DEFAULT_JUNCTION_BASE_URL,\n },\n \"allow-any-key\": {\n type: \"boolean\",\n description: \"Allow a key that is not a sandbox team key\",\n },\n} as const\n\nconst code = await runCli(\n {\n bin: \"mockingbird-junction\",\n description: \"stateful Junction (Vital) API mock\",\n commands: {\n serve: serveCommand(serveTarget),\n\n \"corpus pull\": {\n summary: \"Record a corpus from a real Junction team (read-only GETs)\",\n usage: \"mockingbird-junction corpus pull --out <file> [--zip 10001,94105] [--base <file>]\",\n options: {\n ...REAL_OPTIONS,\n out: { type: \"string\", value: \"<file>\", description: \"Where to write the corpus\" },\n zip: {\n type: \"string\",\n value: \"<zip,zip,\u2026>\",\n description: \"ZIPs to record coverage for (default: the shipped set)\",\n },\n base: {\n type: \"string\",\n value: \"<file|default>\",\n description: \"Only refresh --zip on top of this corpus\",\n },\n \"coverage-only\": {\n type: \"boolean\",\n description: \"Skip the team's catalog and lab accounts\",\n },\n },\n async run(values) {\n const key = guardKey(realKeyOf(values), values)\n if (key === undefined) return 2\n const out = asString(values.out)\n if (out === undefined) {\n console.error(\"missing --out <file>\")\n return 2\n }\n const zips = asString(values.zip)\n ?.split(\",\")\n .map((zip) => zip.trim())\n .filter(Boolean)\n if (zips?.some((zip) => !/^\\d{5}$/.test(zip))) {\n console.error(\"--zip takes comma-separated 5-digit ZIPs\")\n return 2\n }\n const baseSource = asString(values.base)\n const corpus = await pullCorpus({\n apiKey: key,\n baseUrl: asString(values[\"real-url\"]) ?? DEFAULT_JUNCTION_BASE_URL,\n ...(zips ? { zips } : {}),\n ...(baseSource ? { base: await readCorpus(baseSource) } : {}),\n coverageOnly: values[\"coverage-only\"] === true,\n onProgress: (message) => console.log(`corpus pull: ${message}`),\n })\n await writeFile(out, `${JSON.stringify(corpus, null, 2)}\\n`)\n console.log(\n `corpus pull: wrote ${out} \u2014 ${Object.keys(corpus.observations).length} observations, ${corpus.catalog.labTests.length} lab tests, ${corpus.labAccounts.length} lab accounts, fingerprint ${corpus.fingerprint?.slice(0, 12)}`,\n )\n return 0\n },\n },\n\n \"corpus diff\": {\n summary: \"Show what changed between two corpora (exit 1 when they differ)\",\n usage: \"mockingbird-junction corpus diff <before|default> <after|default> [--json]\",\n options: { json: { type: \"boolean\", description: \"Print the diff as JSON\" } },\n async run(values, positionals) {\n const [beforePath, afterPath] = positionals\n if (beforePath === undefined || afterPath === undefined) {\n console.error(\"usage: mockingbird-junction corpus diff <before> <after>\")\n return 2\n }\n const diff = diffCorpus(await readCorpus(beforePath), await readCorpus(afterPath))\n if (values.json === true) {\n console.log(JSON.stringify(diff, null, 2))\n return diff.identical ? 0 : 1\n }\n if (diff.identical) {\n console.log(\"corpora are identical\")\n return 0\n }\n const section = (\n title: string,\n d: { added: string[]; removed: string[]; changed?: string[] },\n ) => {\n const total = d.added.length + d.removed.length + (d.changed?.length ?? 0)\n if (total === 0) return\n console.log(`${title}:`)\n for (const id of d.added) console.log(` + ${id}`)\n for (const id of d.removed) console.log(` - ${id}`)\n for (const id of d.changed ?? []) console.log(` ~ ${id}`)\n }\n section(\"ZIPs\", diff.zips)\n section(\"lab tests\", diff.labTests)\n section(\"lab accounts\", diff.labAccounts)\n const o = diff.observations\n console.log(\n `observations: +${o.added.length} -${o.removed.length} ~${o.changed.length} (--json lists them)`,\n )\n return 1\n },\n },\n\n verify: {\n summary: \"Replay the corpus and a stateful scenario against real Junction and the mock\",\n usage: \"mockingbird-junction verify --real-key <sk_us_\u2026> [--corpus <file>] [--orders]\",\n options: {\n ...REAL_OPTIONS,\n corpus: {\n type: \"string\",\n value: \"<default|file>\",\n description: \"Corpus the mock serves and drift is checked against\",\n default: \"default\",\n },\n sample: {\n type: \"string\",\n value: \"<n>\",\n description: \"Re-fetch at most n recorded observations (default: all)\",\n },\n \"skip-drift\": { type: \"boolean\", description: \"Only run the stateful scenario\" },\n orders: {\n type: \"boolean\",\n description: \"Also place and cancel an order on the real team\",\n },\n json: { type: \"boolean\", description: \"Print the report as JSON\" },\n },\n async run(values) {\n const key = guardKey(realKeyOf(values), values)\n if (key === undefined) return 2\n const corpus = await loadCorpus(asString(values.corpus) ?? \"default\")\n if (!corpus) {\n console.error(\"verify needs a corpus (--corpus default or a file)\")\n return 2\n }\n const sample = asString(values.sample)\n const report = await verifyAgainstReal({\n realKey: key,\n realUrl: asString(values[\"real-url\"]) ?? DEFAULT_JUNCTION_BASE_URL,\n mock: createRuntime({ corpus }),\n corpus,\n ...(sample !== undefined ? { sample: Number.parseInt(sample, 10) } : {}),\n skipDrift: values[\"skip-drift\"] === true,\n orders: values.orders === true,\n ...(values.json === true\n ? {}\n : { onProgress: (message: string) => console.log(`verify: ${message}`) }),\n })\n if (values.json === true) {\n console.log(JSON.stringify(report, null, 2))\n } else {\n for (const d of report.divergences) {\n console.log(`DIVERGED ${d.check} (${d.kind}${d.at ? ` at ${d.at}` : \"\"})`)\n console.log(` real: ${JSON.stringify(d.real)?.slice(0, 400)}`)\n console.log(` mock: ${JSON.stringify(d.mock)?.slice(0, 400)}`)\n }\n console.log(\n `verify: drift ${report.drift.stale}/${report.drift.checked} stale; scenario ${report.scenario.divergent}/${report.scenario.steps} divergent \u2014 ${report.ok ? \"OK\" : \"DIVERGED\"}`,\n )\n }\n return report.ok ? 0 : 1\n },\n },\n },\n },\n process.argv.slice(2),\n)\nif (code !== 0) process.exitCode = code\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -169,82 +169,6 @@ type FaultRegistry = {
|
|
|
169
169
|
take(candidate: FaultCandidate): Promise<FaultHit[]>;
|
|
170
170
|
};
|
|
171
171
|
|
|
172
|
-
/** One handled request, as the structured log sees it. */
|
|
173
|
-
type RequestLog = {
|
|
174
|
-
service: string;
|
|
175
|
-
namespace: string;
|
|
176
|
-
operationId: string | undefined;
|
|
177
|
-
method: string;
|
|
178
|
-
path: string;
|
|
179
|
-
status: number;
|
|
180
|
-
durationMs: number;
|
|
181
|
-
/** True when the path matched no operation in the contract. */
|
|
182
|
-
unmatched: boolean;
|
|
183
|
-
/** Set when a fault rule produced the response. */
|
|
184
|
-
faultId?: string;
|
|
185
|
-
/** Resource ids the handler touched (`userId`, `orderId`, …), when the service reports them. */
|
|
186
|
-
ids?: Record<string, string>;
|
|
187
|
-
/** Set when the service created a resource the request referred to but that did not exist. */
|
|
188
|
-
adopted?: boolean;
|
|
189
|
-
};
|
|
190
|
-
type MetricsReport = {
|
|
191
|
-
requests: number;
|
|
192
|
-
/** Counts keyed `<operationId> <status>`. */
|
|
193
|
-
byOperation: Record<string, number>;
|
|
194
|
-
/**
|
|
195
|
-
* Paths that matched no operation, most frequent first.
|
|
196
|
-
*
|
|
197
|
-
* This is the early-warning signal: a consumer calling something the mock does
|
|
198
|
-
* not implement shows up here as a count, before it fails a suite as a 404.
|
|
199
|
-
*/
|
|
200
|
-
unmatched: {
|
|
201
|
-
method: string;
|
|
202
|
-
path: string;
|
|
203
|
-
count: number;
|
|
204
|
-
}[];
|
|
205
|
-
faults: number;
|
|
206
|
-
totalDurationMs: number;
|
|
207
|
-
};
|
|
208
|
-
type Metrics = {
|
|
209
|
-
record(entry: RequestLog): void;
|
|
210
|
-
report(): MetricsReport;
|
|
211
|
-
reset(): void;
|
|
212
|
-
};
|
|
213
|
-
|
|
214
|
-
/** One journal entry: a request log stamped with when (on the mock clock) it was handled. */
|
|
215
|
-
type JournalEntry = RequestLog & {
|
|
216
|
-
at: string;
|
|
217
|
-
};
|
|
218
|
-
type JournalQuery = {
|
|
219
|
-
/** Only this namespace. Omit for every namespace, oldest first across all of them. */
|
|
220
|
-
namespace?: string;
|
|
221
|
-
operationId?: string;
|
|
222
|
-
status?: number;
|
|
223
|
-
/** Only entries at or after this instant (epoch ms). */
|
|
224
|
-
since?: number;
|
|
225
|
-
/** At most this many, the most recent kept. */
|
|
226
|
-
limit?: number;
|
|
227
|
-
};
|
|
228
|
-
type Journal = {
|
|
229
|
-
readonly size: number;
|
|
230
|
-
record(entry: JournalEntry): void;
|
|
231
|
-
list(query?: JournalQuery): JournalEntry[];
|
|
232
|
-
/** Forget one namespace's entries, or every namespace's. */
|
|
233
|
-
clear(namespace?: string): void;
|
|
234
|
-
};
|
|
235
|
-
|
|
236
|
-
/** Credential → namespace mapping behind `PUT /__admin/credentials`. */
|
|
237
|
-
type CredentialRegistry = {
|
|
238
|
-
set(credential: string, namespace: string): void;
|
|
239
|
-
get(credential: string): string | undefined;
|
|
240
|
-
remove(credential: string): boolean;
|
|
241
|
-
clear(): void;
|
|
242
|
-
entries(): {
|
|
243
|
-
credential: string;
|
|
244
|
-
namespace: string;
|
|
245
|
-
}[];
|
|
246
|
-
};
|
|
247
|
-
|
|
248
172
|
/** A stable identifier for a point in a {@link Timeline}. */
|
|
249
173
|
type CheckpointId = string;
|
|
250
174
|
/** An immutable node in a timeline's checkpoint DAG. */
|
|
@@ -335,6 +259,123 @@ interface FetchAPI$1 {
|
|
|
335
259
|
fetch(request: Request): Promise<Response>;
|
|
336
260
|
}
|
|
337
261
|
|
|
262
|
+
/** Options every provider constructor accepts. */
|
|
263
|
+
type APIOptions = {
|
|
264
|
+
/** Sync SQLite client. Defaults to `@crvouga/mockingbird-service-sqlite`. */
|
|
265
|
+
sqlite?: SqliteClient$1;
|
|
266
|
+
/** Clock used for `created`-style fields. Default `Date.now`. */
|
|
267
|
+
now?: () => number;
|
|
268
|
+
/**
|
|
269
|
+
* Storage namespace for this instance's records. Instances sharing one SQLite
|
|
270
|
+
* client stay isolated when their namespaces differ. Defaults to the service name.
|
|
271
|
+
*/
|
|
272
|
+
namespace?: string;
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* One problem with a request body, at a dotted path (`patient.address.city`, `items.0.sku`).
|
|
277
|
+
* `kind` is `media_type` when the body is present but its media type is not one the operation
|
|
278
|
+
* accepts (a `415` on most vendors), `syntax` when it could not be decoded, `required` when
|
|
279
|
+
* the operation needs a body and none arrived, and `schema` for a contract violation.
|
|
280
|
+
*/
|
|
281
|
+
type BodyIssue = {
|
|
282
|
+
path: string;
|
|
283
|
+
message: string;
|
|
284
|
+
kind?: "media_type" | "syntax" | "required" | "schema";
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* What the mock received from a request it rejected, so a 4xx can be attributed after the
|
|
289
|
+
* fact (an empty body, a missing `content-type`, a schema violation) without logging the body.
|
|
290
|
+
*/
|
|
291
|
+
type RejectedRequest = {
|
|
292
|
+
/** The raw `content-type` header, or `null` when the request sent none. */
|
|
293
|
+
contentType: string | null;
|
|
294
|
+
/** Bytes of body received from `content-length` (`0` for none), or `null` when the client sent no length (a streamed / chunked body). */
|
|
295
|
+
bodyBytes: number | null;
|
|
296
|
+
/** The raw `transfer-encoding` header (`chunked`), or `null`. */
|
|
297
|
+
transferEncoding: string | null;
|
|
298
|
+
};
|
|
299
|
+
/** One handled request, as the structured log sees it. */
|
|
300
|
+
type RequestLog = {
|
|
301
|
+
service: string;
|
|
302
|
+
namespace: string;
|
|
303
|
+
operationId: string | undefined;
|
|
304
|
+
method: string;
|
|
305
|
+
path: string;
|
|
306
|
+
status: number;
|
|
307
|
+
durationMs: number;
|
|
308
|
+
/** True when the path matched no operation in the contract. */
|
|
309
|
+
unmatched: boolean;
|
|
310
|
+
/** Set when a fault rule produced the response. */
|
|
311
|
+
faultId?: string;
|
|
312
|
+
/** Resource ids the handler touched (`userId`, `orderId`, …), when the service reports them. */
|
|
313
|
+
ids?: Record<string, string>;
|
|
314
|
+
/** Set when the service created a resource the request referred to but that did not exist. */
|
|
315
|
+
adopted?: boolean;
|
|
316
|
+
/** Set on a rejection (status ≥ 400) the mock produced itself, never on a scripted fault. */
|
|
317
|
+
request?: RejectedRequest;
|
|
318
|
+
/** The validation issues behind a rejection, when the service found any. */
|
|
319
|
+
issues?: BodyIssue[];
|
|
320
|
+
};
|
|
321
|
+
type MetricsReport = {
|
|
322
|
+
requests: number;
|
|
323
|
+
/** Counts keyed `<operationId> <status>`. */
|
|
324
|
+
byOperation: Record<string, number>;
|
|
325
|
+
/**
|
|
326
|
+
* Paths that matched no operation, most frequent first.
|
|
327
|
+
*
|
|
328
|
+
* This is the early-warning signal: a consumer calling something the mock does
|
|
329
|
+
* not implement shows up here as a count, before it fails a suite as a 404.
|
|
330
|
+
*/
|
|
331
|
+
unmatched: {
|
|
332
|
+
method: string;
|
|
333
|
+
path: string;
|
|
334
|
+
count: number;
|
|
335
|
+
}[];
|
|
336
|
+
faults: number;
|
|
337
|
+
totalDurationMs: number;
|
|
338
|
+
};
|
|
339
|
+
type Metrics = {
|
|
340
|
+
record(entry: RequestLog): void;
|
|
341
|
+
report(): MetricsReport;
|
|
342
|
+
reset(): void;
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
/** One journal entry: a request log stamped with when (on the mock clock) it was handled. */
|
|
346
|
+
type JournalEntry = RequestLog & {
|
|
347
|
+
at: string;
|
|
348
|
+
};
|
|
349
|
+
type JournalQuery = {
|
|
350
|
+
/** Only this namespace. Omit for every namespace, oldest first across all of them. */
|
|
351
|
+
namespace?: string;
|
|
352
|
+
operationId?: string;
|
|
353
|
+
status?: number;
|
|
354
|
+
/** Only entries at or after this instant (epoch ms). */
|
|
355
|
+
since?: number;
|
|
356
|
+
/** At most this many, the most recent kept. */
|
|
357
|
+
limit?: number;
|
|
358
|
+
};
|
|
359
|
+
type Journal = {
|
|
360
|
+
readonly size: number;
|
|
361
|
+
record(entry: JournalEntry): void;
|
|
362
|
+
list(query?: JournalQuery): JournalEntry[];
|
|
363
|
+
/** Forget one namespace's entries, or every namespace's. */
|
|
364
|
+
clear(namespace?: string): void;
|
|
365
|
+
};
|
|
366
|
+
|
|
367
|
+
/** Credential → namespace mapping behind `PUT /__admin/credentials`. */
|
|
368
|
+
type CredentialRegistry = {
|
|
369
|
+
set(credential: string, namespace: string): void;
|
|
370
|
+
get(credential: string): string | undefined;
|
|
371
|
+
remove(credential: string): boolean;
|
|
372
|
+
clear(): void;
|
|
373
|
+
entries(): {
|
|
374
|
+
credential: string;
|
|
375
|
+
namespace: string;
|
|
376
|
+
}[];
|
|
377
|
+
};
|
|
378
|
+
|
|
338
379
|
/**
|
|
339
380
|
* A point-in-time copy of everything a service namespace holds.
|
|
340
381
|
*
|
|
@@ -485,19 +526,6 @@ type ServiceRuntime<T extends ServiceInstance> = FetchAPI$1 & {
|
|
|
485
526
|
timeline(namespace?: string): Timeline<ServiceTimelineState>;
|
|
486
527
|
};
|
|
487
528
|
|
|
488
|
-
/** Options every provider constructor accepts. */
|
|
489
|
-
type APIOptions = {
|
|
490
|
-
/** Sync SQLite client. Defaults to `@crvouga/mockingbird-service-sqlite`. */
|
|
491
|
-
sqlite?: SqliteClient$1;
|
|
492
|
-
/** Clock used for `created`-style fields. Default `Date.now`. */
|
|
493
|
-
now?: () => number;
|
|
494
|
-
/**
|
|
495
|
-
* Storage namespace for this instance's records. Instances sharing one SQLite
|
|
496
|
-
* client stay isolated when their namespaces differ. Defaults to the service name.
|
|
497
|
-
*/
|
|
498
|
-
namespace?: string;
|
|
499
|
-
};
|
|
500
|
-
|
|
501
529
|
/** Bind values accepted by Mockingbird's SQLite port (matches sqlite-mem / better-sqlite3). */
|
|
502
530
|
type SqliteValue = null | number | bigint | string | Uint8Array | boolean;
|
|
503
531
|
/** Mutation counters returned by {@link SqliteStatement.run}. */
|
|
@@ -848,9 +876,9 @@ declare const OTHER_TEAM_ID: string;
|
|
|
848
876
|
declare const TEAM_LAB_ACCOUNTS: readonly LabAccountRecord[];
|
|
849
877
|
/**
|
|
850
878
|
* Whether `teamId` may use an account. An empty `team_id_allowlist` counts as linked:
|
|
851
|
-
* a real team's listing returns such accounts (
|
|
852
|
-
*
|
|
853
|
-
*
|
|
879
|
+
* a real team's listing returns such accounts (Junction's own Quest, Labcorp and
|
|
880
|
+
* BioReference accounts carry `[]`), and the sandbox places an order that names one by id
|
|
881
|
+
* (corpus/lab-account-probes.json), so the mock treats them as the team's.
|
|
854
882
|
*/
|
|
855
883
|
declare const isLinkedToTeam: (entry: LabAccountRecord, teamId: string) => boolean;
|
|
856
884
|
/**
|