@crvouga/mockingbird-service-rxvortex 0.2.0 → 1.1.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/dist/cli.js CHANGED
@@ -3,8 +3,8 @@ import {
3
3
  runCli,
4
4
  serveCommand,
5
5
  serveTarget
6
- } from "./chunk-ZAM35JQO.js";
7
- import "./chunk-DNELVPK4.js";
6
+ } from "./chunk-SNW7NYY6.js";
7
+ import "./chunk-VQAJFAUO.js";
8
8
 
9
9
  // src/cli.ts
10
10
  var code = await runCli(
package/dist/index.d.ts CHANGED
@@ -619,6 +619,17 @@ declare const CUSTOM_CREAM_ANCHOR_PRESET_ID = "e404ad76-0f82-4b04-8f25-841650e2e
619
619
  * it with the real rows); the custom-cream anchor preset must always resolve.
620
620
  */
621
621
  declare const DEFAULT_CATALOG: readonly CatalogItem[];
622
+ /**
623
+ * One catalog row from loose input: `catalog_id` and `medication_name` are required; the
624
+ * other fields default to `null`, `states` to `[]` and `status` to `"active"`.
625
+ */
626
+ declare const parseCatalogItem: (value: unknown) => CatalogItem;
627
+ /**
628
+ * Catalog rows from a JSON value: a bare array, or the `{data: [...]}` envelope
629
+ * `GET /api/v1/preset-catalog-items` answers with (so a recorded response loads as-is).
630
+ * Throws on the first malformed row.
631
+ */
632
+ declare const parseCatalog: (value: unknown) => CatalogItem[];
622
633
 
623
634
  /**
624
635
  * One order as the vendor tracks it. Patient and prescriber details are validated but never
@@ -662,6 +673,12 @@ type Settings = {
662
673
  client_secret: string;
663
674
  }[];
664
675
  autoAdvance: AutoAdvance | null;
676
+ /**
677
+ * What a submit does with a well-formed `preset_catalog_id` the catalog does not hold:
678
+ * `"reject"` answers 422 as the sandbox does; `"accept"` adds it as an active row named
679
+ * after the request's `medication_name`. Inactive rows are refused either way.
680
+ */
681
+ unknownPresets: "reject" | "accept";
665
682
  };
666
683
  declare class RxVortexState {
667
684
  private readonly seed;
@@ -670,11 +687,14 @@ declare class RxVortexState {
670
687
  readonly settings: Collection<Settings>;
671
688
  readonly ids: IdSequence;
672
689
  constructor(sqlite: SqliteClient, namespace: string, seed: {
673
- catalog: readonly CatalogItem[];
690
+ catalog: readonly CatalogItem[] | undefined;
674
691
  settings: Partial<Settings>;
675
692
  });
676
693
  /** Re-apply the catalog and settings after a reset. */
677
694
  ensureSeeded(): void;
695
+ /** Load rows: `replace` drops every other row first, `merge` upserts by `catalog_id`. */
696
+ putCatalog(items: readonly CatalogItem[], mode: "replace" | "merge"): number;
697
+ catalogRows(): CatalogItem[];
678
698
  current(): Settings;
679
699
  update(patch: Partial<Settings>): Settings;
680
700
  /** By vendor tracking id first, then by our sender order id (the recovery lookup). */
@@ -864,6 +884,10 @@ type RxVortexRuntimeOptions = {
864
884
  seed?: number | string;
865
885
  adminKey?: string;
866
886
  onLog?: (entry: RequestLog) => void;
887
+ /**
888
+ * Rows every namespace starts with, and returns to on `POST /__admin/reset` (`serve
889
+ * --catalog <file>`). Default: `DEFAULT_CATALOG`.
890
+ */
867
891
  catalog?: readonly CatalogItem[];
868
892
  settings?: Partial<Settings>;
869
893
  /** Where status webhooks go (`POST /prescriptions/webhooks/rxvortex`), sent with the secret header. */
@@ -950,6 +974,11 @@ declare class RxVortexAPI implements FetchAPI$1 {
950
974
  private iso;
951
975
  private generateToken;
952
976
  private createOrder;
977
+ /**
978
+ * Under `unknownPresets: "accept"`, a well-formed preset id the catalog lacks becomes an
979
+ * active row described by the request, so later submits and catalog reads see it.
980
+ */
981
+ private adoptPreset;
953
982
  private getOrder;
954
983
  private cancelOrder;
955
984
  /** Move an order to a vendor status, set the three fields coherently, emit the webhook. */
@@ -962,5 +991,5 @@ declare class RxVortexAPI implements FetchAPI$1 {
962
991
  orders(): OrderRecord[];
963
992
  }
964
993
 
965
- export { CUSTOM_CREAM_ANCHOR_PRESET_ID, DEFAULT_CATALOG, RXVORTEX_NAMESPACE, RXVORTEX_PRESETS, RxVortexAPI, createRuntime, document, operationIds, supportedOperationIds, tokenCredential };
994
+ export { CUSTOM_CREAM_ANCHOR_PRESET_ID, DEFAULT_CATALOG, RXVORTEX_NAMESPACE, RXVORTEX_PRESETS, RxVortexAPI, createRuntime, document, operationIds, parseCatalog, parseCatalogItem, supportedOperationIds, tokenCredential };
966
995
  export type { AutoAdvance, CatalogItem, FetchAPI$1 as FetchAPI, OperationId, OrderRecord, RxVortexAPIOptions, RxVortexRuntime, RxVortexRuntimeOptions, RxVortexWebhook, Settings, SqliteClient, SupportedOperationId, TransitionInput };
package/dist/index.js CHANGED
@@ -7,9 +7,11 @@ import {
7
7
  createRuntime,
8
8
  document,
9
9
  operationIds,
10
+ parseCatalog,
11
+ parseCatalogItem,
10
12
  supportedOperationIds,
11
13
  tokenCredential
12
- } from "./chunk-DNELVPK4.js";
14
+ } from "./chunk-VQAJFAUO.js";
13
15
  export {
14
16
  CUSTOM_CREAM_ANCHOR_PRESET_ID,
15
17
  DEFAULT_CATALOG,
@@ -19,6 +21,8 @@ export {
19
21
  createRuntime,
20
22
  document,
21
23
  operationIds,
24
+ parseCatalog,
25
+ parseCatalogItem,
22
26
  supportedOperationIds,
23
27
  tokenCredential
24
28
  };
package/dist/server.d.ts CHANGED
@@ -523,6 +523,20 @@ type Listening = {
523
523
  close(): Promise<void>;
524
524
  };
525
525
 
526
+ /** One preset catalog row, in the field names `GET /api/v1/preset-catalog-items` uses. */
527
+ type CatalogItem = {
528
+ catalog_id: string;
529
+ medication_name: string;
530
+ medication_strength: string | null;
531
+ package_size: string | null;
532
+ quantity: number | null;
533
+ quantity_units: string | null;
534
+ medication_form: string | null;
535
+ route: string | null;
536
+ states: string[];
537
+ status: "active" | "inactive";
538
+ };
539
+
526
540
  /**
527
541
  * The single source of time for a service.
528
542
  *
@@ -1098,20 +1112,6 @@ interface SqliteClient {
1098
1112
  transaction<T>(fn: () => T): T;
1099
1113
  }
1100
1114
 
1101
- /** One preset catalog row, in the field names `GET /api/v1/preset-catalog-items` uses. */
1102
- type CatalogItem = {
1103
- catalog_id: string;
1104
- medication_name: string;
1105
- medication_strength: string | null;
1106
- package_size: string | null;
1107
- quantity: number | null;
1108
- quantity_units: string | null;
1109
- medication_form: string | null;
1110
- route: string | null;
1111
- states: string[];
1112
- status: "active" | "inactive";
1113
- };
1114
-
1115
1115
  /**
1116
1116
  * Anything that can answer a Fetch `Request` with a `Response`.
1117
1117
  *
@@ -1164,6 +1164,12 @@ type Settings = {
1164
1164
  client_secret: string;
1165
1165
  }[];
1166
1166
  autoAdvance: AutoAdvance | null;
1167
+ /**
1168
+ * What a submit does with a well-formed `preset_catalog_id` the catalog does not hold:
1169
+ * `"reject"` answers 422 as the sandbox does; `"accept"` adds it as an active row named
1170
+ * after the request's `medication_name`. Inactive rows are refused either way.
1171
+ */
1172
+ unknownPresets: "reject" | "accept";
1167
1173
  };
1168
1174
  declare class RxVortexState {
1169
1175
  private readonly seed;
@@ -1172,11 +1178,14 @@ declare class RxVortexState {
1172
1178
  readonly settings: Collection<Settings>;
1173
1179
  readonly ids: IdSequence;
1174
1180
  constructor(sqlite: SqliteClient, namespace: string, seed: {
1175
- catalog: readonly CatalogItem[];
1181
+ catalog: readonly CatalogItem[] | undefined;
1176
1182
  settings: Partial<Settings>;
1177
1183
  });
1178
1184
  /** Re-apply the catalog and settings after a reset. */
1179
1185
  ensureSeeded(): void;
1186
+ /** Load rows: `replace` drops every other row first, `merge` upserts by `catalog_id`. */
1187
+ putCatalog(items: readonly CatalogItem[], mode: "replace" | "merge"): number;
1188
+ catalogRows(): CatalogItem[];
1180
1189
  current(): Settings;
1181
1190
  update(patch: Partial<Settings>): Settings;
1182
1191
  /** By vendor tracking id first, then by our sender order id (the recovery lookup). */
@@ -1235,6 +1244,11 @@ declare class RxVortexAPI implements FetchAPI {
1235
1244
  private iso;
1236
1245
  private generateToken;
1237
1246
  private createOrder;
1247
+ /**
1248
+ * Under `unknownPresets: "accept"`, a well-formed preset id the catalog lacks becomes an
1249
+ * active row described by the request, so later submits and catalog reads see it.
1250
+ */
1251
+ private adoptPreset;
1238
1252
  private getOrder;
1239
1253
  private cancelOrder;
1240
1254
  /** Move an order to a vendor status, set the three fields coherently, emit the webhook. */
@@ -1253,6 +1267,10 @@ type RxVortexRuntimeOptions = {
1253
1267
  seed?: number | string;
1254
1268
  adminKey?: string;
1255
1269
  onLog?: (entry: RequestLog) => void;
1270
+ /**
1271
+ * Rows every namespace starts with, and returns to on `POST /__admin/reset` (`serve
1272
+ * --catalog <file>`). Default: `DEFAULT_CATALOG`.
1273
+ */
1256
1274
  catalog?: readonly CatalogItem[];
1257
1275
  settings?: Partial<Settings>;
1258
1276
  /** Where status webhooks go (`POST /prescriptions/webhooks/rxvortex`), sent with the secret header. */
@@ -1287,8 +1305,13 @@ type RxVortexServer = Listening & {
1287
1305
  };
1288
1306
  /** Serve the RxVortex mock over `node:http`, with auto-advance ticking every 100 ms. */
1289
1307
  declare const createServer: (options?: RxVortexServerOptions) => Promise<RxVortexServer>;
1308
+ /**
1309
+ * Read a catalog file: a JSON array of rows, or the `{data: [...]}` body
1310
+ * `GET /api/v1/preset-catalog-items` answers with, so a recorded response loads as-is.
1311
+ */
1312
+ declare const loadCatalogFile: (path: string) => CatalogItem[];
1290
1313
  /** How `serve` (and `serve --config`) builds the RxVortex mock from flags. */
1291
1314
  declare const serveTarget: ServeTarget;
1292
1315
 
1293
- export { DEFAULT_PORT, createServer, serveTarget };
1316
+ export { DEFAULT_PORT, createServer, loadCatalogFile, serveTarget };
1294
1317
  export type { RxVortexServer, RxVortexServerOptions };
package/dist/server.js CHANGED
@@ -1,12 +1,14 @@
1
1
  import {
2
2
  DEFAULT_PORT,
3
3
  createServer,
4
+ loadCatalogFile,
4
5
  serveTarget
5
- } from "./chunk-ZAM35JQO.js";
6
- import "./chunk-DNELVPK4.js";
6
+ } from "./chunk-SNW7NYY6.js";
7
+ import "./chunk-VQAJFAUO.js";
7
8
  export {
8
9
  DEFAULT_PORT,
9
10
  createServer,
11
+ loadCatalogFile,
10
12
  serveTarget
11
13
  };
12
14
  //# sourceMappingURL=server.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crvouga/mockingbird-service-rxvortex",
3
- "version": "0.2.0",
3
+ "version": "1.1.0",
4
4
  "description": "Stateful mock of the RxVortex (Strive) pharmacy API: OAuth token, order submit, status, cancel, recovery by sender order id, preset catalog, and signed status webhooks.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -52,7 +52,11 @@
52
52
  "layer": "service",
53
53
  "category": "pharmacy",
54
54
  "displayName": "RxVortex",
55
- "status": "wip"
55
+ "vendor": {
56
+ "website": "https://www.rxvortex.com",
57
+ "description": "RxVortex is a pharmacy order platform whose API lets telehealth partners submit, track and cancel prescription orders with pharmacies such as Strive."
58
+ },
59
+ "status": "ready"
56
60
  },
57
61
  "scripts": {
58
62
  "generate": "bun ../../openapi/codegen/dist/cli.js",
@@ -67,7 +71,7 @@
67
71
  "pack:check": "bun ../../../scripts/pack-check.ts"
68
72
  },
69
73
  "dependencies": {
70
- "@crvouga/mockingbird-service-sqlite": "0.3.0",
74
+ "@crvouga/mockingbird-service-sqlite": "1.0.0",
71
75
  "hono": "4.11.9"
72
76
  },
73
77
  "devDependencies": {
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../adapters/node/src/cli.ts", "../../../adapters/node/src/serve.ts", "../../../adapters/node/src/listen.ts", "../src/server.ts"],
4
- "sourcesContent": ["import { readFile } from \"node:fs/promises\"\nimport { type ParseArgsConfig, parseArgs } from \"node:util\"\nimport type { RequestLog, ServiceInstance, ServiceRuntime } from \"@crvouga/mockingbird-service\"\nimport { type Listening, listen } from \"./listen.js\"\n\nexport type CliOption = {\n type: \"string\" | \"boolean\"\n description: string\n /** Shown in help; the value placeholder, e.g. `<port>`. */\n value?: string\n default?: string | boolean\n}\n\nexport type CliValues = Record<string, string | boolean | undefined>\n\nexport type CliCommand = {\n summary: string\n usage?: string\n options?: Record<string, CliOption>\n /** Resolves to an exit code; a server command resolves only when it stops. */\n run(values: CliValues, positionals: string[]): Promise<number>\n}\n\nexport type CliSpec = {\n bin: string\n description: string\n commands: Record<string, CliCommand>\n}\n\nconst optionHelp = (options: Record<string, CliOption>): string[] =>\n Object.entries(options).map(([name, option]) => {\n const flag = `--${name}${option.type === \"string\" ? ` ${option.value ?? \"<value>\"}` : \"\"}`\n const fallback = option.default !== undefined ? ` (default: ${String(option.default)})` : \"\"\n return ` ${flag.padEnd(30)} ${option.description}${fallback}`\n })\n\nconst help = (spec: CliSpec): string =>\n [\n `${spec.bin} \u2014 ${spec.description}`,\n \"\",\n \"Usage:\",\n ` ${spec.bin} <command> [options]`,\n \"\",\n \"Commands:\",\n ...Object.entries(spec.commands).map(([name, c]) => ` ${name.padEnd(30)} ${c.summary}`),\n \"\",\n `Run \\`${spec.bin} <command> --help\\` for a command's options.`,\n ].join(\"\\n\")\n\nconst commandHelp = (spec: CliSpec, name: string, command: CliCommand): string =>\n [\n `${spec.bin} ${name} \u2014 ${command.summary}`,\n \"\",\n \"Usage:\",\n ` ${command.usage ?? `${spec.bin} ${name} [options]`}`,\n ...(command.options ? [\"\", \"Options:\", ...optionHelp(command.options)] : []),\n ].join(\"\\n\")\n\n/** Parse `argv` against `spec` and run the chosen command. Resolves to an exit code. */\nexport const runCli = async (spec: CliSpec, argv: string[]): Promise<number> => {\n // Two-word commands (`corpus pull`) win over one-word ones.\n const pair = argv.length >= 2 ? `${argv[0]} ${argv[1]}` : undefined\n const words = pair !== undefined && spec.commands[pair] ? 2 : 1\n const name = words === 2 ? pair : argv[0]\n const rest = argv.slice(words)\n if (name === undefined || name === \"--help\" || name === \"-h\" || name === \"help\") {\n console.log(help(spec))\n return 0\n }\n const command = spec.commands[name]\n if (!command) {\n console.error(`${spec.bin}: unknown command ${JSON.stringify(name)}\\n\\n${help(spec)}`)\n return 2\n }\n if (rest.includes(\"--help\") || rest.includes(\"-h\")) {\n console.log(commandHelp(spec, name, command))\n return 0\n }\n let parsed: { values: CliValues; positionals: string[] }\n try {\n parsed = parseArgs({\n args: rest,\n allowPositionals: true,\n strict: true,\n options: Object.fromEntries(\n Object.entries(command.options ?? {}).map(([key, option]) => [\n key,\n {\n type: option.type,\n ...(option.default !== undefined ? { default: option.default } : {}),\n },\n ]),\n ) as ParseArgsConfig[\"options\"],\n }) as { values: CliValues; positionals: string[] }\n } catch (error) {\n console.error(\n `${spec.bin} ${name}: ${error instanceof Error ? error.message : String(error)}\\n\\n${commandHelp(spec, name, command)}`,\n )\n return 2\n }\n return command.run(parsed.values, parsed.positionals)\n}\n\n// \u2500\u2500 serve \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport type LogFormat = \"pretty\" | \"json\" | \"off\"\n\nexport type CommonServeOptions = {\n adminKey: string | undefined\n seed: string | undefined\n onLog: ((entry: RequestLog) => void) | undefined\n}\n\n/**\n * What a service contributes to `serve`: how to build its runtime from CLI flags,\n * and what to say at startup. Every service's `./server` entry exports one as\n * `serveTarget`, which is also how `serve --config` finds services by name.\n */\nexport type ServeTarget = {\n name: string\n defaultPort: number\n /** Serve flags beyond the common ones. */\n options?: Record<string, CliOption>\n create(\n values: CliValues,\n common: CommonServeOptions,\n ): Promise<ServiceRuntime<ServiceInstance>> | ServiceRuntime<ServiceInstance>\n /** Startup lines after the listen address, e.g. the loaded corpus version. */\n banner?(runtime: ServiceRuntime<ServiceInstance>): string[]\n}\n\nconst COMMON_SERVE_OPTIONS: Record<string, CliOption> = {\n port: { type: \"string\", value: \"<port>\", description: \"Port to listen on\" },\n host: { type: \"string\", value: \"<host>\", description: \"Interface to bind\", default: \"127.0.0.1\" },\n \"admin-key\": {\n type: \"string\",\n value: \"<key>\",\n description: \"Require x-mockingbird-admin-key on /__admin/* (env MOCKINGBIRD_ADMIN_KEY)\",\n },\n seed: { type: \"string\", value: \"<seed>\", description: \"Seed for every random choice\" },\n log: {\n type: \"string\",\n value: \"<pretty|json|off>\",\n description: \"Request log format\",\n default: \"pretty\",\n },\n \"log-requests\": {\n type: \"boolean\",\n description:\n \"One JSON line per request: namespace, operationId, status, ids touched (never bodies). Same as --log json\",\n },\n config: {\n type: \"string\",\n value: \"<file>\",\n description: \"Serve every service in a mockingbird.json config instead\",\n },\n}\n\nconst formatLog = (format: LogFormat) => {\n if (format === \"off\") return undefined\n if (format === \"json\") return (entry: RequestLog) => console.log(JSON.stringify(entry))\n return (entry: RequestLog) => {\n const op = entry.operationId ?? (entry.unmatched ? \"UNMATCHED\" : \"-\")\n const ns = entry.namespace === \"default\" ? \"\" : ` [${entry.namespace}]`\n const fault = entry.faultId ? ` fault=${entry.faultId}` : \"\"\n const adopted = entry.adopted ? \" adopted\" : \"\"\n console.log(\n `${entry.service} ${entry.method} ${entry.path} ${entry.status} ${op} ${entry.durationMs}ms${ns}${fault}${adopted}`,\n )\n }\n}\n\nconst asString = (value: string | boolean | undefined): string | undefined =>\n typeof value === \"string\" ? value : undefined\n\n/** A service entry in `mockingbird.json`. */\nexport type ConfigService = {\n port?: number\n host?: string\n adminKey?: string\n seed?: string\n /** Service-specific serve flags, by long name: `{ \"webhook-url\": \"\u2026\" }`. */\n options?: Record<string, string | boolean>\n}\n\nexport type MockingbirdConfig = {\n /** Keyed by service name: `junction` loads `@crvouga/mockingbird-service-junction`. */\n services: Record<string, ConfigService>\n log?: LogFormat\n}\n\nconst loadTarget = async (name: string, own: ServeTarget): Promise<ServeTarget> => {\n if (name === own.name) return own\n const specifier = `@crvouga/mockingbird-service-${name}/server`\n try {\n const mod = (await import(specifier)) as { serveTarget?: ServeTarget }\n if (!mod.serveTarget) throw new Error(`${specifier} exports no serveTarget`)\n return mod.serveTarget\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error)\n throw new Error(\n `cannot load service \"${name}\": ${reason}. Install @crvouga/mockingbird-service-${name}.`,\n )\n }\n}\n\nconst start = async (\n target: ServeTarget,\n values: CliValues,\n config: { port: number; host: string; adminKey?: string; seed?: string; log: LogFormat },\n): Promise<Listening> => {\n const runtime = await target.create(values, {\n adminKey: config.adminKey,\n seed: config.seed,\n onLog: formatLog(config.log),\n })\n const listening = await listen(runtime, { port: config.port, host: config.host })\n console.log(`${target.name} mock listening on ${listening.url}`)\n console.log(`${target.name} health: GET ${listening.url}/health`)\n console.log(\n `${target.name} admin: ${listening.url}/__admin (${config.adminKey ? \"x-mockingbird-admin-key required\" : \"open \u2014 pass --admin-key to lock\"})`,\n )\n for (const line of target.banner?.(runtime) ?? []) console.log(`${target.name} ${line}`)\n return listening\n}\n\nconst untilSignal = async (servers: Listening[]): Promise<number> =>\n new Promise((resolve) => {\n const stop = async () => {\n await Promise.allSettled(servers.map((s) => s.close()))\n resolve(0)\n }\n process.once(\"SIGINT\", stop)\n process.once(\"SIGTERM\", stop)\n })\n\n/** The standard `serve` command for a service, including multi-service `--config`. */\nexport const serveCommand = (target: ServeTarget): CliCommand => ({\n summary: `Serve the ${target.name} mock over HTTP`,\n options: { ...COMMON_SERVE_OPTIONS, ...target.options },\n async run(values) {\n const log = (\n values[\"log-requests\"] === true ? \"json\" : (asString(values.log) ?? \"pretty\")\n ) as LogFormat\n if (![\"pretty\", \"json\", \"off\"].includes(log)) {\n console.error(`--log must be pretty, json or off (got ${log})`)\n return 2\n }\n const configPath = asString(values.config)\n if (configPath !== undefined) {\n const config = JSON.parse(await readFile(configPath, \"utf8\")) as MockingbirdConfig\n const servers: Listening[] = []\n try {\n for (const [name, entry] of Object.entries(config.services ?? {})) {\n const each = await loadTarget(name, target)\n servers.push(\n await start(each, entry.options ?? {}, {\n port: entry.port ?? each.defaultPort,\n host: entry.host ?? \"127.0.0.1\",\n ...(entry.adminKey !== undefined ? { adminKey: entry.adminKey } : {}),\n ...(entry.seed !== undefined ? { seed: entry.seed } : {}),\n log: config.log ?? log,\n }),\n )\n }\n } catch (error) {\n await Promise.allSettled(servers.map((s) => s.close()))\n console.error(error instanceof Error ? error.message : String(error))\n return 1\n }\n return untilSignal(servers)\n }\n const port = asString(values.port)\n const adminKey = asString(values[\"admin-key\"]) ?? process.env.MOCKINGBIRD_ADMIN_KEY\n const seed = asString(values.seed)\n let listening: Listening\n try {\n listening = await start(target, values, {\n port: port === undefined ? target.defaultPort : Number.parseInt(port, 10),\n host: asString(values.host) ?? \"127.0.0.1\",\n ...(adminKey !== undefined ? { adminKey } : {}),\n ...(seed !== undefined ? { seed } : {}),\n log,\n })\n } catch (error) {\n console.error(error instanceof Error ? error.message : String(error))\n return 1\n }\n return untilSignal([listening])\n },\n})\n", "import { createServer } from \"node:http\"\nimport type { FetchAPI } from \"@crvouga/mockingbird-core\"\n\n/** Options for {@link serve}. */\nexport type NodeServeOptions = {\n port?: number\n host?: string\n}\n\n/**\n * Serve any Mockingbird {@link FetchAPI} over `node:http`.\n * Port defaults to `0`, so the OS assigns an ephemeral port (read from `server.address()`).\n */\nexport const serve = async (api: FetchAPI, options: NodeServeOptions = {}) => {\n const server = createServer(async (req, res) => {\n const chunks: Buffer[] = []\n for await (const chunk of req) {\n chunks.push(Buffer.from(chunk))\n }\n const body = Buffer.concat(chunks)\n const address = server.address()\n const port = typeof address === \"object\" && address !== null ? address.port : undefined\n const base = `http://${req.headers.host ?? `localhost:${port ?? 80}`}`\n const raw = req.url ?? \"/\"\n const url = new URL(raw.replace(/^\\/+/, \"/\"), base)\n const method = req.method ?? \"GET\"\n const init: RequestInit = { method, headers: req.headers as Record<string, string> }\n if (method !== \"GET\" && method !== \"HEAD\" && body.length > 0) {\n init.body = body\n }\n const aborted = new AbortController()\n res.once(\"close\", () => {\n if (!res.writableFinished) aborted.abort()\n })\n init.signal = aborted.signal\n const request = new Request(url, init)\n let response: Response\n try {\n response = await api.fetch(request)\n } catch (error) {\n // A `drop` fault: destroy the socket so the client sees the connection die.\n if ((error as { code?: string }).code === \"MOCKINGBIRD_DROP\") {\n req.socket.destroy()\n return\n }\n res.writeHead(500, { \"content-type\": \"application/json\" })\n res.end(\n JSON.stringify({\n error: {\n type: \"mockingbird_internal\",\n message: error instanceof Error ? error.message : String(error),\n },\n }),\n )\n return\n }\n // Headers#entries() joins repeated headers; Set-Cookie must stay one header per cookie.\n const headers: Record<string, string | string[]> = Object.fromEntries(response.headers)\n const cookies = response.headers.getSetCookie()\n if (cookies.length > 0) headers[\"set-cookie\"] = cookies\n if (!response.body) {\n res.writeHead(response.status, headers)\n res.end()\n return\n }\n // Stream the body chunk by chunk: event streams and long-polls must not be buffered.\n res.writeHead(response.status, headers)\n res.flushHeaders()\n const reader = response.body.getReader()\n try {\n for (;;) {\n const { done, value } = await reader.read()\n if (done) break\n if (!res.write(value)) await new Promise<void>((resolve) => res.once(\"drain\", resolve))\n }\n res.end()\n } catch {\n res.destroy()\n } finally {\n reader.releaseLock()\n }\n })\n await new Promise<void>((resolve, reject) => {\n server.once(\"error\", reject)\n server.listen(options.port ?? 0, options.host, resolve)\n })\n return server\n}\n", "import type { Server } from \"node:http\"\nimport type { FetchAPI } from \"@crvouga/mockingbird-core\"\nimport { serve } from \"./serve.js\"\n\nexport type ListenOptions = {\n /** Default `0`: the OS picks a free port. */\n port?: number\n /** Default `127.0.0.1`: a mock should not be reachable off the machine by accident. */\n host?: string\n}\n\n/** A running server, with the address it actually bound. */\nexport type Listening = {\n url: string\n port: number\n host: string\n server: Server\n close(): Promise<void>\n}\n\nexport const listen = async (api: FetchAPI, options: ListenOptions = {}): Promise<Listening> => {\n const host = options.host ?? \"127.0.0.1\"\n const server = await serve(api, { port: options.port ?? 0, host })\n const address = server.address()\n const port = typeof address === \"object\" && address !== null ? address.port : (options.port ?? 0)\n const shown = host.includes(\":\") ? `[${host}]` : host\n return {\n url: `http://${shown}:${port}`,\n port,\n host,\n server,\n close: () =>\n new Promise<void>((resolve, reject) => {\n // Stop accepting first, then drop keep-alive sockets so close() can finish.\n server.close((error) => {\n if (error && (error as { code?: string }).code !== \"ERR_SERVER_NOT_RUNNING\") reject(error)\n else resolve()\n })\n server.closeAllConnections?.()\n }),\n }\n}\n", "/// <reference types=\"node\" />\nimport { type Listening, listen, type ServeTarget } from \"@crvouga/mockingbird-adapter-node\"\nimport { createRuntime, type RxVortexRuntime, type RxVortexRuntimeOptions } from \"./runtime.js\"\n\n/** Port `mockingbird-rxvortex serve` listens on when none is given. */\nexport const DEFAULT_PORT = 8791\n\nexport type RxVortexServerOptions = RxVortexRuntimeOptions & {\n /** Default `0`: the OS picks a free port. */\n port?: number\n /** Default `127.0.0.1`. */\n host?: string\n}\n\nexport type RxVortexServer = Listening & { runtime: RxVortexRuntime }\n\n/** Serve the RxVortex mock over `node:http`, with auto-advance ticking every 100 ms. */\nexport const createServer = async (\n options: RxVortexServerOptions = {},\n): Promise<RxVortexServer> => {\n const { port, host, ...rest } = options\n const runtime = createRuntime({ tickMs: 100, ...rest })\n const listening = await listen(runtime, {\n port: port ?? 0,\n ...(host !== undefined ? { host } : {}),\n })\n return {\n ...listening,\n runtime,\n close: async () => {\n runtime.stop()\n await listening.close()\n },\n }\n}\n\nconst text = (value: string | boolean | undefined) =>\n typeof value === \"string\" ? value : undefined\n\n/** How `serve` (and `serve --config`) builds the RxVortex mock from flags. */\nexport const serveTarget: ServeTarget = {\n name: \"rxvortex\",\n defaultPort: DEFAULT_PORT,\n options: {\n \"webhook-url\": {\n type: \"string\",\n value: \"<url>\",\n description:\n \"Deliver status webhooks here (e.g. http://127.0.0.1:3000/prescriptions/webhooks/rxvortex)\",\n },\n \"webhook-secret\": {\n type: \"string\",\n value: \"<secret>\",\n description: \"Sent as x-rxvortex-webhook-secret (the app's RXVORTEX_WEBHOOK_SECRET)\",\n },\n \"api-token\": {\n type: \"string\",\n value: \"<token>\",\n description: \"A static bearer token to accept (the app's RXVORTEX_API_TOKEN)\",\n },\n \"auto-advance\": {\n type: \"string\",\n value: \"<ms:Status,Status,\u2026>\",\n description: 'Walk every new order along a path, e.g. \"2000:Fill,Shipping,Delivered\"',\n },\n },\n create: (values, common) => {\n const url = text(values[\"webhook-url\"])\n const secret = text(values[\"webhook-secret\"])\n const token = text(values[\"api-token\"])\n const auto = text(values[\"auto-advance\"])\n const plan = auto ? /^(\\d+):(.+)$/.exec(auto) : null\n if (auto && !plan)\n throw new Error('--auto-advance must look like \"2000:Fill,Shipping,Delivered\"')\n return createRuntime({\n tickMs: 100,\n ...(url ? { webhooks: { url, ...(secret ? { secret } : {}) } } : {}),\n settings: {\n ...(token ? { staticTokens: [token] } : {}),\n ...(plan\n ? {\n autoAdvance: {\n afterMs: Number(plan[1]),\n path: (plan[2] as string).split(\",\").map((s) => s.trim()),\n },\n }\n : {}),\n },\n ...(common.adminKey !== undefined ? { adminKey: common.adminKey } : {}),\n ...(common.seed !== undefined ? { seed: common.seed } : {}),\n ...(common.onLog ? { onLog: common.onLog } : {}),\n })\n },\n banner: () => [\n \"auth: POST /api/v1/generate-access-token {client_id, client_secret}, then Authorization: Bearer <token>\",\n \"namespaces: x-mockingbird-namespace, /ns/<name>/\u2026, or PUT /__admin/credentials {<client_id>: <ns>}\",\n ],\n}\n"],
5
- "mappings": "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",
6
- "names": ["createServer"]
7
- }