@wix/himalaya-cli 0.1555.0 → 0.1556.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.mjs CHANGED
@@ -8780,8 +8780,8 @@ function tsExtResolvePlugin() {
8780
8780
  setup(b2) {
8781
8781
  b2.onResolve({ filter: /\.js$/ }, (args) => {
8782
8782
  if (args.kind === "entry-point" || !args.path.startsWith(".")) return void 0;
8783
- const ts13 = resolve8(args.resolveDir, args.path.replace(/\.js$/, ".ts"));
8784
- return existsSync9(ts13) ? { path: ts13 } : void 0;
8783
+ const ts14 = resolve8(args.resolveDir, args.path.replace(/\.js$/, ".ts"));
8784
+ return existsSync9(ts14) ? { path: ts14 } : void 0;
8785
8785
  });
8786
8786
  }
8787
8787
  };
@@ -9536,7 +9536,7 @@ function bundleFor(file2) {
9536
9536
  const match = /^tier5-src\/([^/]+)\//.exec(file2);
9537
9537
  return match?.[1] ?? "_shared";
9538
9538
  }
9539
- function toIssue(ts13, contentDir2, diagnostic) {
9539
+ function toIssue(ts14, contentDir2, diagnostic) {
9540
9540
  const file2 = diagnostic.file ? relativeFile(contentDir2, diagnostic.file.fileName) : void 0;
9541
9541
  const position = diagnostic.file && diagnostic.start !== void 0 ? diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start) : void 0;
9542
9542
  return {
@@ -9544,13 +9544,13 @@ function toIssue(ts13, contentDir2, diagnostic) {
9544
9544
  ...file2 ? { file: file2 } : {},
9545
9545
  ...position ? { line: position.line + 1, column: position.character + 1 } : {},
9546
9546
  code: `TS${diagnostic.code}`,
9547
- message: ts13.flattenDiagnosticMessageText(diagnostic.messageText, "\n")
9547
+ message: ts14.flattenDiagnosticMessageText(diagnostic.messageText, "\n")
9548
9548
  };
9549
9549
  }
9550
- function confinedHost(ts13, contentDir2, options) {
9550
+ function confinedHost(ts14, contentDir2, options) {
9551
9551
  if (!buildConfinementRequired()) return void 0;
9552
- const host = ts13.createCompilerHost(options);
9553
- const libDir = resolve10(ts13.getDefaultLibFilePath(options), "..");
9552
+ const host = ts14.createCompilerHost(options);
9553
+ const libDir = resolve10(ts14.getDefaultLibFilePath(options), "..");
9554
9554
  const allows = confinementMatcher(contentDir2, [libDir]);
9555
9555
  const getSourceFile = host.getSourceFile.bind(host);
9556
9556
  const readFile3 = host.readFile.bind(host);
@@ -9579,7 +9579,7 @@ function confinedHost(ts13, contentDir2, options) {
9579
9579
  }
9580
9580
  async function typecheckContentWorkers(contentDir2, options) {
9581
9581
  if (!existsSync10(resolve10(contentDir2, "tier5-src"))) return [];
9582
- const ts13 = await compiler2();
9582
+ const ts14 = await compiler2();
9583
9583
  const config = {
9584
9584
  compilerOptions: {
9585
9585
  ...CONTENT_WORKER_COMPILER_OPTIONS,
@@ -9588,18 +9588,18 @@ async function typecheckContentWorkers(contentDir2, options) {
9588
9588
  // The deployed authoring runtime stages TypeScript 6, which requires an explicit
9589
9589
  // acknowledgement for this compatibility `baseUrl`; the repository's TypeScript 5 lane
9590
9590
  // rejects that 6.0 value, so keep it specific to the compiler that needs it.
9591
- ...Number.parseInt(ts13.versionMajorMinor, 10) >= 6 ? { ignoreDeprecations: "6.0" } : {}
9591
+ ...Number.parseInt(ts14.versionMajorMinor, 10) >= 6 ? { ignoreDeprecations: "6.0" } : {}
9592
9592
  },
9593
9593
  include: ["tier5-src/*/index.ts", "tier5-src/_shared/**/*.ts"]
9594
9594
  };
9595
- const parsed = ts13.parseJsonConfigFileContent(config, ts13.sys, contentDir2);
9595
+ const parsed = ts14.parseJsonConfigFileContent(config, ts14.sys, contentDir2);
9596
9596
  if (parsed.fileNames.length === 0) return [];
9597
- const program = ts13.createProgram({
9597
+ const program = ts14.createProgram({
9598
9598
  rootNames: parsed.fileNames,
9599
9599
  options: parsed.options,
9600
- host: confinedHost(ts13, contentDir2, parsed.options)
9600
+ host: confinedHost(ts14, contentDir2, parsed.options)
9601
9601
  });
9602
- return [...parsed.errors, ...ts13.getPreEmitDiagnostics(program)].filter((diagnostic) => diagnostic.category === ts13.DiagnosticCategory.Error && belongsToContentWorkers(contentDir2, diagnostic)).map((diagnostic) => toIssue(ts13, contentDir2, diagnostic));
9602
+ return [...parsed.errors, ...ts14.getPreEmitDiagnostics(program)].filter((diagnostic) => diagnostic.category === ts14.DiagnosticCategory.Error && belongsToContentWorkers(contentDir2, diagnostic)).map((diagnostic) => toIssue(ts14, contentDir2, diagnostic));
9603
9603
  }
9604
9604
  var compilerPromise;
9605
9605
  var init_tier5_typecheck = __esm({
@@ -18623,18 +18623,18 @@ var init_pixels = __esm({
18623
18623
  });
18624
18624
 
18625
18625
  // ../../core/dev-server/src/declared-navigation-ast.ts
18626
- function literalTargets(bundleJs, ts13) {
18627
- const name = (n2) => n2 && (ts13.isIdentifier(n2) || ts13.isStringLiteral(n2) || ts13.isNoSubstitutionTemplateLiteral(n2)) ? n2.text : void 0;
18626
+ function literalTargets(bundleJs, ts14) {
18627
+ const name = (n2) => n2 && (ts14.isIdentifier(n2) || ts14.isStringLiteral(n2) || ts14.isNoSubstitutionTemplateLiteral(n2)) ? n2.text : void 0;
18628
18628
  const object10 = (n2) => {
18629
- while (n2 && ts13.isParenthesizedExpression(n2)) n2 = n2.expression;
18630
- return n2 && ts13.isObjectLiteralExpression(n2) ? n2 : void 0;
18629
+ while (n2 && ts14.isParenthesizedExpression(n2)) n2 = n2.expression;
18630
+ return n2 && ts14.isObjectLiteralExpression(n2) ? n2 : void 0;
18631
18631
  };
18632
18632
  const property2 = (o2, key3) => o2?.properties.find((p2) => name(p2.name) === key3);
18633
- const initializer = (p2) => p2 && ts13.isPropertyAssignment(p2) ? p2.initializer : void 0;
18634
- const callable = (n2) => !!n2 && (ts13.isArrowFunction(n2) || ts13.isFunctionExpression(n2) || ts13.isFunctionDeclaration(n2) || ts13.isMethodDeclaration(n2));
18633
+ const initializer = (p2) => p2 && ts14.isPropertyAssignment(p2) ? p2.initializer : void 0;
18634
+ const callable = (n2) => !!n2 && (ts14.isArrowFunction(n2) || ts14.isFunctionExpression(n2) || ts14.isFunctionDeclaration(n2) || ts14.isMethodDeclaration(n2));
18635
18635
  const cached3 = cache.get(bundleJs);
18636
18636
  if (cached3) return cached3;
18637
- const file2 = ts13.createSourceFile("himi-bundle.js", bundleJs, ts13.ScriptTarget.Latest, true, ts13.ScriptKind.JS);
18637
+ const file2 = ts14.createSourceFile("himi-bundle.js", bundleJs, ts14.ScriptTarget.Latest, true, ts14.ScriptKind.JS);
18638
18638
  const symbols = /* @__PURE__ */ new Map();
18639
18639
  const note = (key3, fn2) => {
18640
18640
  if (!key3) return;
@@ -18642,15 +18642,15 @@ function literalTargets(bundleJs, ts13) {
18642
18642
  symbols.set(key3, { count: (prior?.count ?? 0) + 1, fn: fn2 });
18643
18643
  };
18644
18644
  const declarations = (node) => {
18645
- if (ts13.isFunctionDeclaration(node)) note(name(node.name), node);
18646
- else if (ts13.isVariableDeclaration(node)) note(name(node.name), callable(node.initializer) ? node.initializer : void 0);
18647
- else if (ts13.isParameter(node)) note(name(node.name));
18648
- ts13.forEachChild(node, declarations);
18645
+ if (ts14.isFunctionDeclaration(node)) note(name(node.name), node);
18646
+ else if (ts14.isVariableDeclaration(node)) note(name(node.name), callable(node.initializer) ? node.initializer : void 0);
18647
+ else if (ts14.isParameter(node)) note(name(node.name));
18648
+ ts14.forEachChild(node, declarations);
18649
18649
  };
18650
18650
  declarations(file2);
18651
18651
  const resolve87 = (node) => {
18652
18652
  if (callable(node)) return node;
18653
- if (node && ts13.isIdentifier(node)) {
18653
+ if (node && ts14.isIdentifier(node)) {
18654
18654
  const symbol = symbols.get(node.text);
18655
18655
  if (symbol?.count === 1) return symbol.fn;
18656
18656
  }
@@ -18658,47 +18658,47 @@ function literalTargets(bundleJs, ts13) {
18658
18658
  };
18659
18659
  const results = /* @__PURE__ */ new Map();
18660
18660
  const visit = (node) => {
18661
- if (ts13.isCallExpression(node)) {
18662
- const callee = ts13.isPropertyAccessExpression(node.expression) ? node.expression.name.text : name(node.expression);
18661
+ if (ts14.isCallExpression(node)) {
18662
+ const callee = ts14.isPropertyAccessExpression(node.expression) ? node.expression.name.text : name(node.expression);
18663
18663
  const service = node.arguments[0];
18664
- if (callee && /^defineService[0-9]*$/.test(callee) && service && ts13.isStringLiteralLike(service)) {
18664
+ if (callee && /^defineService[0-9]*$/.test(callee) && service && ts14.isStringLiteralLike(service)) {
18665
18665
  const actions = object10(initializer(property2(object10(node.arguments[1]), "actions")));
18666
18666
  for (const member of actions?.properties ?? []) {
18667
18667
  const action = name(member.name);
18668
- const fn2 = ts13.isMethodDeclaration(member) ? member : resolve87(ts13.isShorthandPropertyAssignment(member) ? member.name : initializer(member));
18668
+ const fn2 = ts14.isMethodDeclaration(member) ? member : resolve87(ts14.isShorthandPropertyAssignment(member) ? member.name : initializer(member));
18669
18669
  if (!action || !fn2?.body) continue;
18670
18670
  const targets = [];
18671
18671
  const target = (expr) => {
18672
18672
  const sid = initializer(property2(object10(expr), "screenId"));
18673
- if (!sid || !ts13.isStringLiteralLike(sid)) return;
18673
+ if (!sid || !ts14.isStringLiteralLike(sid)) return;
18674
18674
  const position = file2.getLineAndCharacterOfPosition(sid.getStart(file2));
18675
18675
  targets.push({ screenId: sid.text, line: position.line + 1, column: position.character });
18676
18676
  };
18677
18677
  const returned = (expr) => {
18678
18678
  if (!expr) return;
18679
- if (ts13.isParenthesizedExpression(expr) || ts13.isAwaitExpression(expr)) {
18679
+ if (ts14.isParenthesizedExpression(expr) || ts14.isAwaitExpression(expr)) {
18680
18680
  returned(expr.expression);
18681
18681
  return;
18682
18682
  }
18683
- if (ts13.isConditionalExpression(expr)) {
18683
+ if (ts14.isConditionalExpression(expr)) {
18684
18684
  returned(expr.whenTrue);
18685
18685
  returned(expr.whenFalse);
18686
18686
  return;
18687
18687
  }
18688
- if (ts13.isObjectLiteralExpression(expr)) {
18688
+ if (ts14.isObjectLiteralExpression(expr)) {
18689
18689
  target(initializer(property2(expr, "_nav")));
18690
18690
  return;
18691
18691
  }
18692
- if (ts13.isCallExpression(expr)) {
18693
- const called = ts13.isPropertyAccessExpression(expr.expression) ? expr.expression.name.text : name(expr.expression);
18692
+ if (ts14.isCallExpression(expr)) {
18693
+ const called = ts14.isPropertyAccessExpression(expr.expression) ? expr.expression.name.text : name(expr.expression);
18694
18694
  if (called && /^navigate[0-9]*$/.test(called)) target(expr.arguments[1]);
18695
18695
  }
18696
18696
  };
18697
- if (ts13.isBlock(fn2.body)) {
18697
+ if (ts14.isBlock(fn2.body)) {
18698
18698
  const returns = (part3) => {
18699
18699
  if (callable(part3)) return;
18700
- if (ts13.isReturnStatement(part3)) returned(part3.expression);
18701
- else ts13.forEachChild(part3, returns);
18700
+ if (ts14.isReturnStatement(part3)) returned(part3.expression);
18701
+ else ts14.forEachChild(part3, returns);
18702
18702
  };
18703
18703
  returns(fn2.body);
18704
18704
  } else returned(fn2.body);
@@ -18706,7 +18706,7 @@ function literalTargets(bundleJs, ts13) {
18706
18706
  }
18707
18707
  }
18708
18708
  }
18709
- ts13.forEachChild(node, visit);
18709
+ ts14.forEachChild(node, visit);
18710
18710
  };
18711
18711
  visit(file2);
18712
18712
  cache.set(bundleJs, results);
@@ -23888,7 +23888,6 @@ function resolveIdiom(tokens2, ctx = {}) {
23888
23888
  var IDIOM_CONTEXTS, UNSAFE_KEYS;
23889
23889
  var init_idiom = __esm({
23890
23890
  "../../core/ts/src/idiom.ts"() {
23891
- "use strict";
23892
23891
  IDIOM_CONTEXTS = {
23893
23892
  ios: { native: ["ios"] },
23894
23893
  android: { native: ["material"] },
@@ -140619,9 +140618,9 @@ function stateOf(view) {
140619
140618
  build: b2 && view.live ? { ok: b2.ok, ms: b2.ms, screens: b2.screens, at: b2.at, run: view.live.runId } : null
140620
140619
  };
140621
140620
  }
140622
- function frameFor(state, prev, ts13, v2, key3) {
140623
- if (key3 || !prev) return { ts: ts13, v: v2, key: true, ...state };
140624
- const f2 = { ts: ts13, v: v2 };
140621
+ function frameFor(state, prev, ts14, v2, key3) {
140622
+ if (key3 || !prev) return { ts: ts14, v: v2, key: true, ...state };
140623
+ const f2 = { ts: ts14, v: v2 };
140625
140624
  if (!same2(state.step, prev.step)) f2.step = state.step;
140626
140625
  if (!same2(state.now, prev.now)) f2.now = state.now;
140627
140626
  const screens = {};
@@ -150027,6 +150026,7 @@ __export(template_trim_exports, {
150027
150026
  });
150028
150027
  import { cpSync, existsSync as existsSync43, mkdirSync as mkdirSync23, readdirSync as readdirSync23, readFileSync as readFileSync48, renameSync as renameSync9, rmSync as rmSync13, statSync as statSync12, writeFileSync as writeFileSync17 } from "node:fs";
150029
150028
  import { dirname as dirname28, join as join36 } from "node:path";
150029
+ import ts5 from "typescript";
150030
150030
  function routeMatcher(pattern) {
150031
150031
  const detail = /^\^([A-Za-z0-9_]+)\(\?:\[_\/\]\(\.\+\)\)\?\$$/.exec(pattern);
150032
150032
  if (detail) {
@@ -150083,6 +150083,17 @@ function parseJson2(text12, what) {
150083
150083
  );
150084
150084
  }
150085
150085
  }
150086
+ function configWithoutComments(text12) {
150087
+ const scanner = ts5.createScanner(ts5.ScriptTarget.Latest, false, ts5.LanguageVariant.Standard, text12);
150088
+ const parts = [];
150089
+ let end = 0;
150090
+ for (let token = scanner.scan(); token !== ts5.SyntaxKind.EndOfFileToken; token = scanner.scan()) {
150091
+ if (token !== ts5.SyntaxKind.SingleLineCommentTrivia && token !== ts5.SyntaxKind.MultiLineCommentTrivia) continue;
150092
+ parts.push(text12.slice(end, scanner.getTokenPos()), text12.slice(scanner.getTokenPos(), scanner.getTextPos()).replace(/[^\r\n]/g, " "));
150093
+ end = scanner.getTextPos();
150094
+ }
150095
+ return parts.join("") + text12.slice(end);
150096
+ }
150086
150097
  function jsonString(literal, what) {
150087
150098
  try {
150088
150099
  return JSON.parse(literal);
@@ -150199,14 +150210,15 @@ function parseApp(dev, config) {
150199
150210
  const homeId = jsonString(hm[1], "dev/index.ts: homeScreenId");
150200
150211
  const home = exact.get(homeId);
150201
150212
  if (!home) throw new TrimRefusal(`dev/index.ts: homeScreenId "${homeId}" is not a screen in the SCREENS map`);
150213
+ const configData = configWithoutComments(config);
150202
150214
  const NAV_ANCHOR = "\n navigation: {";
150203
- const nAt = config.indexOf(NAV_ANCHOR);
150215
+ const nAt = configData.indexOf(NAV_ANCHOR);
150204
150216
  if (nAt < 0) throw new TrimRefusal("config.ts has no `navigation: {` \u2014 trim rewrites navigation in the shape `himi init` writes");
150205
150217
  const nOpen = nAt + NAV_ANCHOR.length - 1;
150206
- const nClose = objectEnd(config, nOpen);
150218
+ const nClose = objectEnd(configData, nOpen);
150207
150219
  if (nClose < 0) throw new TrimRefusal("config.ts: the navigation object never closes");
150208
- const navValue2 = parseJson2(config.slice(nOpen, nClose), "config.ts navigation");
150209
- const subtree = parseSubtree(config);
150220
+ const navValue2 = parseJson2(configData.slice(nOpen, nClose), "config.ts navigation");
150221
+ const subtree = parseSubtree(configData);
150210
150222
  return { dev, config, home, routes, exact, templated, templatedRegion, nav: { open: nOpen, close: nClose, value: navValue2 }, subtree };
150211
150223
  }
150212
150224
  function resolveIn(app, id) {
@@ -151799,14 +151811,14 @@ var init_hosted_owner = __esm({
151799
151811
  // src/config-source-edit.ts
151800
151812
  import { lstatSync as lstatSync13 } from "node:fs";
151801
151813
  import { join as join38 } from "node:path";
151802
- import ts5 from "typescript";
151814
+ import ts6 from "typescript";
151803
151815
  function defineAppLiteral(file2) {
151804
151816
  for (const statement of file2.statements) {
151805
- if (!ts5.isExportAssignment(statement)) continue;
151817
+ if (!ts6.isExportAssignment(statement)) continue;
151806
151818
  const exported = localValue(file2, unwrap(statement.expression));
151807
- if (ts5.isObjectLiteralExpression(exported)) return exported;
151808
- const [first] = ts5.isCallExpression(exported) ? exported.arguments : [];
151809
- return first && ts5.isObjectLiteralExpression(unwrap(first)) ? unwrap(first) : void 0;
151819
+ if (ts6.isObjectLiteralExpression(exported)) return exported;
151820
+ const [first] = ts6.isCallExpression(exported) ? exported.arguments : [];
151821
+ return first && ts6.isObjectLiteralExpression(unwrap(first)) ? unwrap(first) : void 0;
151810
151822
  }
151811
151823
  return void 0;
151812
151824
  }
@@ -151814,27 +151826,27 @@ function loginOf(app) {
151814
151826
  const auth = lookup3(app, "auth");
151815
151827
  if (auth.kind !== "written") return { kind: auth.kind === "absent" ? "other" : "opaque" };
151816
151828
  const value2 = unwrap(auth.node.initializer);
151817
- if (ts5.isObjectLiteralExpression(value2)) return { kind: "other" };
151818
- if (!ts5.isCallExpression(value2)) return { kind: "opaque" };
151829
+ if (ts6.isObjectLiteralExpression(value2)) return { kind: "other" };
151830
+ if (!ts6.isCallExpression(value2)) return { kind: "opaque" };
151819
151831
  const provider = calleeName(value2);
151820
151832
  if (provider === "WixOwnerAuthProvider" || provider === "WixAuthProvider") return { kind: "owner" };
151821
151833
  if (provider === "WixNativeAuthProvider") return nativeMode(value2) === "owner" ? { kind: "owner" } : { kind: "other" };
151822
151834
  if (provider !== "WixConsumerAuthProvider") return { kind: "other" };
151823
151835
  const [first] = value2.arguments;
151824
- return first && ts5.isObjectLiteralExpression(first) ? { kind: "member", literal: first } : { kind: "opaque" };
151836
+ return first && ts6.isObjectLiteralExpression(first) ? { kind: "member", literal: first } : { kind: "opaque" };
151825
151837
  }
151826
151838
  function nativeMode(call) {
151827
151839
  const [first] = call.arguments;
151828
- return first && ts5.isObjectLiteralExpression(first) ? stringValue(first, "mode") : void 0;
151840
+ return first && ts6.isObjectLiteralExpression(first) ? stringValue(first, "mode") : void 0;
151829
151841
  }
151830
151842
  function calleeName(call) {
151831
151843
  const callee = call.expression;
151832
- if (ts5.isIdentifier(callee)) return callee.text;
151833
- return ts5.isPropertyAccessExpression(callee) ? callee.name.text : void 0;
151844
+ if (ts6.isIdentifier(callee)) return callee.text;
151845
+ return ts6.isPropertyAccessExpression(callee) ? callee.name.text : void 0;
151834
151846
  }
151835
151847
  function unwrap(node) {
151836
151848
  let current = node;
151837
- while (ts5.isParenthesizedExpression(current) || ts5.isAsExpression(current) || ts5.isSatisfiesExpression(current)) {
151849
+ while (ts6.isParenthesizedExpression(current) || ts6.isAsExpression(current) || ts6.isSatisfiesExpression(current)) {
151838
151850
  current = current.expression;
151839
151851
  }
151840
151852
  return current;
@@ -151842,17 +151854,17 @@ function unwrap(node) {
151842
151854
  function lookup3(literal, name) {
151843
151855
  let found = { kind: "absent" };
151844
151856
  for (const p2 of literal.properties) {
151845
- const key3 = p2.name && (ts5.isIdentifier(p2.name) || ts5.isStringLiteral(p2.name)) ? p2.name.text : void 0;
151846
- if (ts5.isPropertyAssignment(p2) && key3 === name) found = { kind: "written", node: p2 };
151847
- else if (ts5.isSpreadAssignment(p2) || p2.name && ts5.isComputedPropertyName(p2.name) || key3 === name) found = { kind: "opaque" };
151857
+ const key3 = p2.name && (ts6.isIdentifier(p2.name) || ts6.isStringLiteral(p2.name)) ? p2.name.text : void 0;
151858
+ if (ts6.isPropertyAssignment(p2) && key3 === name) found = { kind: "written", node: p2 };
151859
+ else if (ts6.isSpreadAssignment(p2) || p2.name && ts6.isComputedPropertyName(p2.name) || key3 === name) found = { kind: "opaque" };
151848
151860
  }
151849
151861
  return found;
151850
151862
  }
151851
151863
  function stringValue(node, name) {
151852
151864
  const literal = unwrap(node);
151853
- const found = ts5.isObjectLiteralExpression(literal) ? lookup3(literal, name) : void 0;
151865
+ const found = ts6.isObjectLiteralExpression(literal) ? lookup3(literal, name) : void 0;
151854
151866
  const value2 = found?.kind === "written" ? found.node.initializer : void 0;
151855
- return value2 && ts5.isStringLiteralLike(value2) ? value2.text : void 0;
151867
+ return value2 && ts6.isStringLiteralLike(value2) ? value2.text : void 0;
151856
151868
  }
151857
151869
  function appendProperties(literal, file2, lines) {
151858
151870
  const inline = () => lines.filter((line) => !line.trimStart().startsWith("//")).join(" ");
@@ -151884,11 +151896,11 @@ function applySplices(source, splices) {
151884
151896
  return [...splices].sort((a2, b2) => b2.at - a2.at).reduce((out2, s2) => out2.slice(0, s2.at) + s2.text + out2.slice(s2.end), source);
151885
151897
  }
151886
151898
  function localValue(file2, node) {
151887
- if (!ts5.isIdentifier(node)) return node;
151899
+ if (!ts6.isIdentifier(node)) return node;
151888
151900
  for (const statement of file2.statements) {
151889
- if (!ts5.isVariableStatement(statement) || !(statement.declarationList.flags & ts5.NodeFlags.Const)) continue;
151901
+ if (!ts6.isVariableStatement(statement) || !(statement.declarationList.flags & ts6.NodeFlags.Const)) continue;
151890
151902
  for (const declaration of statement.declarationList.declarations) {
151891
- if (ts5.isIdentifier(declaration.name) && declaration.name.text === node.text && declaration.initializer) return unwrap(declaration.initializer);
151903
+ if (ts6.isIdentifier(declaration.name) && declaration.name.text === node.text && declaration.initializer) return unwrap(declaration.initializer);
151892
151904
  }
151893
151905
  }
151894
151906
  return node;
@@ -151936,12 +151948,12 @@ __export(config_push_edit_exports, {
151936
151948
  });
151937
151949
  import { readFileSync as readFileSync50 } from "node:fs";
151938
151950
  import { basename as basename13 } from "node:path";
151939
- import ts6 from "typescript";
151951
+ import ts7 from "typescript";
151940
151952
  function enablePushInConfig(source, options) {
151941
151953
  const pingAppName = DEFAULT_PING_APP_NAME;
151942
151954
  const fileName = options.fileName ?? "config.ts";
151943
- const kind = fileName.endsWith(".ts") ? ts6.ScriptKind.TS : ts6.ScriptKind.JS;
151944
- const file2 = ts6.createSourceFile(fileName, source, ts6.ScriptTarget.Latest, true, kind);
151955
+ const kind = fileName.endsWith(".ts") ? ts7.ScriptKind.TS : ts7.ScriptKind.JS;
151956
+ const file2 = ts7.createSourceFile(fileName, source, ts7.ScriptTarget.Latest, true, kind);
151945
151957
  const app = defineAppLiteral(file2);
151946
151958
  const named = (instruction) => instruction.replaceAll("config.ts", fileName);
151947
151959
  const unchanged = (instruction) => ({ source, changed: false, applied: [], instructions: [named(instruction)], pushOn: false });
@@ -151993,9 +152005,9 @@ function planPush(app, pingAppName, plan) {
151993
152005
  }
151994
152006
  function planRetiredFamily(block, plan) {
151995
152007
  const literal = unwrap(block);
151996
- const found = ts6.isObjectLiteralExpression(literal) ? lookup3(literal, "pingAppName") : void 0;
152008
+ const found = ts7.isObjectLiteralExpression(literal) ? lookup3(literal, "pingAppName") : void 0;
151997
152009
  const value2 = found?.kind === "written" ? unwrap(found.node.initializer) : void 0;
151998
- const replacement = value2 && ts6.isStringLiteralLike(value2) ? replacementPingFamily(value2.text) : void 0;
152010
+ const replacement = value2 && ts7.isStringLiteralLike(value2) ? replacementPingFamily(value2.text) : void 0;
151999
152011
  if (!value2 || !replacement) return;
152000
152012
  plan.splices.push({ at: value2.getStart(), end: value2.end, text: JSON.stringify(replacement) });
152001
152013
  plan.applied.push(`pingAppName ${JSON.stringify(replacement)} in place of ${value2.getText()}`);
@@ -152008,11 +152020,11 @@ function planCapability(app, plan) {
152008
152020
  return;
152009
152021
  }
152010
152022
  const list2 = capabilities.kind === "written" ? unwrap(capabilities.node.initializer) : void 0;
152011
- if (!list2 || !ts6.isArrayLiteralExpression(list2)) {
152023
+ if (!list2 || !ts7.isArrayLiteralExpression(list2)) {
152012
152024
  plan.instructions.push('Add "push" to capabilities: Wix push needs the push capability, and config.ts does not list it inline.');
152013
152025
  return;
152014
152026
  }
152015
- if (list2.elements.some((e2) => ts6.isStringLiteralLike(e2) && e2.text === "push")) return;
152027
+ if (list2.elements.some((e2) => ts7.isStringLiteralLike(e2) && e2.text === "push")) return;
152016
152028
  const last = list2.elements[list2.elements.length - 1];
152017
152029
  plan.splices.push(last ? { at: last.end, end: last.end, text: ', "push"' } : { at: list2.getStart(), end: list2.end, text: '["push"]' });
152018
152030
  plan.applied.push("push capability");
@@ -152040,7 +152052,7 @@ function planAuthSite(login, file2, site, plan) {
152040
152052
  const current = siteId.kind === "written" ? unwrap(siteId.node.initializer) : void 0;
152041
152053
  if (!current) {
152042
152054
  plan.instructions.push(`auth may get its siteId from elsewhere, so none was added. Wix push needs ${wanted}.`);
152043
- } else if (!ts6.isStringLiteralLike(current)) {
152055
+ } else if (!ts7.isStringLiteralLike(current)) {
152044
152056
  plan.instructions.push(`auth's siteId is computed, so it was not checked: make sure it evaluates to ${JSON.stringify(site)}.`);
152045
152057
  } else if (current.text !== site) {
152046
152058
  plan.instructions.push(
@@ -153538,15 +153550,15 @@ function loadMemory2(dir) {
153538
153550
  for (const t2 of m2.timeline) {
153539
153551
  if (!isObj3(t2)) continue;
153540
153552
  const file2 = historyName(t2.sha, t2.ext);
153541
- const ts13 = str5(t2.ts);
153553
+ const ts14 = str5(t2.ts);
153542
153554
  const id = str5(t2.id);
153543
- if (file2 && ts13 && id) timeline.push({ ts: ts13, id, file: file2 });
153555
+ if (file2 && ts14 && id) timeline.push({ ts: ts14, id, file: file2 });
153544
153556
  }
153545
153557
  return { createdAt: str5(m2.createdAt), shots, timeline };
153546
153558
  }
153547
- function captionAt(entries, ts13) {
153559
+ function captionAt(entries, ts14) {
153548
153560
  let best = null;
153549
- for (const e2 of entries) if (e2.ts <= ts13) best = e2;
153561
+ for (const e2 of entries) if (e2.ts <= ts14) best = e2;
153550
153562
  return best ? best.message : null;
153551
153563
  }
153552
153564
  function thin(items, max) {
@@ -153666,13 +153678,13 @@ function duration(ms2) {
153666
153678
  const m2 = Math.round(ms2 / 6e4);
153667
153679
  return m2 < 60 ? `${m2} min` : `${Math.floor(m2 / 60)} h ${m2 % 60} min`;
153668
153680
  }
153669
- function utcDay(ts13) {
153670
- const d2 = new Date(ts13);
153681
+ function utcDay(ts14) {
153682
+ const d2 = new Date(ts14);
153671
153683
  return Number.isNaN(d2.getTime()) ? "" : `${d2.toUTCString().slice(0, 16)} (UTC)`;
153672
153684
  }
153673
- function sinceStart(start, ts13) {
153685
+ function sinceStart(start, ts14) {
153674
153686
  if (!start) return "";
153675
- const s2 = Math.max(0, Math.round((Date.parse(ts13) - Date.parse(start)) / 1e3));
153687
+ const s2 = Math.max(0, Math.round((Date.parse(ts14) - Date.parse(start)) / 1e3));
153676
153688
  const h2 = Math.floor(s2 / 3600);
153677
153689
  const m2 = Math.floor(s2 % 3600 / 60);
153678
153690
  const sec = String(s2 % 60).padStart(2, "0");
@@ -153682,7 +153694,7 @@ function renderReel(plan, images) {
153682
153694
  const img = (f2, alt, cls = "") => f2 && images.has(f2) ? `<img class="${cls}" src="${images.get(f2)}" alt="${escapeHtml(alt)}">` : "";
153683
153695
  const count2 = (n2) => escapeHtml(String(Number.isSafeInteger(n2) && n2 >= 0 ? n2 : 0));
153684
153696
  const accent = ACCENT.test(plan.accent) ? plan.accent : DEFAULT_ACCENT;
153685
- const clock = (ts13) => sinceStart(plan.startedAt, ts13);
153697
+ const clock = (ts14) => sinceStart(plan.startedAt, ts14);
153686
153698
  const frames = plan.frames.filter((f2) => images.has(f2.file));
153687
153699
  const flip = frames.length ? `<section class="flip"><div class="phone">${frames.map((f2, i2) => `<img class="fr${i2 === 0 ? " on" : ""}" src="${images.get(f2.file)}" alt="${escapeHtml(plan.focusId ?? "")} at ${clock(f2.ts)}">`).join("")}</div>
153688
153700
  <div class="flipcap"><div class="t" id="ft">${frames[0] ? clock(frames[0].ts) : ""}</div><div id="fc">${escapeHtml(frames[0]?.caption ?? "")}</div><div class="bar"><div id="fb"></div></div></div></section>` : `<p class="muted">No screen versions were recorded \u2014 open the build board with <code>himi studio</code> before building to capture them.</p>`;
@@ -155029,19 +155041,19 @@ var init_brand_color_math = __esm({
155029
155041
  // src/token-lint.ts
155030
155042
  import { existsSync as existsSync51, readFileSync as readFileSync59 } from "node:fs";
155031
155043
  import { join as join48 } from "node:path";
155032
- import ts7 from "typescript";
155044
+ import ts8 from "typescript";
155033
155045
  function configuredTokensPath(dir) {
155034
155046
  for (const name of ["config.ts", "config.js", "himi.config.ts"]) {
155035
155047
  const f2 = join48(dir, name);
155036
155048
  if (!existsSync51(f2)) continue;
155037
155049
  const src = readFileSync59(f2, "utf8");
155038
- const app = defineAppLiteral(ts7.createSourceFile(f2, src, ts7.ScriptTarget.Latest, true));
155050
+ const app = defineAppLiteral(ts8.createSourceFile(f2, src, ts8.ScriptTarget.Latest, true));
155039
155051
  if (!app) return { computed: true };
155040
155052
  const field = lookup3(app, "designTokensPath");
155041
155053
  if (field.kind === "opaque") return { computed: true };
155042
155054
  if (field.kind === "written") {
155043
155055
  const value2 = unwrap(field.node.initializer);
155044
- return ts7.isStringLiteralLike(value2) && !ts7.isTemplateExpression(value2) ? { path: value2.text.replace(/^\.\//, "") } : { computed: true };
155056
+ return ts8.isStringLiteralLike(value2) && !ts8.isTemplateExpression(value2) ? { path: value2.text.replace(/^\.\//, "") } : { computed: true };
155045
155057
  }
155046
155058
  }
155047
155059
  return {};
@@ -155686,17 +155698,17 @@ __export(template_sweep_exports, {
155686
155698
  });
155687
155699
  import { readFileSync as readFileSync62, writeFileSync as writeFileSync22 } from "node:fs";
155688
155700
  import { join as join51 } from "node:path";
155689
- import ts8 from "typescript";
155701
+ import ts9 from "typescript";
155690
155702
  function isCopy(node, file2) {
155691
155703
  const parent = node.parent;
155692
- if (ts8.isPropertyAssignment(parent) && parent.name === node) return false;
155693
- if (ts8.isImportDeclaration(parent) || ts8.isExportDeclaration(parent) || ts8.isExternalModuleReference(parent)) return false;
155694
- if (ts8.isLiteralTypeNode(parent) || ts8.isImportTypeNode(parent)) return false;
155695
- if (ts8.isCallExpression(parent) && ts8.isIdentifier(parent.expression) && parent.expression.text === "require") return false;
155704
+ if (ts9.isPropertyAssignment(parent) && parent.name === node) return false;
155705
+ if (ts9.isImportDeclaration(parent) || ts9.isExportDeclaration(parent) || ts9.isExternalModuleReference(parent)) return false;
155706
+ if (ts9.isLiteralTypeNode(parent) || ts9.isImportTypeNode(parent)) return false;
155707
+ if (ts9.isCallExpression(parent) && ts9.isIdentifier(parent.expression) && parent.expression.text === "require") return false;
155696
155708
  const value2 = node.text;
155697
155709
  if (/\s/.test(value2) || PLACEHOLDER.test(value2)) return true;
155698
155710
  if (ID_LIKE.test(value2)) return false;
155699
- const key3 = ts8.isPropertyAssignment(parent) ? propName4(parent.name) : void 0;
155711
+ const key3 = ts9.isPropertyAssignment(parent) ? propName4(parent.name) : void 0;
155700
155712
  if (!key3) return false;
155701
155713
  return COPY_KEYS.has(key3) || key3 === "name" && file2 === "config.ts";
155702
155714
  }
@@ -155714,8 +155726,8 @@ function syntaxErrors(file2, text12) {
155714
155726
  return [e2.message];
155715
155727
  }
155716
155728
  }
155717
- const out2 = ts8.transpileModule(text12, { fileName: file2, reportDiagnostics: true, compilerOptions: { target: ts8.ScriptTarget.ES2022 } });
155718
- return (out2.diagnostics ?? []).map((d2) => ts8.flattenDiagnosticMessageText(d2.messageText, "\n"));
155729
+ const out2 = ts9.transpileModule(text12, { fileName: file2, reportDiagnostics: true, compilerOptions: { target: ts9.ScriptTarget.ES2022 } });
155730
+ return (out2.diagnostics ?? []).map((d2) => ts9.flattenDiagnosticMessageText(d2.messageText, "\n"));
155719
155731
  }
155720
155732
  function parses(dev, config) {
155721
155733
  try {
@@ -155737,11 +155749,11 @@ function sweepCopy(dir, pairs, dryRun) {
155737
155749
  for (const f2 of files) {
155738
155750
  const text12 = readFileSync62(join51(dir, f2), "utf8");
155739
155751
  if (!pairs.some(([from]) => text12.includes(from) || text12.includes(JSON.stringify(from).slice(1, -1)))) continue;
155740
- const kind = f2.endsWith(".json") ? ts8.ScriptKind.JSON : f2.endsWith("x") ? ts8.ScriptKind.TSX : ts8.ScriptKind.TS;
155741
- const sf2 = ts8.createSourceFile(f2, text12, ts8.ScriptTarget.Latest, true, kind);
155752
+ const kind = f2.endsWith(".json") ? ts9.ScriptKind.JSON : f2.endsWith("x") ? ts9.ScriptKind.TSX : ts9.ScriptKind.TS;
155753
+ const sf2 = ts9.createSourceFile(f2, text12, ts9.ScriptTarget.Latest, true, kind);
155742
155754
  const edits = [];
155743
155755
  const visit = (node) => {
155744
- if ((ts8.isStringLiteral(node) || ts8.isNoSubstitutionTemplateLiteral(node)) && isCopy(node, f2)) {
155756
+ if ((ts9.isStringLiteral(node) || ts9.isNoSubstitutionTemplateLiteral(node)) && isCopy(node, f2)) {
155745
155757
  let value2 = node.text;
155746
155758
  pairs.forEach(([from, to2], i2) => {
155747
155759
  const n2 = value2.split(from).length - 1;
@@ -155754,7 +155766,7 @@ function sweepCopy(dir, pairs, dryRun) {
155754
155766
  edits.push({ start, end: node.end, text: encode(value2, text12[start]) });
155755
155767
  }
155756
155768
  }
155757
- ts8.forEachChild(node, visit);
155769
+ ts9.forEachChild(node, visit);
155758
155770
  };
155759
155771
  visit(sf2);
155760
155772
  if (!edits.length) continue;
@@ -155833,7 +155845,7 @@ var init_template_sweep = __esm({
155833
155845
  "appName",
155834
155846
  "displayName"
155835
155847
  ]);
155836
- propName4 = (n2) => ts8.isIdentifier(n2) || ts8.isStringLiteral(n2) || ts8.isNoSubstitutionTemplateLiteral(n2) ? n2.text : void 0;
155848
+ propName4 = (n2) => ts9.isIdentifier(n2) || ts9.isStringLiteral(n2) || ts9.isNoSubstitutionTemplateLiteral(n2) ? n2.text : void 0;
155837
155849
  }
155838
155850
  });
155839
155851
 
@@ -167250,7 +167262,7 @@ __export(validate_topbar_exports, {
167250
167262
  import { createHash as createHash40 } from "node:crypto";
167251
167263
  import { existsSync as existsSync84, readFileSync as readFileSync94, statSync as statSync23 } from "node:fs";
167252
167264
  import { resolve as resolve68, join as join88 } from "node:path";
167253
- import ts9 from "typescript";
167265
+ import ts10 from "typescript";
167254
167266
  function enrichedControls(raw, views) {
167255
167267
  const result = /* @__PURE__ */ new Map();
167256
167268
  const graph = buildSourceGraph(raw, views);
@@ -167360,22 +167372,22 @@ function authoredControls(raw) {
167360
167372
  return { controls, byScreen, screens: count2 };
167361
167373
  }
167362
167374
  function property(node, name) {
167363
- const item = node?.properties.find((candidate) => ts9.isPropertyAssignment(candidate) && ((ts9.isIdentifier(candidate.name) || ts9.isStringLiteral(candidate.name)) && candidate.name.text === name));
167364
- return item && ts9.isPropertyAssignment(item) ? item.initializer : void 0;
167375
+ const item = node?.properties.find((candidate) => ts10.isPropertyAssignment(candidate) && ((ts10.isIdentifier(candidate.name) || ts10.isStringLiteral(candidate.name)) && candidate.name.text === name));
167376
+ return item && ts10.isPropertyAssignment(item) ? item.initializer : void 0;
167365
167377
  }
167366
167378
  function unwrap2(node) {
167367
- while (ts9.isParenthesizedExpression(node) || ts9.isAsExpression(node) || ts9.isSatisfiesExpression(node)) node = node.expression;
167379
+ while (ts10.isParenthesizedExpression(node) || ts10.isAsExpression(node) || ts10.isSatisfiesExpression(node)) node = node.expression;
167368
167380
  return node;
167369
167381
  }
167370
167382
  function resolveObject(node, source, seen = /* @__PURE__ */ new Set()) {
167371
167383
  if (!node) return void 0;
167372
167384
  const value2 = unwrap2(node);
167373
- if (ts9.isObjectLiteralExpression(value2)) return value2;
167374
- if (!ts9.isIdentifier(value2) || seen.has(value2.text)) return void 0;
167385
+ if (ts10.isObjectLiteralExpression(value2)) return value2;
167386
+ if (!ts10.isIdentifier(value2) || seen.has(value2.text)) return void 0;
167375
167387
  seen.add(value2.text);
167376
167388
  for (const statement of source.statements) {
167377
- if (!ts9.isVariableStatement(statement)) continue;
167378
- const declaration = statement.declarationList.declarations.find((item) => ts9.isIdentifier(item.name) && item.name.text === value2.text);
167389
+ if (!ts10.isVariableStatement(statement)) continue;
167390
+ const declaration = statement.declarationList.declarations.find((item) => ts10.isIdentifier(item.name) && item.name.text === value2.text);
167379
167391
  if (declaration?.initializer) return resolveObject(declaration.initializer, source, seen);
167380
167392
  }
167381
167393
  return void 0;
@@ -167384,21 +167396,21 @@ function resolveScreenObject(node, source) {
167384
167396
  const direct = resolveObject(node, source);
167385
167397
  if (direct) return direct;
167386
167398
  const value2 = unwrap2(node);
167387
- const name = ts9.isCallExpression(value2) && ts9.isIdentifier(value2.expression) ? value2.expression.text : ts9.isIdentifier(value2) ? value2.text : void 0;
167399
+ const name = ts10.isCallExpression(value2) && ts10.isIdentifier(value2.expression) ? value2.expression.text : ts10.isIdentifier(value2) ? value2.text : void 0;
167388
167400
  if (!name) return void 0;
167389
- const functionBody = source.statements.find((statement) => ts9.isFunctionDeclaration(statement) && statement.name?.text === name)?.body;
167390
- const variable = source.statements.filter(ts9.isVariableStatement).flatMap((statement) => [...statement.declarationList.declarations]).find((item) => ts9.isIdentifier(item.name) && item.name.text === name);
167401
+ const functionBody = source.statements.find((statement) => ts10.isFunctionDeclaration(statement) && statement.name?.text === name)?.body;
167402
+ const variable = source.statements.filter(ts10.isVariableStatement).flatMap((statement) => [...statement.declarationList.declarations]).find((item) => ts10.isIdentifier(item.name) && item.name.text === name);
167391
167403
  const initializer = variable?.initializer && unwrap2(variable.initializer);
167392
- const body = functionBody ?? (initializer && (ts9.isArrowFunction(initializer) || ts9.isFunctionExpression(initializer)) ? initializer.body : void 0);
167404
+ const body = functionBody ?? (initializer && (ts10.isArrowFunction(initializer) || ts10.isFunctionExpression(initializer)) ? initializer.body : void 0);
167393
167405
  if (!body) return void 0;
167394
- if (!ts9.isBlock(body)) return resolveObject(body, source);
167395
- const returns = body.statements.filter(ts9.isReturnStatement);
167406
+ if (!ts10.isBlock(body)) return resolveObject(body, source);
167407
+ const returns = body.statements.filter(ts10.isReturnStatement);
167396
167408
  return returns.length === 1 ? resolveObject(returns[0]?.expression, source) : void 0;
167397
167409
  }
167398
167410
  function stringValue2(node) {
167399
167411
  if (!node) return void 0;
167400
167412
  const value2 = unwrap2(node);
167401
- return ts9.isStringLiteralLike(value2) ? value2.text : void 0;
167413
+ return ts10.isStringLiteralLike(value2) ? value2.text : void 0;
167402
167414
  }
167403
167415
  function actionTokens(action) {
167404
167416
  const values = ["id", "icon", "label", "accessibilityLabel"].map((key3) => stringValue2(property(action, key3)) ?? "").join(" ").replace(/([a-z0-9])([A-Z])/g, "$1 $2").toLowerCase().match(/[a-z0-9]+/g) ?? [];
@@ -167415,12 +167427,12 @@ function parseActions(topBar, source) {
167415
167427
  if (!actionExpr) return { actions: [] };
167416
167428
  const actionsNode = unwrap2(actionExpr);
167417
167429
  let items;
167418
- if (ts9.isArrayLiteralExpression(actionsNode)) items = actionsNode.elements.filter(ts9.isExpression);
167419
- else if (ts9.isIdentifier(actionsNode)) {
167420
- const declaration = source.statements.filter(ts9.isVariableStatement).flatMap((statement) => [...statement.declarationList.declarations]).find((item) => ts9.isIdentifier(item.name) && item.name.text === actionsNode.text);
167430
+ if (ts10.isArrayLiteralExpression(actionsNode)) items = actionsNode.elements.filter(ts10.isExpression);
167431
+ else if (ts10.isIdentifier(actionsNode)) {
167432
+ const declaration = source.statements.filter(ts10.isVariableStatement).flatMap((statement) => [...statement.declarationList.declarations]).find((item) => ts10.isIdentifier(item.name) && item.name.text === actionsNode.text);
167421
167433
  const init = declaration?.initializer && unwrap2(declaration.initializer);
167422
- if (!init || !ts9.isArrayLiteralExpression(init)) return { actions: [], error: "Top-bar actions cannot be statically inspected." };
167423
- items = init.elements.filter(ts9.isExpression);
167434
+ if (!init || !ts10.isArrayLiteralExpression(init)) return { actions: [], error: "Top-bar actions cannot be statically inspected." };
167435
+ items = init.elements.filter(ts10.isExpression);
167424
167436
  } else return { actions: [], error: "Top-bar actions cannot be statically inspected." };
167425
167437
  const actions = [];
167426
167438
  for (const item of items) {
@@ -167431,23 +167443,23 @@ function parseActions(topBar, source) {
167431
167443
  return { actions };
167432
167444
  }
167433
167445
  function configActions(configPath) {
167434
- const source = ts9.createSourceFile(configPath, readFileSync94(configPath, "utf8"), ts9.ScriptTarget.Latest, true, ts9.ScriptKind.TS);
167446
+ const source = ts10.createSourceFile(configPath, readFileSync94(configPath, "utf8"), ts10.ScriptTarget.Latest, true, ts10.ScriptKind.TS);
167435
167447
  if (source.parseDiagnostics.length) return { actions: [], error: "config.ts could not be parsed." };
167436
- const exportAssignment = source.statements.find(ts9.isExportAssignment);
167448
+ const exportAssignment = source.statements.find(ts10.isExportAssignment);
167437
167449
  if (!exportAssignment) return { actions: [], error: "config.ts has no default app export." };
167438
167450
  let exported = unwrap2(exportAssignment.expression);
167439
- if (ts9.isIdentifier(exported)) {
167451
+ if (ts10.isIdentifier(exported)) {
167440
167452
  const exportedName = exported.text;
167441
167453
  for (const statement of source.statements) {
167442
- if (!ts9.isVariableStatement(statement)) continue;
167443
- const declaration = statement.declarationList.declarations.find((item) => ts9.isIdentifier(item.name) && item.name.text === exportedName);
167454
+ if (!ts10.isVariableStatement(statement)) continue;
167455
+ const declaration = statement.declarationList.declarations.find((item) => ts10.isIdentifier(item.name) && item.name.text === exportedName);
167444
167456
  if (declaration?.initializer) {
167445
167457
  exported = unwrap2(declaration.initializer);
167446
167458
  break;
167447
167459
  }
167448
167460
  }
167449
167461
  }
167450
- if (!ts9.isCallExpression(exported) || !exported.arguments[0]) return { actions: [], error: "config.ts does not default-export defineApp({...})." };
167462
+ if (!ts10.isCallExpression(exported) || !exported.arguments[0]) return { actions: [], error: "config.ts does not default-export defineApp({...})." };
167451
167463
  const app = resolveObject(exported.arguments[0], source);
167452
167464
  const navigation = resolveObject(property(app, "navigation"), source);
167453
167465
  const topBar = resolveObject(property(navigation, "topBarDefault"), source);
@@ -167458,13 +167470,13 @@ function configActions(configPath) {
167458
167470
  function screenActions2(contentDir2) {
167459
167471
  const path2 = join88(contentDir2, "dev", "index.ts");
167460
167472
  if (!existsSync84(path2)) return /* @__PURE__ */ new Map();
167461
- const source = ts9.createSourceFile(path2, readFileSync94(path2, "utf8"), ts9.ScriptTarget.Latest, true, ts9.ScriptKind.TS);
167473
+ const source = ts10.createSourceFile(path2, readFileSync94(path2, "utf8"), ts10.ScriptTarget.Latest, true, ts10.ScriptKind.TS);
167462
167474
  if (source.parseDiagnostics.length) throw Error("dev/index.ts could not be parsed.");
167463
- const declaration = source.statements.filter(ts9.isVariableStatement).flatMap((statement) => [...statement.declarationList.declarations]).find((item) => ts9.isIdentifier(item.name) && item.name.text === "SCREENS");
167475
+ const declaration = source.statements.filter(ts10.isVariableStatement).flatMap((statement) => [...statement.declarationList.declarations]).find((item) => ts10.isIdentifier(item.name) && item.name.text === "SCREENS");
167464
167476
  const initializer = declaration?.initializer && unwrap2(declaration.initializer);
167465
- let registry2 = initializer && ts9.isCallExpression(initializer) ? resolveObject(initializer.arguments[0], source) : resolveObject(initializer, source);
167477
+ let registry2 = initializer && ts10.isCallExpression(initializer) ? resolveObject(initializer.arguments[0], source) : resolveObject(initializer, source);
167466
167478
  if (!declaration) {
167467
- const exported = source.statements.find(ts9.isExportAssignment);
167479
+ const exported = source.statements.find(ts10.isExportAssignment);
167468
167480
  const module = resolveObject(exported?.expression, source);
167469
167481
  const screens = resolveObject(property(module, "screens"), source);
167470
167482
  registry2 = resolveObject(property(screens, "exact"), source);
@@ -167472,11 +167484,11 @@ function screenActions2(contentDir2) {
167472
167484
  if (!registry2) throw Error("dev/index.ts screen registry cannot be statically inspected.");
167473
167485
  const result = /* @__PURE__ */ new Map();
167474
167486
  for (const item of registry2.properties) {
167475
- if (!ts9.isPropertyAssignment(item) || !ts9.isIdentifier(item.name) && !ts9.isStringLiteral(item.name)) {
167487
+ if (!ts10.isPropertyAssignment(item) || !ts10.isIdentifier(item.name) && !ts10.isStringLiteral(item.name)) {
167476
167488
  throw Error("dev/index.ts screen registry contains entries that cannot be statically inspected.");
167477
167489
  }
167478
167490
  const screen = resolveScreenObject(item.initializer, source);
167479
- if (!screen || screen.properties.some(ts9.isSpreadAssignment)) {
167491
+ if (!screen || screen.properties.some(ts10.isSpreadAssignment)) {
167480
167492
  result.set(item.name.text, { actions: [], error: "ScreenDescriptor cannot be statically inspected." });
167481
167493
  continue;
167482
167494
  }
@@ -167638,7 +167650,7 @@ __export(validate_design_exports, {
167638
167650
  import { randomBytes as randomBytes5 } from "node:crypto";
167639
167651
  import { closeSync as closeSync7, constants as constants5, existsSync as existsSync85, lstatSync as lstatSync23, openSync as openSync6, readFileSync as readFileSync95, realpathSync as realpathSync12, renameSync as renameSync13, unlinkSync as unlinkSync5, writeFileSync as writeFileSync36 } from "node:fs";
167640
167652
  import { dirname as dirname47, isAbsolute as isAbsolute9, join as join89, relative as relative19, resolve as resolve69, sep as sep20, win32 } from "node:path";
167641
- import ts10 from "typescript";
167653
+ import ts11 from "typescript";
167642
167654
  function readColorToken(tokens2, name) {
167643
167655
  const entry = obj5(tokens2.colors)?.[name];
167644
167656
  if (typeof entry === "string") return { value: entry, origin: "token" };
@@ -167735,11 +167747,11 @@ function tokensLocation(contentDir2) {
167735
167747
  }
167736
167748
  function literalPolicyValue(expression) {
167737
167749
  const node = unwrap(expression);
167738
- if (ts10.isStringLiteralLike(node)) return node.text;
167739
- if (!ts10.isObjectLiteralExpression(node)) throw new Error("The app idiom policy is computed and cannot be checked.");
167750
+ if (ts11.isStringLiteralLike(node)) return node.text;
167751
+ if (!ts11.isObjectLiteralExpression(node)) throw new Error("The app idiom policy is computed and cannot be checked.");
167740
167752
  const value2 = {};
167741
167753
  for (const property2 of node.properties) {
167742
- if (!ts10.isPropertyAssignment(property2) || !property2.name || !ts10.isIdentifier(property2.name) && !ts10.isStringLiteral(property2.name)) {
167754
+ if (!ts11.isPropertyAssignment(property2) || !property2.name || !ts11.isIdentifier(property2.name) && !ts11.isStringLiteral(property2.name)) {
167743
167755
  throw new Error("The app idiom policy is computed and cannot be checked.");
167744
167756
  }
167745
167757
  value2[property2.name.text] = literalPolicyValue(property2.initializer);
@@ -167752,7 +167764,7 @@ function activeIdiomNames(contentDir2, tokens2) {
167752
167764
  for (const name of ["config.ts", "config.js", "himi.config.ts"]) {
167753
167765
  const file2 = join89(contentDir2, name);
167754
167766
  if (!existsSync85(file2)) continue;
167755
- const source = ts10.createSourceFile(file2, readFileSync95(file2, "utf8"), ts10.ScriptTarget.Latest, true);
167767
+ const source = ts11.createSourceFile(file2, readFileSync95(file2, "utf8"), ts11.ScriptTarget.Latest, true);
167756
167768
  const app = defineAppLiteral(source);
167757
167769
  if (!app) throw new Error("The app config cannot be inspected for active idiom overlays.");
167758
167770
  const field = lookup3(app, "idiom");
@@ -174952,11 +174964,11 @@ var init_store_spec = __esm({
174952
174964
  // src/iap-config-edit.ts
174953
174965
  import { existsSync as existsSync94, readFileSync as readFileSync109 } from "node:fs";
174954
174966
  import { basename as basename25, join as join97 } from "node:path";
174955
- import ts11 from "typescript";
174967
+ import ts12 from "typescript";
174956
174968
  function bindPurchasesAppInConfig(source, options) {
174957
174969
  const fileName = options.fileName ?? "config.ts";
174958
- const kind = fileName.endsWith(".ts") ? ts11.ScriptKind.TS : ts11.ScriptKind.JS;
174959
- const file2 = ts11.createSourceFile(fileName, source, ts11.ScriptTarget.Latest, true, kind);
174970
+ const kind = fileName.endsWith(".ts") ? ts12.ScriptKind.TS : ts12.ScriptKind.JS;
174971
+ const file2 = ts12.createSourceFile(fileName, source, ts12.ScriptTarget.Latest, true, kind);
174960
174972
  const wanted = `wixIap: { purchasesAppId: ${JSON.stringify(options.purchasesAppId)} }`;
174961
174973
  const unchanged = (result) => ({ source, changed: false, applied: [], conflicts: [], instructions: [], ...result });
174962
174974
  const app = defineAppLiteral(file2);
@@ -174984,7 +174996,7 @@ function siteFinding(app, siteId, fileName) {
174984
174996
  if (login.kind !== "member") return { instruction: `${fileName} does not write auth as a WixConsumerAuthProvider({ \u2026 }) call it can read, so ${check}` };
174985
174997
  const found = lookup3(login.literal, "siteId");
174986
174998
  const value2 = found.kind === "written" ? unwrap(found.node.initializer) : void 0;
174987
- if (!value2 || !ts11.isStringLiteralLike(value2)) return { instruction: `auth's siteId is not written as a literal, so ${check}` };
174999
+ if (!value2 || !ts12.isStringLiteralLike(value2)) return { instruction: `auth's siteId is not written as a literal, so ${check}` };
174988
175000
  if (value2.text.toLowerCase() === siteId.toLowerCase()) return {};
174989
175001
  return { conflict: `auth's siteId is "${value2.text}", but the purchases app is registered on site "${siteId}". A build bakes the binding only when they match, so ${fileName} was not edited.` };
174990
175002
  }
@@ -174995,7 +175007,7 @@ function bundleFinding(app, { bundleId, storeBundleId }, fileName) {
174995
175007
  }
174996
175008
  const found = lookup3(app, "bundleId");
174997
175009
  const value2 = found.kind === "written" ? unwrap(found.node.initializer) : void 0;
174998
- if (!value2 || !ts11.isStringLiteralLike(value2)) {
175010
+ if (!value2 || !ts12.isStringLiteralLike(value2)) {
174999
175011
  return { instruction: `${fileName} does not write bundleId as a literal: make sure this app builds bundle ${JSON.stringify(bundleId)}, the one the purchases app is registered for.` };
175000
175012
  }
175001
175013
  if (value2.text === bundleId || defaultProdBundleId(value2.text) === bundleId) return {};
@@ -175005,23 +175017,23 @@ function bindingFinding(app, file2, purchasesAppId, wanted, fileName) {
175005
175017
  const wixIap = lookup3(app, "wixIap");
175006
175018
  if (wixIap.kind === "absent") return { splice: appendProperties(app, file2, [`${wanted},`]), applied: "wixIap.purchasesAppId" };
175007
175019
  const literal = wixIap.kind === "written" ? unwrap(wixIap.node.initializer) : void 0;
175008
- if (!literal || !ts11.isObjectLiteralExpression(literal)) return { instruction: `${fileName} computes wixIap, so it was not edited: it must evaluate to ${wanted}.` };
175020
+ if (!literal || !ts12.isObjectLiteralExpression(literal)) return { instruction: `${fileName} computes wixIap, so it was not edited: it must evaluate to ${wanted}.` };
175009
175021
  const current = lookup3(literal, "purchasesAppId");
175010
175022
  if (current.kind === "absent") return { splice: appendProperties(literal, file2, [`purchasesAppId: ${JSON.stringify(purchasesAppId)},`]), applied: "wixIap.purchasesAppId" };
175011
175023
  const value2 = current.kind === "written" ? unwrap(current.node.initializer) : void 0;
175012
- if (!value2 || !ts11.isStringLiteralLike(value2)) return { instruction: `${fileName} computes wixIap.purchasesAppId, so it was not edited: it must evaluate to ${JSON.stringify(purchasesAppId)}.` };
175024
+ if (!value2 || !ts12.isStringLiteralLike(value2)) return { instruction: `${fileName} computes wixIap.purchasesAppId, so it was not edited: it must evaluate to ${JSON.stringify(purchasesAppId)}.` };
175013
175025
  if (value2.text === purchasesAppId) return {};
175014
175026
  return { conflict: `${fileName} already binds purchases app "${value2.text}", but this site's purchases app for the bundle is "${purchasesAppId}". Nothing was changed; fix whichever is stale.` };
175015
175027
  }
175016
175028
  function capabilityFinding(app, fileName) {
175017
175029
  const capabilities = lookup3(app, "capabilities");
175018
175030
  const list2 = capabilities.kind === "written" ? unwrap(capabilities.node.initializer) : void 0;
175019
- if (capabilities.kind !== "absent" && (!list2 || !ts11.isArrayLiteralExpression(list2))) {
175031
+ if (capabilities.kind !== "absent" && (!list2 || !ts12.isArrayLiteralExpression(list2))) {
175020
175032
  return { instruction: `Add "iap" to capabilities: the purchases app is baked only into a build that declares it, and ${fileName} does not list capabilities inline.` };
175021
175033
  }
175022
175034
  if (!list2) return { instruction: `Add capabilities: ["iap"] (with the app's other capabilities) to ${fileName}: the purchases app is baked only into a build that declares it.` };
175023
175035
  const elements = list2.elements;
175024
- if (elements.some((e2) => ts11.isStringLiteralLike(e2) && e2.text === "iap")) return {};
175036
+ if (elements.some((e2) => ts12.isStringLiteralLike(e2) && e2.text === "iap")) return {};
175025
175037
  const last = elements[elements.length - 1];
175026
175038
  return {
175027
175039
  splice: last ? { at: last.end, end: last.end, text: ', "iap"' } : { at: list2.getStart(), end: list2.end, text: '["iap"]' },
@@ -192620,7 +192632,7 @@ var init_site_oauth_client = __esm({
192620
192632
 
192621
192633
  // src/site-analyze/velo-source.ts
192622
192634
  import path from "node:path";
192623
- import ts12 from "typescript";
192635
+ import ts13 from "typescript";
192624
192636
  function applySourceEdits(source, edits) {
192625
192637
  const chunks = [];
192626
192638
  let cursor = 0;
@@ -192638,13 +192650,13 @@ function redactVeloSource(source, knownSecrets = []) {
192638
192650
  /\b(?:IST\.[\w.-]+|eyJ[\w-]+\.[\w-]+\.[\w-]+|(?:sk|rk)_(?:live|test)_[\w-]+|gh[pousr]_[\w]+|github_pat_[\w]+|AKIA[A-Z0-9]{16})\b/g,
192639
192651
  REDACTED2
192640
192652
  ).replace(/\b(?:Bearer|Basic)\s+[A-Za-z0-9._~+/=-]+/gi, REDACTED2).replace(/\b([a-z][a-z0-9+.-]*:\/\/)[^\s/'"`]+:[^\s/'"`]+@/gi, "$1[REDACTED]@").replace(/([?&](?:api[-_]?key|token|secret|password|signature)=)[^&#\s'"`]+/gi, "$1[REDACTED]");
192641
- const parsed = ts12.createSourceFile("backend.ts", source, ts12.ScriptTarget.Latest, true);
192653
+ const parsed = ts13.createSourceFile("backend.ts", source, ts13.ScriptTarget.Latest, true);
192642
192654
  const comments = /* @__PURE__ */ new Map();
192643
192655
  const visitComments = (node) => {
192644
192656
  for (const range of [
192645
- ...ts12.getLeadingCommentRanges(source, node.pos) ?? [],
192646
- ...ts12.getTrailingCommentRanges(source, node.pos) ?? [],
192647
- ...ts12.getTrailingCommentRanges(source, node.end) ?? []
192657
+ ...ts13.getLeadingCommentRanges(source, node.pos) ?? [],
192658
+ ...ts13.getTrailingCommentRanges(source, node.pos) ?? [],
192659
+ ...ts13.getTrailingCommentRanges(source, node.end) ?? []
192648
192660
  ]) comments.set(range.pos, range.end);
192649
192661
  for (const child of node.getChildren(parsed)) visitComments(child);
192650
192662
  };
@@ -192663,22 +192675,22 @@ function redactVeloSource(source, knownSecrets = []) {
192663
192675
  if (/^["'`][A-Za-z0-9_+/=-]{24,}["'`]$/.test(token)) return JSON.stringify(REDACTED2);
192664
192676
  return token;
192665
192677
  };
192666
- const clean2 = ts12.createSourceFile("backend.ts", source, ts12.ScriptTarget.Latest, true);
192678
+ const clean2 = ts13.createSourceFile("backend.ts", source, ts13.ScriptTarget.Latest, true);
192667
192679
  const masks = [];
192668
192680
  const collectMasks = (node) => {
192669
192681
  const start = node.getStart(clean2);
192670
- if (ts12.isRegularExpressionLiteral(node)) {
192682
+ if (ts13.isRegularExpressionLiteral(node)) {
192671
192683
  masks.push({ start, end: node.end, text: " ".repeat(node.end - start) });
192672
- } else if (ts12.isStringLiteral(node) || ts12.isTemplateLiteralToken(node)) {
192684
+ } else if (ts13.isStringLiteral(node) || ts13.isTemplateLiteralToken(node)) {
192673
192685
  masks.push({ start, end: node.end, text: source.slice(start, node.end).replace(/;/g, " ") });
192674
192686
  }
192675
- ts12.forEachChild(node, collectMasks);
192687
+ ts13.forEachChild(node, collectMasks);
192676
192688
  };
192677
192689
  collectMasks(clean2);
192678
192690
  const assignmentContext = applySourceEdits(source, masks);
192679
192691
  const edits = [];
192680
192692
  const visitLiterals = (node) => {
192681
- if (ts12.isStringLiteral(node) || ts12.isNoSubstitutionTemplateLiteral(node) || ts12.isTemplateExpression(node)) {
192693
+ if (ts13.isStringLiteral(node) || ts13.isNoSubstitutionTemplateLiteral(node) || ts13.isTemplateExpression(node)) {
192682
192694
  const start = node.getStart(clean2);
192683
192695
  const text12 = source.slice(start, node.end);
192684
192696
  const redacted = redactLiteral(text12, start);
@@ -192687,7 +192699,7 @@ function redactVeloSource(source, knownSecrets = []) {
192687
192699
  return;
192688
192700
  }
192689
192701
  }
192690
- ts12.forEachChild(node, visitLiterals);
192702
+ ts13.forEachChild(node, visitLiterals);
192691
192703
  };
192692
192704
  visitLiterals(clean2);
192693
192705
  return applySourceEdits(source, edits);
@@ -192726,19 +192738,19 @@ function selectVeloSource(files, request, knownSecrets = []) {
192726
192738
  selected.set(file2.path, { source: excerpt, sourceTruncated: excerpt.length < redacted.length });
192727
192739
  remaining -= excerpt.length;
192728
192740
  const dependencies = [];
192729
- const parsed = ts12.createSourceFile(file2.path, file2.content, ts12.ScriptTarget.Latest, true);
192741
+ const parsed = ts13.createSourceFile(file2.path, file2.content, ts13.ScriptTarget.Latest, true);
192730
192742
  const specifiers = [];
192731
192743
  const collectImports = (node) => {
192732
192744
  let specifier;
192733
- if (ts12.isImportDeclaration(node) || ts12.isExportDeclaration(node)) {
192745
+ if (ts13.isImportDeclaration(node) || ts13.isExportDeclaration(node)) {
192734
192746
  specifier = node.moduleSpecifier;
192735
- } else if (ts12.isImportEqualsDeclaration(node) && ts12.isExternalModuleReference(node.moduleReference)) {
192747
+ } else if (ts13.isImportEqualsDeclaration(node) && ts13.isExternalModuleReference(node.moduleReference)) {
192736
192748
  specifier = node.moduleReference.expression;
192737
- } else if (ts12.isCallExpression(node) && (node.expression.kind === ts12.SyntaxKind.ImportKeyword || ts12.isIdentifier(node.expression) && node.expression.text === "require")) {
192749
+ } else if (ts13.isCallExpression(node) && (node.expression.kind === ts13.SyntaxKind.ImportKeyword || ts13.isIdentifier(node.expression) && node.expression.text === "require")) {
192738
192750
  specifier = node.arguments[0];
192739
192751
  }
192740
- if (specifier && ts12.isStringLiteralLike(specifier)) specifiers.push(specifier.text);
192741
- ts12.forEachChild(node, collectImports);
192752
+ if (specifier && ts13.isStringLiteralLike(specifier)) specifiers.push(specifier.text);
192753
+ ts13.forEachChild(node, collectImports);
192742
192754
  };
192743
192755
  collectImports(parsed);
192744
192756
  for (const specifier of specifiers) {
@@ -114,10 +114,18 @@ should keep working.
114
114
  It **refuses** (exit `2`, nothing written) when `--keep` is missing or names an id the app does
115
115
  not serve (the report lists the ones it does), when the app's `dev/index.ts` or `config.ts` is
116
116
  no longer in the shape `himi init` writes (a block, the `navigation` object or
117
- `workerSubtreeScreens` that is not plain JSON), when kept screens link to removed ones and no `--links` was given, when no tab would be
117
+ `workerSubtreeScreens` that is not JSON data), when kept screens link to removed ones and no `--links` was given, when no tab would be
118
118
  left, and when dropping links would leave a kept screen empty or cannot reach a link. Then trim
119
119
  by hand, below.
120
120
 
121
+ The `navigation` object and `workerSubtreeScreens` array in `config.ts` may contain
122
+ `//` or `/* … */` comments. Read-only template commands preserve their
123
+ source bytes. Commands that rewrite navigation, including trim and `template screens --add`,
124
+ re-emit that block as JSON, removing comments inside it.
125
+ Property names and strings must remain double-quoted; computed values, spreads and function
126
+ calls are refused rather than evaluated. This also keeps migrated navigation readable by
127
+ `himi template screens`, `himi template inspect` and `himi template trim` after an agent adds notes.
128
+
121
129
  Afterwards: `himi render <each kept screen>`, then `himi test`.
122
130
 
123
131
  ## How to trim by hand
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wix/himalaya-cli",
3
- "version": "0.1555.0",
3
+ "version": "0.1556.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": [
@@ -71,5 +71,5 @@
71
71
  "artifactId": "himalaya-cli"
72
72
  }
73
73
  },
74
- "falconPackageHash": "e307bc39941a4361847922e798725eec91eaa76e98753612e7133ca1"
74
+ "falconPackageHash": "23dddd99ae87fea0fd887d35bbd733e1d696ad3f0b28d9c774b360ee"
75
75
  }