@crvouga/mockingbird-service-step-functions 3.6.0 → 3.7.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.
@@ -3,17 +3,31 @@ import {
3
3
  createRuntime,
4
4
  normalizeBootControls,
5
5
  normalizeControls,
6
+ normalizeIdBase,
6
7
  ownedTransport,
7
8
  parseDuration,
8
9
  parseFaultHeader,
9
10
  resolveAdminPrefix,
10
11
  restoreClock
11
- } from "./chunk-WM6TYPGJ.js";
12
+ } from "./chunk-3A5FTNZP.js";
12
13
 
13
14
  // ../../adapters/node/dist/cli.js
14
15
  import { readFile as readFile5 } from "node:fs/promises";
15
16
  import { parseArgs } from "node:util";
16
17
 
18
+ // ../../adapters/node/dist/boot-settings.js
19
+ var checkSettings = (target, settings, label) => {
20
+ if (!target.parseSettings)
21
+ throw new Error(`${label}: ${target.name} takes no boot settings`);
22
+ try {
23
+ return target.parseSettings(settings);
24
+ } catch (error) {
25
+ throw new Error(`${label}: ${error instanceof Error ? error.message : String(error)}`, {
26
+ cause: error
27
+ });
28
+ }
29
+ };
30
+
17
31
  // ../../adapters/node/dist/fleet.js
18
32
  import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
19
33
  import { createHash as createHash4, randomUUID as randomUUID4 } from "node:crypto";
@@ -2663,6 +2677,9 @@ var fleet_config_schema_default = {
2663
2677
  adminControls: {
2664
2678
  $ref: "#/$defs/controls"
2665
2679
  },
2680
+ idBase: {
2681
+ $ref: "#/$defs/idBase"
2682
+ },
2666
2683
  namespace: {
2667
2684
  type: "string",
2668
2685
  pattern: "^[A-Za-z0-9_.-]{1,64}$"
@@ -2752,6 +2769,12 @@ var fleet_config_schema_default = {
2752
2769
  adminControls: {
2753
2770
  $ref: "#/$defs/controls"
2754
2771
  },
2772
+ idBase: {
2773
+ $ref: "#/$defs/idBase"
2774
+ },
2775
+ settings: {
2776
+ type: "object"
2777
+ },
2755
2778
  fixtures: {
2756
2779
  type: "object"
2757
2780
  },
@@ -2798,6 +2821,18 @@ var fleet_config_schema_default = {
2798
2821
  }
2799
2822
  }
2800
2823
  },
2824
+ idBase: {
2825
+ anyOf: [
2826
+ {
2827
+ type: "integer",
2828
+ minimum: 0
2829
+ },
2830
+ {
2831
+ type: "string",
2832
+ pattern: "^(boot|[0-9]+)$"
2833
+ }
2834
+ ]
2835
+ },
2801
2836
  controls: {
2802
2837
  type: "object",
2803
2838
  additionalProperties: false,
@@ -2947,6 +2982,8 @@ async function preflightFleet(config, options) {
2947
2982
  throw new Error("protected archive policy requires a protected repository; configure its protector before startup");
2948
2983
  resolveAdminPrefix(config.adminPrefix);
2949
2984
  normalizeBootControls(config.adminControls);
2985
+ if (config.idBase !== void 0)
2986
+ normalizeIdBase(config.idBase, "idBase");
2950
2987
  const targets = /* @__PURE__ */ new Map();
2951
2988
  const ports = /* @__PURE__ */ new Set();
2952
2989
  for (const [name, entry] of Object.entries(config.services)) {
@@ -2978,6 +3015,13 @@ async function preflightFleet(config, options) {
2978
3015
  throw new Error("invalid protocol namespace selector");
2979
3016
  }
2980
3017
  }
3018
+ if (entry.idBase !== void 0)
3019
+ normalizeIdBase(entry.idBase, "idBase");
3020
+ if (entry.settings !== void 0) {
3021
+ if (protocol !== "http" || !("create" in target))
3022
+ throw new Error("settings: only HTTP services take boot settings");
3023
+ checkSettings(target, entry.settings, "settings");
3024
+ }
2981
3025
  const port = entry.port ?? target.defaultPort;
2982
3026
  if (port !== 0) {
2983
3027
  const key = `${entry.host ?? "127.0.0.1"}:${port}`;
@@ -3013,7 +3057,7 @@ async function preflightFleet(config, options) {
3013
3057
  break;
3014
3058
  }
3015
3059
  }
3016
- targets.set(name, { ...target, packageVersion: packageVersion ?? "3.6.0" });
3060
+ targets.set(name, { ...target, packageVersion: packageVersion ?? "3.7.0" });
3017
3061
  } catch (error) {
3018
3062
  throw new Error(`service ${name}: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
3019
3063
  }
@@ -3333,6 +3377,7 @@ var httpChild = async (target, entry, options, admission, generation, privateAcc
3333
3377
  options.onLog?.(entry2);
3334
3378
  },
3335
3379
  ...entry.adminControls !== void 0 ? { adminControls: entry.adminControls } : {},
3380
+ ...entry.settings !== void 0 ? { settings: checkSettings(target, entry.settings, "settings") } : {},
3336
3381
  ...entry.fixtures !== void 0 ? { fixtures: entry.fixtures } : {},
3337
3382
  ...(advertisedHttpBase(entry) ?? entry.baseUrl) !== void 0 ? { baseUrl: advertisedHttpBase(entry) ?? entry.baseUrl } : {}
3338
3383
  });
@@ -3351,6 +3396,8 @@ var httpChild = async (target, entry, options, admission, generation, privateAcc
3351
3396
  ].some((method) => typeof created[method] !== "function"))
3352
3397
  throw new Error("HTTP target does not implement the fleet runtime protocol; build/install matching supported service versions");
3353
3398
  const runtime = created;
3399
+ if (entry.idBase !== void 0)
3400
+ runtime.setIdBase?.(entry.idBase);
3354
3401
  const unobserve = runtime.webhooks?.observeDeliveries(observer.delivery);
3355
3402
  if (options.outbound && runtime.webhooks)
3356
3403
  runtime.webhooks.setTransportPolicy(ownedTransport(options.outbound));
@@ -3949,6 +3996,7 @@ async function startFleet(config, options) {
3949
3996
  ...entry,
3950
3997
  adminPrefix: resolveAdminPrefix(entry.adminPrefix ?? adminPrefix),
3951
3998
  ...adminKey !== void 0 ? { adminKey } : {},
3999
+ ...(entry.idBase ?? config.idBase) !== void 0 ? { idBase: entry.idBase ?? config.idBase } : {},
3952
4000
  // Fleet-wide controls, with the service's own keys replacing them.
3953
4001
  ...config.adminControls !== void 0 || entry.adminControls !== void 0 ? { adminControls: { ...config.adminControls, ...entry.adminControls } } : {}
3954
4002
  }, options, (namespace, request) => management?.admit(namespace, request), (namespace) => management?.generation(namespace), (namespace, request) => management?.privateRequest(namespace, request) ?? false, {
@@ -4633,6 +4681,16 @@ var COMMON_SERVE_OPTIONS = {
4633
4681
  value: "<seed>",
4634
4682
  description: "Seed for every random choice (env MOCKINGBIRD_SEED)"
4635
4683
  },
4684
+ "id-base": {
4685
+ type: "string",
4686
+ value: "<n|boot>",
4687
+ description: "Start generated ids at this base so a restart does not reissue the last boot's ids; boot derives one from the clock (env MOCKINGBIRD_ID_BASE; default 0, the same ids every boot)"
4688
+ },
4689
+ settings: {
4690
+ type: "string",
4691
+ value: "<json|file>",
4692
+ description: "Service settings to boot with, as JSON or a JSON file; every namespace starts from them (env MOCKINGBIRD_SETTINGS; only for services that declare settings)"
4693
+ },
4636
4694
  "admin-controls": {
4637
4695
  type: "string",
4638
4696
  value: "<json|file>",
@@ -4727,19 +4785,40 @@ var readJsonFile = async (path, label) => {
4727
4785
  }
4728
4786
  };
4729
4787
  var isObject2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
4788
+ var readJsonOption = async (source, label) => {
4789
+ const trimmed = source.trim();
4790
+ if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
4791
+ try {
4792
+ return JSON.parse(trimmed);
4793
+ } catch {
4794
+ throw new Error(`${label}: not valid JSON`);
4795
+ }
4796
+ }
4797
+ return readJsonFile(source, label);
4798
+ };
4799
+ var resolveServeIdBase = (values, env = process.env) => {
4800
+ const source = asString(values["id-base"]) ?? env.MOCKINGBIRD_ID_BASE;
4801
+ if (source === void 0 || source.trim() === "")
4802
+ return void 0;
4803
+ normalizeIdBase(source.trim(), "--id-base");
4804
+ return source.trim();
4805
+ };
4806
+ var resolveServeSettings = async (target, values, env = process.env) => {
4807
+ const flag = asString(values.settings);
4808
+ const source = flag ?? env.MOCKINGBIRD_SETTINGS;
4809
+ if (source === void 0 || source.trim() === "")
4810
+ return void 0;
4811
+ const label = flag !== void 0 ? "--settings" : "MOCKINGBIRD_SETTINGS";
4812
+ const parsed = await readJsonOption(source, label);
4813
+ if (!isObject2(parsed))
4814
+ throw new Error(`${label}: expected a JSON object`);
4815
+ return checkSettings(target, parsed, label);
4816
+ };
4730
4817
  var resolveServeControls = async (values, env = process.env, base) => {
4731
4818
  const source = asString(values["admin-controls"]) ?? env.MOCKINGBIRD_ADMIN_CONTROLS;
4732
4819
  let document = isObject2(base) ? { ...base } : {};
4733
4820
  if (source !== void 0 && source.trim() !== "") {
4734
- let parsed;
4735
- if (source.trim().startsWith("{")) {
4736
- try {
4737
- parsed = JSON.parse(source);
4738
- } catch {
4739
- throw new Error("--admin-controls: not valid JSON");
4740
- }
4741
- } else
4742
- parsed = await readJsonFile(source, "--admin-controls");
4821
+ const parsed = source.trim().startsWith("{") ? await readJsonOption(source, "--admin-controls") : await readJsonFile(source, "--admin-controls");
4743
4822
  if (!isObject2(parsed))
4744
4823
  throw new Error("--admin-controls: expected a JSON object");
4745
4824
  document = { ...document, ...parsed };
@@ -4789,8 +4868,11 @@ var start = async (target, values, config) => {
4789
4868
  adminKey: config.adminKey,
4790
4869
  seed: config.seed,
4791
4870
  onLog: formatLog(config.log),
4871
+ ...config.settings !== void 0 ? { settings: config.settings } : {},
4792
4872
  ...config.adminControls !== void 0 ? { adminControls: config.adminControls } : {}
4793
4873
  });
4874
+ if (config.idBase !== void 0)
4875
+ runtime.setIdBase?.(config.idBase);
4794
4876
  const listening = await listen(runtime, { port: config.port, host: config.host });
4795
4877
  target.listening?.(listening);
4796
4878
  console.log(`${target.name} emulator listening on ${listening.url}`);
@@ -4836,6 +4918,11 @@ var serveCommand = (target) => ({
4836
4918
  const adminControls = await resolveServeControls(values, process.env, config.adminControls);
4837
4919
  if (adminControls !== void 0)
4838
4920
  config.adminControls = adminControls;
4921
+ if (values.settings !== void 0)
4922
+ throw new Error("--settings serves a single service; give each service its own `settings` in the config");
4923
+ const idBase = config.idBase ?? resolveServeIdBase(values);
4924
+ if (idBase !== void 0)
4925
+ config.idBase = idBase;
4839
4926
  const fleet = await startFleet(config, {
4840
4927
  load: (name) => loadTarget(name, target),
4841
4928
  onLog: formatLog(config.log ?? log),
@@ -4865,8 +4952,12 @@ var serveCommand = (target) => ({
4865
4952
  let listening;
4866
4953
  try {
4867
4954
  const adminControls = await resolveServeControls(values);
4955
+ const idBase = resolveServeIdBase(values);
4956
+ const settings = await resolveServeSettings(target, values);
4868
4957
  listening = await start(target, values, {
4869
4958
  ...adminControls !== void 0 ? { adminControls } : {},
4959
+ ...idBase !== void 0 ? { idBase } : {},
4960
+ ...settings !== void 0 ? { settings } : {},
4870
4961
  adminPrefix: resolveAdminPrefix(asString(values["admin-prefix"]) ?? process.env.MOCKINGBIRD_ADMIN_PREFIX),
4871
4962
  port: port === void 0 ? target.defaultPort : Number.parseInt(port, 10),
4872
4963
  host: asString(values.host) ?? "127.0.0.1",
@@ -4912,4 +5003,4 @@ export {
4912
5003
  createServer2 as createServer,
4913
5004
  serveTarget
4914
5005
  };
4915
- //# sourceMappingURL=chunk-X4DADTG3.js.map
5006
+ //# sourceMappingURL=chunk-RWOXKPES.js.map