@wix/himalaya-cli 0.966.0 → 0.968.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.
@@ -4,6 +4,14 @@ export * from "./wix-gateway.rules.js";
4
4
  export interface WixGatewayState {
5
5
  mode: WixGatewayMode;
6
6
  rules: WixMockRule[];
7
+ /** An OPERATOR replaced the rules or the mode through `/__dev/{wix,net}/*`.
8
+ *
9
+ * Read by the date-rollover re-seed (net-mocks-rollover.ts), which must not
10
+ * regenerate what a person pushed: seeding from the app's scenario reassigns
11
+ * `rules` wholesale AND forces `mode` back to the declared one, so an operator
12
+ * watching real traffic in `record` mode would have both silently reverted at
13
+ * midnight with only a "re-seeded N rule(s)" line on stderr. */
14
+ operatorOverride?: boolean;
7
15
  traffic: WixTrafficEvent[];
8
16
  clients: Set<ServerResponse>;
9
17
  seq: number;
package/dist/cli.mjs CHANGED
@@ -5261,6 +5261,7 @@ function resolveTranslation(value, catalog, sourceCatalog) {
5261
5261
  var BINDING_SIGILS, BINDING_SIGIL_RE, TRANSLATION_PREFIX, TRANSLATION_KEY_RE;
5262
5262
  var init_bindings = __esm({
5263
5263
  "../../core/ts/src/bindings.ts"() {
5264
+ "use strict";
5264
5265
  BINDING_SIGILS = ["service", "flag", "item", "t"];
5265
5266
  BINDING_SIGIL_RE = new RegExp(
5266
5267
  `^\\$(?:${BINDING_SIGILS.filter((s) => s !== "t").join("|")})\\b|^\\$t:`
@@ -15336,7 +15337,10 @@ data: ${JSON.stringify({ mode: gw.mode })}
15336
15337
  if (suffix === "mode" && method === "POST") {
15337
15338
  try {
15338
15339
  const { mode } = JSON.parse(await readBody(req));
15339
- if (mode === "record" || mode === "mock") gw.mode = mode;
15340
+ if (mode === "record" || mode === "mock") {
15341
+ gw.mode = mode;
15342
+ gw.operatorOverride = true;
15343
+ }
15340
15344
  } catch {
15341
15345
  }
15342
15346
  return json(res, 200, { ok: true, mode: gw.mode }), true;
@@ -15348,6 +15352,7 @@ data: ${JSON.stringify({ mode: gw.mode })}
15348
15352
  try {
15349
15353
  const { rules } = JSON.parse(await readBody(req));
15350
15354
  gw.rules = Array.isArray(rules) ? rules.map((r) => ({ ...r, id: r.id || ++gw.ruleSeq })) : [];
15355
+ gw.operatorOverride = true;
15351
15356
  } catch {
15352
15357
  return json(res, 400, { error: "invalid_json" }), true;
15353
15358
  }
@@ -17041,6 +17046,59 @@ var init_tier4_verifier = __esm({
17041
17046
  }
17042
17047
  });
17043
17048
 
17049
+ // ../../core/dev-server/src/net-mocks-rollover.ts
17050
+ function todayYmd(now = /* @__PURE__ */ new Date()) {
17051
+ const utc = now.toISOString().slice(0, 10);
17052
+ let local = utc;
17053
+ try {
17054
+ const parts = new Intl.DateTimeFormat("en-CA", { year: "numeric", month: "2-digit", day: "2-digit" }).formatToParts(now);
17055
+ const get = (t) => parts.find((x) => x.type === t)?.value ?? "";
17056
+ const assembled = `${get("year")}-${get("month")}-${get("day")}`;
17057
+ if (/^\d{4}-\d{2}-\d{2}$/.test(assembled)) local = assembled;
17058
+ } catch {
17059
+ }
17060
+ return local > utc ? local : utc;
17061
+ }
17062
+ async function reseedIfDayChanged(host, today = todayYmd()) {
17063
+ if (!host.seededFromApp) return { reseeded: false, reason: "not-from-app" };
17064
+ if (host.wix.operatorOverride) return { reseeded: false, reason: "operator-override" };
17065
+ const from = host.seededOn;
17066
+ if (!from || from === today) return { reseeded: false, reason: "same-day" };
17067
+ const reload = await host.reloadAppModule("net-mocks date rollover");
17068
+ if (!reload.ok) return { reseeded: false, reason: "reload-failed" };
17069
+ if (host.wix.operatorOverride) return { reseeded: false, reason: "operator-override" };
17070
+ const declared = host.declaredRules();
17071
+ if (!declared?.rules?.length) {
17072
+ const before = { mode: host.wix.mode, rules: [...host.wix.rules] };
17073
+ host.seed({ mode: declared ? declared.mode : "record", rules: [] });
17074
+ if (scenarioChanged(before, { mode: host.wix.mode, rules: host.wix.rules })) {
17075
+ host.publishConfigInvalidated("net-mocks scenario removed");
17076
+ }
17077
+ host.seededOn = today;
17078
+ return { reseeded: false, reason: "no-rules" };
17079
+ }
17080
+ host.seed({ mode: declared.mode, rules: declared.rules });
17081
+ host.seededOn = today;
17082
+ host.publishConfigInvalidated("net-mocks date rollover");
17083
+ return { reseeded: true, rules: declared.rules.length, from, to: today };
17084
+ }
17085
+ function scenarioChanged(before, after) {
17086
+ if (before.mode !== after.mode) return true;
17087
+ if (before.rules.length !== after.rules.length) return true;
17088
+ return serialise(before.rules) !== serialise(after.rules);
17089
+ }
17090
+ function serialise(rules) {
17091
+ return JSON.stringify(rules.map((r) => {
17092
+ if (!r || typeof r !== "object") return r;
17093
+ const { id: _id, ...rest } = r;
17094
+ return rest;
17095
+ }));
17096
+ }
17097
+ var init_net_mocks_rollover = __esm({
17098
+ "../../core/dev-server/src/net-mocks-rollover.ts"() {
17099
+ }
17100
+ });
17101
+
17044
17102
  // ../../core/dev-server/src/player-proxy.ts
17045
17103
  function isPlayerHost(appName) {
17046
17104
  return appName === PLAYER_APP_ID || process.env.HIMALAYA_DEV_MULTI_APP === "1";
@@ -30891,7 +30949,66 @@ function applyTopBarDefault(descriptor, config) {
30891
30949
  if (!fallback || own2) return descriptor;
30892
30950
  return { ...descriptor, topBar: fallback };
30893
30951
  }
30894
- async function reloadAppModule(state, opts) {
30952
+ function syncNetMocksWithApp(state) {
30953
+ if (!state.wixSeededFromApp || state.wix.operatorOverride) return;
30954
+ const declared = state.app?.meta.devGateway;
30955
+ const next = declared?.rules ?? [];
30956
+ const before = { mode: state.wix.mode, rules: state.wix.rules };
30957
+ const beforeSnapshot = { mode: before.mode, rules: JSON.parse(JSON.stringify(before.rules)) };
30958
+ applyNetMocks(state.wix, { mode: declared?.mode, rules: next });
30959
+ state.wixSeededOn = todayYmd();
30960
+ state.wixReseedBackoffUntil = 0;
30961
+ if (scenarioChanged(beforeSnapshot, { mode: state.wix.mode, rules: state.wix.rules })) {
30962
+ publishSSE(state, "config.invalidated", { reason: "net-mocks scenario changed", at: Date.now() });
30963
+ console.error(`[himalaya-dev] net-mocks: re-synced ${next.length} rule(s) after an app reload`);
30964
+ }
30965
+ }
30966
+ async function maybeReseedNetMocks(state) {
30967
+ if (state.wixReseedInFlight) return state.wixReseedInFlight;
30968
+ if (!state.wixSeededFromApp || !state.wixSeededOn || state.wixSeededOn === todayYmd()) return;
30969
+ if (Date.now() < (state.wixReseedBackoffUntil ?? 0)) return;
30970
+ const run2 = reseedNetMocksNow(state).finally(() => {
30971
+ state.wixReseedInFlight = void 0;
30972
+ });
30973
+ state.wixReseedInFlight = run2;
30974
+ return run2;
30975
+ }
30976
+ async function reseedNetMocksNow(state) {
30977
+ const outcome = await reseedIfDayChanged({
30978
+ wix: state.wix,
30979
+ declaredRules: () => state.app?.meta.devGateway,
30980
+ reloadAppModule: (reason) => reloadAppModule(state, { reason }),
30981
+ seed: (mocks) => {
30982
+ applyNetMocks(state.wix, mocks);
30983
+ },
30984
+ publishConfigInvalidated: (reason) => publishSSE(state, "config.invalidated", { reason, at: Date.now() }),
30985
+ get seededOn() {
30986
+ return state.wixSeededOn;
30987
+ },
30988
+ set seededOn(day) {
30989
+ state.wixSeededOn = day;
30990
+ },
30991
+ seededFromApp: state.wixSeededFromApp
30992
+ });
30993
+ if (outcome.reseeded) {
30994
+ console.error(`[himalaya-dev] net-mocks: re-seeded ${outcome.rules} rule(s) \u2014 the date turned (${outcome.from} \u2192 ${outcome.to})`);
30995
+ return;
30996
+ }
30997
+ if (outcome.reason === "reload-failed" || outcome.reason === "no-rules") {
30998
+ state.wixReseedBackoffUntil = Date.now() + 6e4;
30999
+ console.error(outcome.reason === "reload-failed" ? "[himalaya-dev] net-mocks: the date turned but the app module would not reload \u2014 keeping yesterday's rules, retrying in a minute" : "[himalaya-dev] net-mocks: the date turned and the app now declares no scenario \u2014 cleared the stale rules, re-checking in a minute");
31000
+ }
31001
+ }
31002
+ function reloadAppModule(state, opts) {
31003
+ const run2 = appReloadChain.then(
31004
+ () => reloadAppModuleNow(state, opts),
31005
+ () => reloadAppModuleNow(state, opts)
31006
+ // a previous failure must not block the queue
31007
+ );
31008
+ appReloadChain = run2.catch(() => void 0);
31009
+ return run2;
31010
+ }
31011
+ async function reloadAppModuleNow(state, opts) {
30895
31012
  const current = state.app;
30896
31013
  if (!current) return { ok: false, error: "no_app" };
30897
31014
  const entry = resolve30(current.dir, "dev/index.ts");
@@ -30913,6 +31030,7 @@ async function reloadAppModule(state, opts) {
30913
31030
  meta: deriveAppMeta(current.name, next, readPlatformsJson(current.dir)),
30914
31031
  dir: current.dir
30915
31032
  };
31033
+ syncNetMocksWithApp(state);
30916
31034
  if (opts.recreateStore) {
30917
31035
  try {
30918
31036
  state.moduleStore?.close?.();
@@ -32351,12 +32469,16 @@ function createDevServer(opts = {}) {
32351
32469
  );
32352
32470
  if (resolved2) {
32353
32471
  const seeded = applyNetMocks(state.wix, resolved2.mocks);
32472
+ state.wixSeededOn = todayYmd();
32473
+ state.wixSeededFromApp = resolved2.source !== "file";
32354
32474
  const from = resolved2.source === "file" ? netMocksPath : `${state.appName} devGateway.rules`;
32355
32475
  console.error(`[himalaya-dev] net-mocks: seeded ${seeded.rules} rule(s), mode=${seeded.mode} from ${from}`);
32356
32476
  }
32357
32477
  const appScenario = state.app?.meta.devGateway;
32358
32478
  if (!netMocksDisabled && appScenario?.rules?.length && state.wix.rules.length === 0) {
32359
32479
  const seeded = applyNetMocks(state.wix, { mode: appScenario.mode, rules: appScenario.rules });
32480
+ state.wixSeededOn = todayYmd();
32481
+ state.wixSeededFromApp = true;
32360
32482
  console.error(`[himalaya-dev] net-mocks: seeded ${seeded.rules} rule(s), mode=${seeded.mode} from the app's devGateway scenario`);
32361
32483
  }
32362
32484
  if (state.hotReloadEnabled) {
@@ -32388,6 +32510,7 @@ function createDevServer(opts = {}) {
32388
32510
  if (req.method === "HEAD") req.method = "GET";
32389
32511
  void (async () => {
32390
32512
  try {
32513
+ await maybeReseedNetMocks(state);
32391
32514
  if (url.startsWith("/__dev/")) return await handleDev(req, res, state);
32392
32515
  if (url.split("?")[0] === "/v1/app-icon" && req.method === "GET") {
32393
32516
  const iconApp = new URLSearchParams(url.split("?")[1] ?? "").get("app") ?? "";
@@ -32752,7 +32875,7 @@ ${err.message}`);
32752
32875
  });
32753
32876
  return httpServer;
32754
32877
  }
32755
- var ROOT6, TIER3_ROOT, TIER4_ROOT, tier4Verifier, TIER5_ROOT2, ACTION_HANDLERS_ROOT, SAMPLES_ROOT, TELEMETRY_BUFFER_CAP, overrideHistorySeq, CACHE_CONTROL, TIER5_SRC_ROOT, HMR_TMP_DIR, appReloadSeq, WEBWIX_CLIENT_ID, WEBWIX_REDIRECT, WEBWIX_COOKIE, webOwnerPreviewInstances, MIME, widgetOverrides;
32878
+ var ROOT6, TIER3_ROOT, TIER4_ROOT, tier4Verifier, TIER5_ROOT2, ACTION_HANDLERS_ROOT, SAMPLES_ROOT, TELEMETRY_BUFFER_CAP, overrideHistorySeq, CACHE_CONTROL, TIER5_SRC_ROOT, HMR_TMP_DIR, appReloadSeq, appReloadChain, WEBWIX_CLIENT_ID, WEBWIX_REDIRECT, WEBWIX_COOKIE, webOwnerPreviewInstances, MIME, widgetOverrides;
32756
32879
  var init_src6 = __esm({
32757
32880
  "../../core/dev-server/src/index.ts"() {
32758
32881
  init_inject();
@@ -32772,6 +32895,7 @@ var init_src6 = __esm({
32772
32895
  init_preview();
32773
32896
  init_tier4_verifier();
32774
32897
  init_loader();
32898
+ init_net_mocks_rollover();
32775
32899
  init_tier5_dir();
32776
32900
  init_contained_dev_module();
32777
32901
  init_player_proxy();
@@ -32802,6 +32926,7 @@ var init_src6 = __esm({
32802
32926
  TIER5_SRC_ROOT = resolve30(ROOT6, "core/dev-server/tier5-bundles-src");
32803
32927
  HMR_TMP_DIR = resolve30(ROOT6, "node_modules/.cache/himalaya-hmr");
32804
32928
  appReloadSeq = 0;
32929
+ appReloadChain = Promise.resolve();
32805
32930
  WEBWIX_CLIENT_ID = process.env.DEMO_APP_WIX_CLIENT_ID ?? "4f58d461-c1f5-4a5d-a467-62cc2329e4dd";
32806
32931
  WEBWIX_REDIRECT = "himalaya-demo-app://oauth/callback";
32807
32932
  WEBWIX_COOKIE = "himi_webwix_session";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wix/himalaya-cli",
3
- "version": "0.966.0",
3
+ "version": "0.968.0",
4
4
  "type": "module",
5
5
  "description": "himi — the Himalaya authoring CLI. Build a Tier-5 content package on your own machine, push it to the production serve as a draft, preview it on web + Himi Player, and read worker logs back — the remote dev loop. Wraps @himalaya/serve-cli for transport.",
6
6
  "keywords": [
@@ -64,5 +64,5 @@
64
64
  "artifactId": "himalaya-cli"
65
65
  }
66
66
  },
67
- "falconPackageHash": "c12a59fbdcd27a2233673aa22facc9ca266f627e049c8c4ece035da8"
67
+ "falconPackageHash": "e41cecd4c127159c9493293586554a07f307be67bc66163cb13683c0"
68
68
  }