@wix/himalaya-cli 0.1078.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";
@@ -23946,7 +24029,6 @@ function shouldRevealError(args) {
23946
24029
  var EMAIL_RE, URL_HOST_RE, INTEGER_RE, NUMBER_RE;
23947
24030
  var init_validation = __esm({
23948
24031
  "../../core/ts/src/validation.ts"() {
23949
- "use strict";
23950
24032
  EMAIL_RE = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*\.[A-Za-z]{2,}$/;
23951
24033
  URL_HOST_RE = /^[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*(:[0-9]+)?$/;
23952
24034
  INTEGER_RE = /^[+-]?[0-9]+$/;
@@ -27567,7 +27649,6 @@ function validateWorkerSubtree(raw, slotId, policy, actionCatalog) {
27567
27649
  var WORKER_SUBTREE_CEILINGS, ID_PART, ACTION_ID;
27568
27650
  var init_worker_subtree = __esm({
27569
27651
  "../../core/ts/src/worker-subtree.ts"() {
27570
- "use strict";
27571
27652
  init_worker_subtree_safe_types_generated();
27572
27653
  WORKER_SUBTREE_CEILINGS = Object.freeze({
27573
27654
  maxEncodedBytes: 65536,
@@ -54113,10 +54194,16 @@ function previewResponse(pathname, assets, mount = "/preview", creds, handoverAt
54113
54194
  headers: { "content-type": "text/html; charset=utf-8", "cache-control": "public, max-age=31536000, immutable", "content-security-policy": T5_FRAME_CSP }
54114
54195
  });
54115
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
+ }
54116
54203
  const immutable = key2.startsWith("assets/");
54117
54204
  return bytes(hit, immutable ? "public, max-age=31536000, immutable" : "no-cache");
54118
54205
  }
54119
- if (key2.startsWith("assets/")) {
54206
+ if (key2.startsWith("assets/") || key2.startsWith("__himi/")) {
54120
54207
  return new Response(JSON.stringify({ error: "preview_asset_not_found", key: key2 }), {
54121
54208
  status: 404,
54122
54209
  headers: { "content-type": "application/json; charset=utf-8" }
@@ -54129,10 +54216,12 @@ function previewResponse(pathname, assets, mount = "/preview", creds, handoverAt
54129
54216
  headers: { "content-type": "application/json; charset=utf-8" }
54130
54217
  });
54131
54218
  }
54132
- 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;
54133
54220
  var init_preview3 = __esm({
54134
54221
  "../../packages/serve/src/preview.ts"() {
54135
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:";
54136
54225
  PREVIEW_BASE_JS = // Both serve mounts (/preview framed + /app unframed — RFC 0051 track D) serve the SAME
54137
54226
  // embedded artifact, so one shim derives whichever mount the browser is on. Non-greedy:
54138
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.1078.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": "70cae8e9f3455dbda3af632c51aa39b8900dab8e391552018b340702"
70
+ "falconPackageHash": "d5eb7481dca2d7a6272424f6a9a08ddc1bca8661f0a9a11443e2ca45"
71
71
  }