@wix/himalaya-cli 0.966.0 → 0.967.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";
@@ -18546,7 +18604,6 @@ function shouldRevealError(args) {
18546
18604
  var EMAIL_RE, URL_HOST_RE, INTEGER_RE, NUMBER_RE;
18547
18605
  var init_validation = __esm({
18548
18606
  "../../core/ts/src/validation.ts"() {
18549
- "use strict";
18550
18607
  EMAIL_RE = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*\.[A-Za-z]{2,}$/;
18551
18608
  URL_HOST_RE = /^[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*(:[0-9]+)?$/;
18552
18609
  INTEGER_RE = /^[+-]?[0-9]+$/;
@@ -21971,7 +22028,6 @@ function validateWorkerSubtree(raw, slotId, policy, actionCatalog) {
21971
22028
  var WORKER_SUBTREE_CEILINGS, ID_PART, ACTION_ID;
21972
22029
  var init_worker_subtree = __esm({
21973
22030
  "../../core/ts/src/worker-subtree.ts"() {
21974
- "use strict";
21975
22031
  init_worker_subtree_safe_types_generated();
21976
22032
  WORKER_SUBTREE_CEILINGS = Object.freeze({
21977
22033
  maxEncodedBytes: 65536,
@@ -30891,7 +30947,66 @@ function applyTopBarDefault(descriptor, config) {
30891
30947
  if (!fallback || own2) return descriptor;
30892
30948
  return { ...descriptor, topBar: fallback };
30893
30949
  }
30894
- async function reloadAppModule(state, opts) {
30950
+ function syncNetMocksWithApp(state) {
30951
+ if (!state.wixSeededFromApp || state.wix.operatorOverride) return;
30952
+ const declared = state.app?.meta.devGateway;
30953
+ const next = declared?.rules ?? [];
30954
+ const before = { mode: state.wix.mode, rules: state.wix.rules };
30955
+ const beforeSnapshot = { mode: before.mode, rules: JSON.parse(JSON.stringify(before.rules)) };
30956
+ applyNetMocks(state.wix, { mode: declared?.mode, rules: next });
30957
+ state.wixSeededOn = todayYmd();
30958
+ state.wixReseedBackoffUntil = 0;
30959
+ if (scenarioChanged(beforeSnapshot, { mode: state.wix.mode, rules: state.wix.rules })) {
30960
+ publishSSE(state, "config.invalidated", { reason: "net-mocks scenario changed", at: Date.now() });
30961
+ console.error(`[himalaya-dev] net-mocks: re-synced ${next.length} rule(s) after an app reload`);
30962
+ }
30963
+ }
30964
+ async function maybeReseedNetMocks(state) {
30965
+ if (state.wixReseedInFlight) return state.wixReseedInFlight;
30966
+ if (!state.wixSeededFromApp || !state.wixSeededOn || state.wixSeededOn === todayYmd()) return;
30967
+ if (Date.now() < (state.wixReseedBackoffUntil ?? 0)) return;
30968
+ const run2 = reseedNetMocksNow(state).finally(() => {
30969
+ state.wixReseedInFlight = void 0;
30970
+ });
30971
+ state.wixReseedInFlight = run2;
30972
+ return run2;
30973
+ }
30974
+ async function reseedNetMocksNow(state) {
30975
+ const outcome = await reseedIfDayChanged({
30976
+ wix: state.wix,
30977
+ declaredRules: () => state.app?.meta.devGateway,
30978
+ reloadAppModule: (reason) => reloadAppModule(state, { reason }),
30979
+ seed: (mocks) => {
30980
+ applyNetMocks(state.wix, mocks);
30981
+ },
30982
+ publishConfigInvalidated: (reason) => publishSSE(state, "config.invalidated", { reason, at: Date.now() }),
30983
+ get seededOn() {
30984
+ return state.wixSeededOn;
30985
+ },
30986
+ set seededOn(day) {
30987
+ state.wixSeededOn = day;
30988
+ },
30989
+ seededFromApp: state.wixSeededFromApp
30990
+ });
30991
+ if (outcome.reseeded) {
30992
+ console.error(`[himalaya-dev] net-mocks: re-seeded ${outcome.rules} rule(s) \u2014 the date turned (${outcome.from} \u2192 ${outcome.to})`);
30993
+ return;
30994
+ }
30995
+ if (outcome.reason === "reload-failed" || outcome.reason === "no-rules") {
30996
+ state.wixReseedBackoffUntil = Date.now() + 6e4;
30997
+ 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");
30998
+ }
30999
+ }
31000
+ function reloadAppModule(state, opts) {
31001
+ const run2 = appReloadChain.then(
31002
+ () => reloadAppModuleNow(state, opts),
31003
+ () => reloadAppModuleNow(state, opts)
31004
+ // a previous failure must not block the queue
31005
+ );
31006
+ appReloadChain = run2.catch(() => void 0);
31007
+ return run2;
31008
+ }
31009
+ async function reloadAppModuleNow(state, opts) {
30895
31010
  const current = state.app;
30896
31011
  if (!current) return { ok: false, error: "no_app" };
30897
31012
  const entry = resolve30(current.dir, "dev/index.ts");
@@ -30913,6 +31028,7 @@ async function reloadAppModule(state, opts) {
30913
31028
  meta: deriveAppMeta(current.name, next, readPlatformsJson(current.dir)),
30914
31029
  dir: current.dir
30915
31030
  };
31031
+ syncNetMocksWithApp(state);
30916
31032
  if (opts.recreateStore) {
30917
31033
  try {
30918
31034
  state.moduleStore?.close?.();
@@ -32351,12 +32467,16 @@ function createDevServer(opts = {}) {
32351
32467
  );
32352
32468
  if (resolved2) {
32353
32469
  const seeded = applyNetMocks(state.wix, resolved2.mocks);
32470
+ state.wixSeededOn = todayYmd();
32471
+ state.wixSeededFromApp = resolved2.source !== "file";
32354
32472
  const from = resolved2.source === "file" ? netMocksPath : `${state.appName} devGateway.rules`;
32355
32473
  console.error(`[himalaya-dev] net-mocks: seeded ${seeded.rules} rule(s), mode=${seeded.mode} from ${from}`);
32356
32474
  }
32357
32475
  const appScenario = state.app?.meta.devGateway;
32358
32476
  if (!netMocksDisabled && appScenario?.rules?.length && state.wix.rules.length === 0) {
32359
32477
  const seeded = applyNetMocks(state.wix, { mode: appScenario.mode, rules: appScenario.rules });
32478
+ state.wixSeededOn = todayYmd();
32479
+ state.wixSeededFromApp = true;
32360
32480
  console.error(`[himalaya-dev] net-mocks: seeded ${seeded.rules} rule(s), mode=${seeded.mode} from the app's devGateway scenario`);
32361
32481
  }
32362
32482
  if (state.hotReloadEnabled) {
@@ -32388,6 +32508,7 @@ function createDevServer(opts = {}) {
32388
32508
  if (req.method === "HEAD") req.method = "GET";
32389
32509
  void (async () => {
32390
32510
  try {
32511
+ await maybeReseedNetMocks(state);
32391
32512
  if (url.startsWith("/__dev/")) return await handleDev(req, res, state);
32392
32513
  if (url.split("?")[0] === "/v1/app-icon" && req.method === "GET") {
32393
32514
  const iconApp = new URLSearchParams(url.split("?")[1] ?? "").get("app") ?? "";
@@ -32752,7 +32873,7 @@ ${err.message}`);
32752
32873
  });
32753
32874
  return httpServer;
32754
32875
  }
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;
32876
+ 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
32877
  var init_src6 = __esm({
32757
32878
  "../../core/dev-server/src/index.ts"() {
32758
32879
  init_inject();
@@ -32772,6 +32893,7 @@ var init_src6 = __esm({
32772
32893
  init_preview();
32773
32894
  init_tier4_verifier();
32774
32895
  init_loader();
32896
+ init_net_mocks_rollover();
32775
32897
  init_tier5_dir();
32776
32898
  init_contained_dev_module();
32777
32899
  init_player_proxy();
@@ -32802,6 +32924,7 @@ var init_src6 = __esm({
32802
32924
  TIER5_SRC_ROOT = resolve30(ROOT6, "core/dev-server/tier5-bundles-src");
32803
32925
  HMR_TMP_DIR = resolve30(ROOT6, "node_modules/.cache/himalaya-hmr");
32804
32926
  appReloadSeq = 0;
32927
+ appReloadChain = Promise.resolve();
32805
32928
  WEBWIX_CLIENT_ID = process.env.DEMO_APP_WIX_CLIENT_ID ?? "4f58d461-c1f5-4a5d-a467-62cc2329e4dd";
32806
32929
  WEBWIX_REDIRECT = "himalaya-demo-app://oauth/callback";
32807
32930
  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.967.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": "21a64fc457cad496774edeab407735299722e76708687a0a3a6dcaaf"
68
68
  }