@crvouga/mockingbird-service-payload-cms 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,12 +3,13 @@ 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-Z6NY3ESF.js";
12
+ } from "./chunk-4LD2P27R.js";
12
13
 
13
14
  // src/server.ts
14
15
  import { readFile as readFile6 } from "node:fs/promises";
@@ -17,6 +18,19 @@ import { readFile as readFile6 } from "node:fs/promises";
17
18
  import { readFile as readFile5 } from "node:fs/promises";
18
19
  import { parseArgs } from "node:util";
19
20
 
21
+ // ../../adapters/node/dist/boot-settings.js
22
+ var checkSettings = (target, settings, label) => {
23
+ if (!target.parseSettings)
24
+ throw new Error(`${label}: ${target.name} takes no boot settings`);
25
+ try {
26
+ return target.parseSettings(settings);
27
+ } catch (error) {
28
+ throw new Error(`${label}: ${error instanceof Error ? error.message : String(error)}`, {
29
+ cause: error
30
+ });
31
+ }
32
+ };
33
+
20
34
  // ../../adapters/node/dist/fleet.js
21
35
  import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
22
36
  import { createHash as createHash4, randomUUID as randomUUID4 } from "node:crypto";
@@ -2666,6 +2680,9 @@ var fleet_config_schema_default = {
2666
2680
  adminControls: {
2667
2681
  $ref: "#/$defs/controls"
2668
2682
  },
2683
+ idBase: {
2684
+ $ref: "#/$defs/idBase"
2685
+ },
2669
2686
  namespace: {
2670
2687
  type: "string",
2671
2688
  pattern: "^[A-Za-z0-9_.-]{1,64}$"
@@ -2755,6 +2772,12 @@ var fleet_config_schema_default = {
2755
2772
  adminControls: {
2756
2773
  $ref: "#/$defs/controls"
2757
2774
  },
2775
+ idBase: {
2776
+ $ref: "#/$defs/idBase"
2777
+ },
2778
+ settings: {
2779
+ type: "object"
2780
+ },
2758
2781
  fixtures: {
2759
2782
  type: "object"
2760
2783
  },
@@ -2801,6 +2824,18 @@ var fleet_config_schema_default = {
2801
2824
  }
2802
2825
  }
2803
2826
  },
2827
+ idBase: {
2828
+ anyOf: [
2829
+ {
2830
+ type: "integer",
2831
+ minimum: 0
2832
+ },
2833
+ {
2834
+ type: "string",
2835
+ pattern: "^(boot|[0-9]+)$"
2836
+ }
2837
+ ]
2838
+ },
2804
2839
  controls: {
2805
2840
  type: "object",
2806
2841
  additionalProperties: false,
@@ -2950,6 +2985,8 @@ async function preflightFleet(config, options) {
2950
2985
  throw new Error("protected archive policy requires a protected repository; configure its protector before startup");
2951
2986
  resolveAdminPrefix(config.adminPrefix);
2952
2987
  normalizeBootControls(config.adminControls);
2988
+ if (config.idBase !== void 0)
2989
+ normalizeIdBase(config.idBase, "idBase");
2953
2990
  const targets = /* @__PURE__ */ new Map();
2954
2991
  const ports = /* @__PURE__ */ new Set();
2955
2992
  for (const [name, entry] of Object.entries(config.services)) {
@@ -2981,6 +3018,13 @@ async function preflightFleet(config, options) {
2981
3018
  throw new Error("invalid protocol namespace selector");
2982
3019
  }
2983
3020
  }
3021
+ if (entry.idBase !== void 0)
3022
+ normalizeIdBase(entry.idBase, "idBase");
3023
+ if (entry.settings !== void 0) {
3024
+ if (protocol !== "http" || !("create" in target))
3025
+ throw new Error("settings: only HTTP services take boot settings");
3026
+ checkSettings(target, entry.settings, "settings");
3027
+ }
2984
3028
  const port = entry.port ?? target.defaultPort;
2985
3029
  if (port !== 0) {
2986
3030
  const key = `${entry.host ?? "127.0.0.1"}:${port}`;
@@ -3016,7 +3060,7 @@ async function preflightFleet(config, options) {
3016
3060
  break;
3017
3061
  }
3018
3062
  }
3019
- targets.set(name, { ...target, packageVersion: packageVersion ?? "3.6.0" });
3063
+ targets.set(name, { ...target, packageVersion: packageVersion ?? "3.7.0" });
3020
3064
  } catch (error) {
3021
3065
  throw new Error(`service ${name}: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
3022
3066
  }
@@ -3336,6 +3380,7 @@ var httpChild = async (target, entry, options, admission, generation, privateAcc
3336
3380
  options.onLog?.(entry2);
3337
3381
  },
3338
3382
  ...entry.adminControls !== void 0 ? { adminControls: entry.adminControls } : {},
3383
+ ...entry.settings !== void 0 ? { settings: checkSettings(target, entry.settings, "settings") } : {},
3339
3384
  ...entry.fixtures !== void 0 ? { fixtures: entry.fixtures } : {},
3340
3385
  ...(advertisedHttpBase(entry) ?? entry.baseUrl) !== void 0 ? { baseUrl: advertisedHttpBase(entry) ?? entry.baseUrl } : {}
3341
3386
  });
@@ -3354,6 +3399,8 @@ var httpChild = async (target, entry, options, admission, generation, privateAcc
3354
3399
  ].some((method) => typeof created[method] !== "function"))
3355
3400
  throw new Error("HTTP target does not implement the fleet runtime protocol; build/install matching supported service versions");
3356
3401
  const runtime = created;
3402
+ if (entry.idBase !== void 0)
3403
+ runtime.setIdBase?.(entry.idBase);
3357
3404
  const unobserve = runtime.webhooks?.observeDeliveries(observer.delivery);
3358
3405
  if (options.outbound && runtime.webhooks)
3359
3406
  runtime.webhooks.setTransportPolicy(ownedTransport(options.outbound));
@@ -3952,6 +3999,7 @@ async function startFleet(config, options) {
3952
3999
  ...entry,
3953
4000
  adminPrefix: resolveAdminPrefix(entry.adminPrefix ?? adminPrefix),
3954
4001
  ...adminKey !== void 0 ? { adminKey } : {},
4002
+ ...(entry.idBase ?? config.idBase) !== void 0 ? { idBase: entry.idBase ?? config.idBase } : {},
3955
4003
  // Fleet-wide controls, with the service's own keys replacing them.
3956
4004
  ...config.adminControls !== void 0 || entry.adminControls !== void 0 ? { adminControls: { ...config.adminControls, ...entry.adminControls } } : {}
3957
4005
  }, options, (namespace, request) => management?.admit(namespace, request), (namespace) => management?.generation(namespace), (namespace, request) => management?.privateRequest(namespace, request) ?? false, {
@@ -4636,6 +4684,16 @@ var COMMON_SERVE_OPTIONS = {
4636
4684
  value: "<seed>",
4637
4685
  description: "Seed for every random choice (env MOCKINGBIRD_SEED)"
4638
4686
  },
4687
+ "id-base": {
4688
+ type: "string",
4689
+ value: "<n|boot>",
4690
+ 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)"
4691
+ },
4692
+ settings: {
4693
+ type: "string",
4694
+ value: "<json|file>",
4695
+ 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)"
4696
+ },
4639
4697
  "admin-controls": {
4640
4698
  type: "string",
4641
4699
  value: "<json|file>",
@@ -4730,19 +4788,40 @@ var readJsonFile = async (path, label) => {
4730
4788
  }
4731
4789
  };
4732
4790
  var isObject2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
4791
+ var readJsonOption = async (source, label) => {
4792
+ const trimmed = source.trim();
4793
+ if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
4794
+ try {
4795
+ return JSON.parse(trimmed);
4796
+ } catch {
4797
+ throw new Error(`${label}: not valid JSON`);
4798
+ }
4799
+ }
4800
+ return readJsonFile(source, label);
4801
+ };
4802
+ var resolveServeIdBase = (values, env = process.env) => {
4803
+ const source = asString(values["id-base"]) ?? env.MOCKINGBIRD_ID_BASE;
4804
+ if (source === void 0 || source.trim() === "")
4805
+ return void 0;
4806
+ normalizeIdBase(source.trim(), "--id-base");
4807
+ return source.trim();
4808
+ };
4809
+ var resolveServeSettings = async (target, values, env = process.env) => {
4810
+ const flag = asString(values.settings);
4811
+ const source = flag ?? env.MOCKINGBIRD_SETTINGS;
4812
+ if (source === void 0 || source.trim() === "")
4813
+ return void 0;
4814
+ const label = flag !== void 0 ? "--settings" : "MOCKINGBIRD_SETTINGS";
4815
+ const parsed = await readJsonOption(source, label);
4816
+ if (!isObject2(parsed))
4817
+ throw new Error(`${label}: expected a JSON object`);
4818
+ return checkSettings(target, parsed, label);
4819
+ };
4733
4820
  var resolveServeControls = async (values, env = process.env, base) => {
4734
4821
  const source = asString(values["admin-controls"]) ?? env.MOCKINGBIRD_ADMIN_CONTROLS;
4735
4822
  let document = isObject2(base) ? { ...base } : {};
4736
4823
  if (source !== void 0 && source.trim() !== "") {
4737
- let parsed;
4738
- if (source.trim().startsWith("{")) {
4739
- try {
4740
- parsed = JSON.parse(source);
4741
- } catch {
4742
- throw new Error("--admin-controls: not valid JSON");
4743
- }
4744
- } else
4745
- parsed = await readJsonFile(source, "--admin-controls");
4824
+ const parsed = source.trim().startsWith("{") ? await readJsonOption(source, "--admin-controls") : await readJsonFile(source, "--admin-controls");
4746
4825
  if (!isObject2(parsed))
4747
4826
  throw new Error("--admin-controls: expected a JSON object");
4748
4827
  document = { ...document, ...parsed };
@@ -4792,8 +4871,11 @@ var start = async (target, values, config) => {
4792
4871
  adminKey: config.adminKey,
4793
4872
  seed: config.seed,
4794
4873
  onLog: formatLog(config.log),
4874
+ ...config.settings !== void 0 ? { settings: config.settings } : {},
4795
4875
  ...config.adminControls !== void 0 ? { adminControls: config.adminControls } : {}
4796
4876
  });
4877
+ if (config.idBase !== void 0)
4878
+ runtime.setIdBase?.(config.idBase);
4797
4879
  const listening = await listen(runtime, { port: config.port, host: config.host });
4798
4880
  target.listening?.(listening);
4799
4881
  console.log(`${target.name} emulator listening on ${listening.url}`);
@@ -4839,6 +4921,11 @@ var serveCommand = (target) => ({
4839
4921
  const adminControls = await resolveServeControls(values, process.env, config.adminControls);
4840
4922
  if (adminControls !== void 0)
4841
4923
  config.adminControls = adminControls;
4924
+ if (values.settings !== void 0)
4925
+ throw new Error("--settings serves a single service; give each service its own `settings` in the config");
4926
+ const idBase = config.idBase ?? resolveServeIdBase(values);
4927
+ if (idBase !== void 0)
4928
+ config.idBase = idBase;
4842
4929
  const fleet = await startFleet(config, {
4843
4930
  load: (name) => loadTarget(name, target),
4844
4931
  onLog: formatLog(config.log ?? log),
@@ -4868,8 +4955,12 @@ var serveCommand = (target) => ({
4868
4955
  let listening;
4869
4956
  try {
4870
4957
  const adminControls = await resolveServeControls(values);
4958
+ const idBase = resolveServeIdBase(values);
4959
+ const settings = await resolveServeSettings(target, values);
4871
4960
  listening = await start(target, values, {
4872
4961
  ...adminControls !== void 0 ? { adminControls } : {},
4962
+ ...idBase !== void 0 ? { idBase } : {},
4963
+ ...settings !== void 0 ? { settings } : {},
4873
4964
  adminPrefix: resolveAdminPrefix(asString(values["admin-prefix"]) ?? process.env.MOCKINGBIRD_ADMIN_PREFIX),
4874
4965
  port: port === void 0 ? target.defaultPort : Number.parseInt(port, 10),
4875
4966
  host: asString(values.host) ?? "127.0.0.1",
@@ -4932,4 +5023,4 @@ export {
4932
5023
  createServer2 as createServer,
4933
5024
  serveTarget
4934
5025
  };
4935
- //# sourceMappingURL=chunk-EUNZBLLX.js.map
5026
+ //# sourceMappingURL=chunk-T2FKJBGI.js.map