@wix/himalaya-cli 0.1077.0 → 0.1079.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.
@@ -246,6 +246,15 @@ export interface AppConfig {
246
246
  * headroom, then move within it OTA. Full rationale: docs/orientation.md.
247
247
  */
248
248
  orientationEnvelope?: OrientationEnvelope;
249
+ /**
250
+ * RFC 0063 §9 — ship the Ricos engine page (`core/rich-content-editor/dist/editor.html`, several MB)
251
+ * inside this app's binaries, so its `RichContentEditor` screens can edit. `tools/native-config`
252
+ * writes the iOS/macOS folder reference; `scripts/gen.sh` copies the page into
253
+ * `localweb/ricos/editor.html` (iOS/macOS bundle) and `assets/localweb/ricos/editor.html`
254
+ * (Android). Absent/false ⇒ nothing is baked and an editor renders its `fallback`.
255
+ * Build-time only — cannot be switched on OTA.
256
+ */
257
+ richContentEditor?: boolean;
249
258
  /** Path to `tokens.json` (resolved relative to config.ts). */
250
259
  designTokensPath: string;
251
260
  /** Resolved tokens — populated by the loader, not the caller. */
@@ -7493,6 +7493,9 @@ function validateConfigShape(config) {
7493
7493
  throw new Error("defineApp: tier5Cap.maxBundleKilobytes must be positive.");
7494
7494
  }
7495
7495
  }
7496
+ if (config.richContentEditor !== void 0 && typeof config.richContentEditor !== "boolean") {
7497
+ throw new Error("defineApp: richContentEditor must be a boolean (RFC 0063 \xA79 opt-in).");
7498
+ }
7496
7499
  if (config.workerSubtreeScreens) {
7497
7500
  const seen = /* @__PURE__ */ new Set();
7498
7501
  for (const screenId of config.workerSubtreeScreens) {
package/dist/cli.mjs CHANGED
@@ -12495,6 +12495,7 @@ function resolveIdiom(tokens, ctx = {}) {
12495
12495
  var IDIOM_CONTEXTS, UNSAFE_KEYS;
12496
12496
  var init_idiom = __esm({
12497
12497
  "../../core/ts/src/idiom.ts"() {
12498
+ "use strict";
12498
12499
  IDIOM_CONTEXTS = {
12499
12500
  ios: { native: ["ios"] },
12500
12501
  android: { native: ["material"] },
@@ -17090,6 +17091,79 @@ struct GeneratedLiveActivityBundle: WidgetBundle {
17090
17091
  }
17091
17092
  });
17092
17093
 
17094
+ // ../native-config/localweb.ts
17095
+ function resourcesDirOf(projectYml) {
17096
+ const m = /^\s*-\s*path:\s*(\S+)\/Resources\/seed\s*$/m.exec(projectYml);
17097
+ return m ? `${m[1]}/Resources` : null;
17098
+ }
17099
+ function renderLocalWebYaml(resourcesDir, declared) {
17100
+ return (indent) => declared && resourcesDir ? [`${indent}- path: ${resourcesDir}/localweb`, `${indent} type: folder`, `${indent} optional: true`] : [];
17101
+ }
17102
+ function assertLocalWebBlockLanded(app, declared, path2, outcome) {
17103
+ if (!declared || outcome !== "skipped") return;
17104
+ throw new Error(
17105
+ `${app}: config.ts declares richContentEditor: true, but ${path2} has no "# >>> ${LABEL_LOCALWEB}" markers. Add the markers and a "- Resources/localweb" exclude (core/rich-content-editor/README.md, "Opting an app in"); otherwise gen.sh copies the engine page into Resources/ and the .app never contains it.`
17106
+ );
17107
+ }
17108
+ var LABEL_LOCALWEB;
17109
+ var init_localweb = __esm({
17110
+ "../native-config/localweb.ts"() {
17111
+ LABEL_LOCALWEB = "himalaya:localweb";
17112
+ }
17113
+ });
17114
+
17115
+ // ../../core/rich-content-editor/prebuild.mjs
17116
+ function codeOnly(src) {
17117
+ let out2 = "";
17118
+ let i = 0;
17119
+ const n = src.length;
17120
+ while (i < n) {
17121
+ const c = src[i], d = src[i + 1];
17122
+ if (c === "/" && d === "/") {
17123
+ while (i < n && src[i] !== "\n") i++;
17124
+ continue;
17125
+ }
17126
+ if (c === "/" && d === "*") {
17127
+ i += 2;
17128
+ while (i < n && !(src[i] === "*" && src[i + 1] === "/")) {
17129
+ if (src[i] === "\n") out2 += "\n";
17130
+ i++;
17131
+ }
17132
+ i += 2;
17133
+ continue;
17134
+ }
17135
+ if (c === '"' || c === "'" || c === "`") {
17136
+ out2 += c;
17137
+ i++;
17138
+ while (i < n && src[i] !== c) {
17139
+ if (src[i] === "\\") {
17140
+ i += 2;
17141
+ continue;
17142
+ }
17143
+ if (c !== "`" && src[i] === "\n") break;
17144
+ out2 += src[i] === "\n" ? "\n" : " ";
17145
+ i++;
17146
+ }
17147
+ if (i < n && src[i] === c) {
17148
+ out2 += c;
17149
+ i++;
17150
+ }
17151
+ continue;
17152
+ }
17153
+ out2 += c;
17154
+ i++;
17155
+ }
17156
+ return out2;
17157
+ }
17158
+ function declaresRichContentEditor(configTs) {
17159
+ return /^\s*richContentEditor\s*:\s*true\s*,?\s*$/m.test(codeOnly(String(configTs ?? "")));
17160
+ }
17161
+ var init_prebuild = __esm({
17162
+ "../../core/rich-content-editor/prebuild.mjs"() {
17163
+ "use strict";
17164
+ }
17165
+ });
17166
+
17093
17167
  // ../native-config/gen-native-config.ts
17094
17168
  var gen_native_config_exports = {};
17095
17169
  __export(gen_native_config_exports, {
@@ -17396,6 +17470,13 @@ function genNativeConfig(app, opts = {}) {
17396
17470
  // apps that hand-author their own launch screen are untouched.
17397
17471
  applyToFile(iosProjectYml(app), "yaml", LABEL_IOS_SPLASH, renderSplashYaml, check)
17398
17472
  ];
17473
+ const rce = declaresRichContentEditor(configTs);
17474
+ for (const yml of [iosYml, macosProjectYml(app)]) {
17475
+ const text6 = existsSync26(yml) ? readFileSync26(yml, "utf8") : "";
17476
+ const r = applyToFile(yml, "yaml", LABEL_LOCALWEB, renderLocalWebYaml(resourcesDirOf(text6), rce), check);
17477
+ if (existsSync26(yml)) assertLocalWebBlockLanded(app, rce, yml, r.outcome);
17478
+ files.push(r);
17479
+ }
17399
17480
  if (targetManaged) {
17400
17481
  const plan = live2;
17401
17482
  files.push(applyToFile(iosYml, "yaml", LABEL_LIVE_TARGET, (i) => plan.target.map((line) => i + line), check));
@@ -17425,6 +17506,8 @@ var init_gen_native_config = __esm({
17425
17506
  init_icon2();
17426
17507
  init_live_activity();
17427
17508
  init_car();
17509
+ init_localweb();
17510
+ init_prebuild();
17428
17511
  init_src2();
17429
17512
  LABEL_IOS_INFO = "himalaya:capabilities:info";
17430
17513
  LABEL_IOS_ENTITLEMENTS = "himalaya:capabilities:entitlements";
@@ -54111,10 +54194,16 @@ function previewResponse(pathname, assets, mount = "/preview", creds, handoverAt
54111
54194
  headers: { "content-type": "text/html; charset=utf-8", "cache-control": "public, max-age=31536000, immutable", "content-security-policy": T5_FRAME_CSP }
54112
54195
  });
54113
54196
  }
54197
+ if (key2 === RICOS_EDITOR_KEY) {
54198
+ return new Response(assetBytes(hit), {
54199
+ status: 200,
54200
+ headers: { "content-type": "text/html; charset=utf-8", "cache-control": "no-cache", "content-security-policy": RICOS_EDITOR_CSP, "x-content-type-options": "nosniff" }
54201
+ });
54202
+ }
54114
54203
  const immutable = key2.startsWith("assets/");
54115
54204
  return bytes(hit, immutable ? "public, max-age=31536000, immutable" : "no-cache");
54116
54205
  }
54117
- if (key2.startsWith("assets/")) {
54206
+ if (key2.startsWith("assets/") || key2.startsWith("__himi/")) {
54118
54207
  return new Response(JSON.stringify({ error: "preview_asset_not_found", key: key2 }), {
54119
54208
  status: 404,
54120
54209
  headers: { "content-type": "application/json; charset=utf-8" }
@@ -54127,10 +54216,12 @@ function previewResponse(pathname, assets, mount = "/preview", creds, handoverAt
54127
54216
  headers: { "content-type": "application/json; charset=utf-8" }
54128
54217
  });
54129
54218
  }
54130
- var T5_FRAME_CSP, PREVIEW_BASE_JS, PREVIEW_ENTRY_RECOVERY_JS, MOUNT_STRIP;
54219
+ var T5_FRAME_CSP, RICOS_EDITOR_KEY, RICOS_EDITOR_CSP, PREVIEW_BASE_JS, PREVIEW_ENTRY_RECOVERY_JS, MOUNT_STRIP;
54131
54220
  var init_preview3 = __esm({
54132
54221
  "../../packages/serve/src/preview.ts"() {
54133
54222
  T5_FRAME_CSP = "default-src 'none'; script-src 'unsafe-inline' 'unsafe-eval'; connect-src 'none'; img-src 'none'; media-src 'none'; style-src 'unsafe-inline'; base-uri 'none'; form-action 'none'; sandbox allow-scripts";
54223
+ RICOS_EDITOR_KEY = "__himi/ricos/editor.html";
54224
+ RICOS_EDITOR_CSP = "default-src 'none'; script-src 'unsafe-inline'; style-src 'unsafe-inline'; img-src https: data: blob:; media-src https: blob:";
54134
54225
  PREVIEW_BASE_JS = // Both serve mounts (/preview framed + /app unframed — RFC 0051 track D) serve the SAME
54135
54226
  // embedded artifact, so one shim derives whichever mount the browser is on. Non-greedy:
54136
54227
  // the EARLIEST mount segment wins, mirroring the SPA's own deployBase (an app literally
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wix/himalaya-cli",
3
- "version": "0.1077.0",
3
+ "version": "0.1079.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": [
@@ -67,5 +67,5 @@
67
67
  "artifactId": "himalaya-cli"
68
68
  }
69
69
  },
70
- "falconPackageHash": "f05f26ed8fab307cde555efea47651788f996fd6d20bb908d209e946"
70
+ "falconPackageHash": "d5eb7481dca2d7a6272424f6a9a08ddc1bca8661f0a9a11443e2ca45"
71
71
  }