@wix/himalaya-cli 0.1201.0 → 0.1203.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/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/dev-server/src/builder.d.ts +2 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/ts/src/schema.d.ts +20 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/core/validation.mjs +1 -1
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/core.mjs +3 -1
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/state.mjs +1 -1
- package/dist/cli.mjs +325 -24
- package/dist/preview-assets.generated.bin +0 -0
- package/guides/component-reference.json +10 -1
- package/guides/component-reference.md +18 -2
- package/guides/index.json +1 -1
- package/package.json +2 -2
|
@@ -610,6 +610,8 @@ export declare function formField(props: {
|
|
|
610
610
|
* opens the device photo picker; the renderer uploads the bytes to Wix Media and
|
|
611
611
|
* calls `<uploadService>.genUpload`/`setMedia` on the screen's worker so the well
|
|
612
612
|
* previews the photo and the worker can attach it on save. Generic (any app).
|
|
613
|
+
* Declared in core.proto as `media_field = 163` (#3744); `label` also names the
|
|
614
|
+
* well for assistive technology, so pass one.
|
|
613
615
|
*/
|
|
614
616
|
export declare function mediaField(props: {
|
|
615
617
|
valuePath: string;
|
package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/ts/src/schema.d.ts
CHANGED
|
@@ -1549,6 +1549,22 @@ export interface RichContentEditorProps {
|
|
|
1549
1549
|
/** Rendered when the engine page is unavailable (not bundled / missing / failed / 15 s timeout). */
|
|
1550
1550
|
fallback?: Component;
|
|
1551
1551
|
}
|
|
1552
|
+
/**
|
|
1553
|
+
* #3744 — an image well bound to a `$service:` image URL. Tapping it opens the platform photo
|
|
1554
|
+
* picker (PhotosPicker on iOS, the Android photo picker, a file chooser on web); the renderer
|
|
1555
|
+
* then runs the upload contract against the screen's worker: `<uploadService>.genUpload({fileName,
|
|
1556
|
+
* mimeType})` → PUT the bytes to `<uploadService>.uploadUrl` + `?filename=<fileName>` →
|
|
1557
|
+
* `<uploadService>.setMedia({mediaId, imageUrl})`. The well previews whatever `valuePath`
|
|
1558
|
+
* resolves to, so the worker updating that value in `setMedia` is what shows the new photo.
|
|
1559
|
+
*/
|
|
1560
|
+
export interface MediaFieldProps {
|
|
1561
|
+
/** `$service:<svc>.<path>` → the current image URL; empty ⇒ the empty well with `label`. */
|
|
1562
|
+
valuePath: string;
|
|
1563
|
+
/** The worker service exposing `genUpload` / `setMedia` and the `uploadUrl` value. */
|
|
1564
|
+
uploadService: string;
|
|
1565
|
+
/** Empty-well copy (a message key or literal). Default "Add a photo". */
|
|
1566
|
+
label?: string;
|
|
1567
|
+
}
|
|
1552
1568
|
/**
|
|
1553
1569
|
* RFC 0063 — a Wix Ricos rich-content document rendered natively: headings, lists, links,
|
|
1554
1570
|
* images, galleries, video, tables and link cards (never a WebView). The document travels as a
|
|
@@ -2379,6 +2395,10 @@ export type CoreComponentBody = {
|
|
|
2379
2395
|
package: "himalaya";
|
|
2380
2396
|
type: "RichContentEditor";
|
|
2381
2397
|
props: RichContentEditorProps;
|
|
2398
|
+
} | {
|
|
2399
|
+
package: "himalaya";
|
|
2400
|
+
type: "MediaField";
|
|
2401
|
+
props: MediaFieldProps;
|
|
2382
2402
|
} | {
|
|
2383
2403
|
package: "himalaya";
|
|
2384
2404
|
type: "VoiceNote";
|
|
@@ -193,7 +193,7 @@ function errorMessageFor(args) {
|
|
|
193
193
|
if (worker) return worker;
|
|
194
194
|
const failure = validate(args.rule, args.value);
|
|
195
195
|
if (!failure) return null;
|
|
196
|
-
if (args.rule?.message) return args.rule.message;
|
|
196
|
+
if (typeof args.rule?.message === "string" && args.rule.message.trim()) return args.rule.message;
|
|
197
197
|
return defaultMessage(failure, args.catalog);
|
|
198
198
|
}
|
|
199
199
|
function shouldRevealError(args) {
|
|
@@ -8774,6 +8774,8 @@ var CORE_COMPONENTS = /* @__PURE__ */ new Set([
|
|
|
8774
8774
|
"himalaya.RichContent",
|
|
8775
8775
|
// Rich content editor — RFC 0063 §6
|
|
8776
8776
|
"himalaya.RichContentEditor",
|
|
8777
|
+
// Image well + Wix Media upload — #3744
|
|
8778
|
+
"himalaya.MediaField",
|
|
8777
8779
|
// Recorded-audio bubble — messenger design G4
|
|
8778
8780
|
"himalaya.VoiceNote",
|
|
8779
8781
|
"himalaya.Marquee",
|
|
@@ -9251,7 +9253,7 @@ function errorMessageFor(args) {
|
|
|
9251
9253
|
if (worker) return worker;
|
|
9252
9254
|
const failure = validate(args.rule, args.value);
|
|
9253
9255
|
if (!failure) return null;
|
|
9254
|
-
if (args.rule?.message) return args.rule.message;
|
|
9256
|
+
if (typeof args.rule?.message === "string" && args.rule.message.trim()) return args.rule.message;
|
|
9255
9257
|
return defaultMessage(failure, args.catalog);
|
|
9256
9258
|
}
|
|
9257
9259
|
function shouldRevealError(args) {
|
|
@@ -155,7 +155,7 @@ function errorMessageFor(args) {
|
|
|
155
155
|
if (worker) return worker;
|
|
156
156
|
const failure = validate(args.rule, args.value);
|
|
157
157
|
if (!failure) return null;
|
|
158
|
-
if (args.rule?.message) return args.rule.message;
|
|
158
|
+
if (typeof args.rule?.message === "string" && args.rule.message.trim()) return args.rule.message;
|
|
159
159
|
return defaultMessage(failure, args.catalog);
|
|
160
160
|
}
|
|
161
161
|
var nonEmpty = (type) => (v) => typeof v === "string" && v.length > 0 && isValid({ type }, v);
|
package/dist/cli.mjs
CHANGED
|
@@ -6818,6 +6818,7 @@ function walk(node, registry, path2, out2) {
|
|
|
6818
6818
|
var SYSTEM_FONT_FAMILY, TONAL_ELEVATION_ALPHA, COLOR_TOKEN_PROPS, TYPOGRAPHY_TOKEN_PROPS;
|
|
6819
6819
|
var init_tokens = __esm({
|
|
6820
6820
|
"../../core/ts/src/tokens.ts"() {
|
|
6821
|
+
"use strict";
|
|
6821
6822
|
SYSTEM_FONT_FAMILY = "$system";
|
|
6822
6823
|
TONAL_ELEVATION_ALPHA = [0, 0.05, 0.08, 0.11, 0.12, 0.14];
|
|
6823
6824
|
COLOR_TOKEN_PROPS = {
|
|
@@ -6868,6 +6869,7 @@ function resolveTranslation(value, catalog, sourceCatalog) {
|
|
|
6868
6869
|
var BINDING_SIGILS, BINDING_SIGIL_RE, TRANSLATION_PREFIX, TRANSLATION_KEY_RE;
|
|
6869
6870
|
var init_bindings = __esm({
|
|
6870
6871
|
"../../core/ts/src/bindings.ts"() {
|
|
6872
|
+
"use strict";
|
|
6871
6873
|
BINDING_SIGILS = ["service", "flag", "item", "t"];
|
|
6872
6874
|
BINDING_SIGIL_RE = new RegExp(
|
|
6873
6875
|
`^\\$(?:${BINDING_SIGILS.filter((s) => s !== "t").join("|")})\\b|^\\$t:`
|
|
@@ -7825,6 +7827,8 @@ var init_validator = __esm({
|
|
|
7825
7827
|
"himalaya.RichContent",
|
|
7826
7828
|
// Rich content editor — RFC 0063 §6
|
|
7827
7829
|
"himalaya.RichContentEditor",
|
|
7830
|
+
// Image well + Wix Media upload — #3744
|
|
7831
|
+
"himalaya.MediaField",
|
|
7828
7832
|
// Recorded-audio bubble — messenger design G4
|
|
7829
7833
|
"himalaya.VoiceNote",
|
|
7830
7834
|
"himalaya.Marquee",
|
|
@@ -8265,6 +8269,9 @@ var init_a11y_contract = __esm({
|
|
|
8265
8269
|
VoiceNote: { role: "group", name: "required", state: ["playing", "duration/position"], decorative: false },
|
|
8266
8270
|
Map: { role: "image", name: "required", state: [], decorative: false },
|
|
8267
8271
|
WebView: { role: "group", name: "required", state: [], decorative: false },
|
|
8272
|
+
// #3744 — the image well is a BUTTON (it opens the photo picker), named by its `label` on every
|
|
8273
|
+
// renderer — including once a photo fills the well and the label is no longer drawn.
|
|
8274
|
+
MediaField: { role: "button", name: "required", state: ["photo set / empty", "uploading"], decorative: false },
|
|
8268
8275
|
// ---- Interactive controls -----------------------------------------------------------
|
|
8269
8276
|
Button: { role: "button", name: "required", state: ["disabled"], decorative: false },
|
|
8270
8277
|
Fab: { role: "button", name: "required", state: ["disabled"], decorative: false },
|
|
@@ -10359,6 +10366,33 @@ function richContentEditorFindings(descriptor) {
|
|
|
10359
10366
|
visit(descriptor, "", true, false);
|
|
10360
10367
|
return out2;
|
|
10361
10368
|
}
|
|
10369
|
+
function mediaFieldFindings(descriptor) {
|
|
10370
|
+
const out2 = [];
|
|
10371
|
+
const visit = (v, path2, atRoot) => {
|
|
10372
|
+
if (Array.isArray(v)) {
|
|
10373
|
+
v.forEach((x, i) => visit(x, `${path2}[${i}]`, false));
|
|
10374
|
+
return;
|
|
10375
|
+
}
|
|
10376
|
+
if (!v || typeof v !== "object") return;
|
|
10377
|
+
const record2 = v;
|
|
10378
|
+
const body = record2.body;
|
|
10379
|
+
if (body?.package === "himalaya" && body.type === "MediaField") {
|
|
10380
|
+
const p = body.props ?? {};
|
|
10381
|
+
if (typeof p.valuePath !== "string" || !p.valuePath.startsWith("$service:") || !WHOLE_VALUE_BINDING.test(p.valuePath)) {
|
|
10382
|
+
out2.push({ path: path2, message: `MediaField.valuePath must be a "$service:<service>.<field>" binding to the current image URL, got ${JSON.stringify(p.valuePath ?? null)} \u2014 every renderer reads it only as a binding to one field, so the well would stay empty` });
|
|
10383
|
+
}
|
|
10384
|
+
if (typeof p.uploadService !== "string" || !EDITOR_SERVICE_NAME.test(p.uploadService)) {
|
|
10385
|
+
out2.push({ path: path2, message: `MediaField.uploadService must name a worker service (letters, digits, "_" or "-") exposing genUpload / setMedia, got ${JSON.stringify(p.uploadService ?? null)}` });
|
|
10386
|
+
}
|
|
10387
|
+
}
|
|
10388
|
+
for (const [key2, child] of Object.entries(record2)) {
|
|
10389
|
+
if (isOpaqueAuthorJson(key2, child, atRoot)) continue;
|
|
10390
|
+
visit(child, path2 ? `${path2}.${key2}` : key2, false);
|
|
10391
|
+
}
|
|
10392
|
+
};
|
|
10393
|
+
visit(descriptor, "", true);
|
|
10394
|
+
return out2;
|
|
10395
|
+
}
|
|
10362
10396
|
function renderedWixMediaReferences(descriptor) {
|
|
10363
10397
|
const record2 = descriptor && typeof descriptor === "object" ? descriptor : null;
|
|
10364
10398
|
const regions = record2 && "payload" in record2 ? [
|
|
@@ -10468,6 +10502,9 @@ function validateScreenDescriptor(screenId, descriptor, opts = {}) {
|
|
|
10468
10502
|
for (const finding of richContentEditorFindings(descriptor)) {
|
|
10469
10503
|
issues.push({ severity: "error", pass: "rich-content-editor", path: finding.path, message: finding.message });
|
|
10470
10504
|
}
|
|
10505
|
+
for (const finding of mediaFieldFindings(descriptor)) {
|
|
10506
|
+
issues.push({ severity: "error", pass: "media-field", path: finding.path, message: finding.message });
|
|
10507
|
+
}
|
|
10471
10508
|
const bindings = collectServiceBindings(descriptor);
|
|
10472
10509
|
const descriptorActions = collectDescriptorActions(descriptor);
|
|
10473
10510
|
const workerActions = descriptorActions.filter(({ actionId }) => actionId.startsWith("tier5."));
|
|
@@ -11316,6 +11353,7 @@ var init_validate_descriptor_core = __esm({
|
|
|
11316
11353
|
zoom: "number"
|
|
11317
11354
|
},
|
|
11318
11355
|
Marquee: { color: "string", durationMs: "number", style: "string", text: "string" },
|
|
11356
|
+
MediaField: { label: "string", uploadService: "string", valuePath: "string" },
|
|
11319
11357
|
MediaPlayer: {
|
|
11320
11358
|
allowCellular: "boolean",
|
|
11321
11359
|
appearance: "any",
|
|
@@ -11691,6 +11729,7 @@ var init_validate_descriptor_core = __esm({
|
|
|
11691
11729
|
Form: ["id", "submitButton"],
|
|
11692
11730
|
FragmentSlot: ["casePath", "defaultCase"],
|
|
11693
11731
|
Icon: ["name"],
|
|
11732
|
+
MediaField: ["valuePath", "uploadService"],
|
|
11694
11733
|
ProgressBar: ["progress"],
|
|
11695
11734
|
SegmentedControl: ["selectedId"],
|
|
11696
11735
|
Snackbar: ["message"],
|
|
@@ -25205,7 +25244,7 @@ function errorMessageFor(args) {
|
|
|
25205
25244
|
if (worker) return worker;
|
|
25206
25245
|
const failure = validate(args.rule, args.value);
|
|
25207
25246
|
if (!failure) return null;
|
|
25208
|
-
if (args.rule?.message) return args.rule.message;
|
|
25247
|
+
if (typeof args.rule?.message === "string" && args.rule.message.trim()) return args.rule.message;
|
|
25209
25248
|
return defaultMessage(failure, args.catalog);
|
|
25210
25249
|
}
|
|
25211
25250
|
function shouldRevealError(args) {
|
|
@@ -32628,6 +32667,181 @@ var init_richContentEditor = __esm({
|
|
|
32628
32667
|
}
|
|
32629
32668
|
});
|
|
32630
32669
|
|
|
32670
|
+
// ../../core/web-host/src/actions/presigned-upload-policy.ts
|
|
32671
|
+
function hostMatches(host) {
|
|
32672
|
+
const h = host.toLowerCase().split(":")[0];
|
|
32673
|
+
return PRESIGNED_UPLOAD_HOST_ROOTS.some((r) => h === r || h.endsWith(`.${r}`));
|
|
32674
|
+
}
|
|
32675
|
+
function isPresignedUploadTarget(raw) {
|
|
32676
|
+
if (!raw) return false;
|
|
32677
|
+
let u;
|
|
32678
|
+
try {
|
|
32679
|
+
u = new URL(raw);
|
|
32680
|
+
} catch {
|
|
32681
|
+
return false;
|
|
32682
|
+
}
|
|
32683
|
+
if (u.protocol !== "https:") return false;
|
|
32684
|
+
if (u.username || u.password) return false;
|
|
32685
|
+
return hostMatches(u.hostname);
|
|
32686
|
+
}
|
|
32687
|
+
var PRESIGNED_UPLOAD_HOST_ROOTS, MAX_INLINE_BASE64_BYTES, MAX_UPLOAD_BYTES;
|
|
32688
|
+
var init_presigned_upload_policy = __esm({
|
|
32689
|
+
"../../core/web-host/src/actions/presigned-upload-policy.ts"() {
|
|
32690
|
+
PRESIGNED_UPLOAD_HOST_ROOTS = ["wixmp.com"];
|
|
32691
|
+
MAX_INLINE_BASE64_BYTES = 8 * 1024 * 1024;
|
|
32692
|
+
MAX_UPLOAD_BYTES = 32 * 1024 * 1024;
|
|
32693
|
+
}
|
|
32694
|
+
});
|
|
32695
|
+
|
|
32696
|
+
// ../../core/web-renderer/src/mediaFieldUpload.ts
|
|
32697
|
+
function mediaFieldName(label2) {
|
|
32698
|
+
return typeof label2 === "string" && label2.trim() !== "" ? label2 : MEDIA_FIELD_DEFAULT_LABEL;
|
|
32699
|
+
}
|
|
32700
|
+
function mediaFieldState(uploading, hasPhoto, failed2 = false) {
|
|
32701
|
+
if (uploading) return "Uploading";
|
|
32702
|
+
if (failed2) return MEDIA_FIELD_UPLOAD_FAILED;
|
|
32703
|
+
return hasPhoto ? "Photo added" : void 0;
|
|
32704
|
+
}
|
|
32705
|
+
function mediaFieldServicePath(valuePath) {
|
|
32706
|
+
if (typeof valuePath !== "string" || !valuePath.startsWith("$service:")) return null;
|
|
32707
|
+
const p = valuePath.slice("$service:".length);
|
|
32708
|
+
return p === "" ? null : p;
|
|
32709
|
+
}
|
|
32710
|
+
function mediaFieldFileName(sizeBytes, mimeType) {
|
|
32711
|
+
const ext = /png/i.test(mimeType) ? "png" : /gif/i.test(mimeType) ? "gif" : /webp/i.test(mimeType) ? "webp" : /hei[cf]/i.test(mimeType) ? "heic" : "jpg";
|
|
32712
|
+
return `photo-${Math.max(0, Math.floor(sizeBytes))}.${ext}`;
|
|
32713
|
+
}
|
|
32714
|
+
function isMediaFieldUploadTarget(url) {
|
|
32715
|
+
return typeof url === "string" && isPresignedUploadTarget(url);
|
|
32716
|
+
}
|
|
32717
|
+
async function runMediaFieldUpload(o) {
|
|
32718
|
+
const { uploadService: svc, file, deps } = o;
|
|
32719
|
+
if (!svc) return { ok: false, reason: "no_service" };
|
|
32720
|
+
const t = deps.timers ?? { setTimeout: (fn, ms) => setTimeout(fn, ms), clearTimeout: (h) => clearTimeout(h) };
|
|
32721
|
+
const controller = typeof AbortController === "function" ? new AbortController() : null;
|
|
32722
|
+
let expired = false;
|
|
32723
|
+
let onExpire = [];
|
|
32724
|
+
const timer = t.setTimeout(() => {
|
|
32725
|
+
expired = true;
|
|
32726
|
+
controller?.abort();
|
|
32727
|
+
for (const fn of onExpire) fn();
|
|
32728
|
+
onExpire = [];
|
|
32729
|
+
}, o.timeoutMs ?? MEDIA_FIELD_UPLOAD_TIMEOUT_MS);
|
|
32730
|
+
const bounded2 = (p) => {
|
|
32731
|
+
if (expired) return Promise.reject(new Deadline());
|
|
32732
|
+
return new Promise((resolve57, reject) => {
|
|
32733
|
+
const stop = () => reject(new Deadline());
|
|
32734
|
+
onExpire.push(stop);
|
|
32735
|
+
p.then(resolve57, reject).finally(() => {
|
|
32736
|
+
onExpire = onExpire.filter((f) => f !== stop);
|
|
32737
|
+
});
|
|
32738
|
+
});
|
|
32739
|
+
};
|
|
32740
|
+
const dispatchedAs = async (action) => {
|
|
32741
|
+
try {
|
|
32742
|
+
const r = deps.dispatch(action);
|
|
32743
|
+
if (r && typeof r.then === "function") {
|
|
32744
|
+
const v = await bounded2(Promise.resolve(r));
|
|
32745
|
+
return v === null ? "rejected" : "settled";
|
|
32746
|
+
}
|
|
32747
|
+
return "unknown";
|
|
32748
|
+
} catch {
|
|
32749
|
+
return "rejected";
|
|
32750
|
+
}
|
|
32751
|
+
};
|
|
32752
|
+
const dispatched = async (action) => await dispatchedAs(action) !== "rejected";
|
|
32753
|
+
try {
|
|
32754
|
+
const urlPath = `${svc}.uploadUrl`;
|
|
32755
|
+
const before = deps.value(urlPath);
|
|
32756
|
+
let uploadUrl;
|
|
32757
|
+
try {
|
|
32758
|
+
uploadUrl = await bounded2(new Promise((resolve57, reject) => {
|
|
32759
|
+
let done = false;
|
|
32760
|
+
let unsub = () => {
|
|
32761
|
+
};
|
|
32762
|
+
unsub = deps.subscribe(urlPath, (v) => {
|
|
32763
|
+
if (done || typeof v !== "string" || v === "" || v === before) return;
|
|
32764
|
+
done = true;
|
|
32765
|
+
queueMicrotask(() => unsub());
|
|
32766
|
+
resolve57(v);
|
|
32767
|
+
});
|
|
32768
|
+
onExpire.push(() => {
|
|
32769
|
+
if (!done) {
|
|
32770
|
+
done = true;
|
|
32771
|
+
queueMicrotask(() => unsub());
|
|
32772
|
+
}
|
|
32773
|
+
});
|
|
32774
|
+
void dispatchedAs({ actionId: `tier5.${svc}.genUpload`, args: { fileName: file.fileName, mimeType: file.mimeType } }).then((how) => {
|
|
32775
|
+
if (done || how === "unknown") return;
|
|
32776
|
+
if (how === "settled") {
|
|
32777
|
+
const now = deps.value(urlPath);
|
|
32778
|
+
if (typeof now === "string" && now !== "" && now !== before) {
|
|
32779
|
+
done = true;
|
|
32780
|
+
queueMicrotask(() => unsub());
|
|
32781
|
+
resolve57(now);
|
|
32782
|
+
return;
|
|
32783
|
+
}
|
|
32784
|
+
}
|
|
32785
|
+
done = true;
|
|
32786
|
+
queueMicrotask(() => unsub());
|
|
32787
|
+
reject(new ActionRejected());
|
|
32788
|
+
});
|
|
32789
|
+
}));
|
|
32790
|
+
} catch (e) {
|
|
32791
|
+
return { ok: false, reason: e instanceof ActionRejected ? "gen_upload" : "timeout" };
|
|
32792
|
+
}
|
|
32793
|
+
if (!isMediaFieldUploadTarget(uploadUrl)) return { ok: false, reason: "bad_target" };
|
|
32794
|
+
let body;
|
|
32795
|
+
try {
|
|
32796
|
+
body = await bounded2(Promise.resolve(typeof file.body === "function" ? file.body() : file.body));
|
|
32797
|
+
} catch (e) {
|
|
32798
|
+
return { ok: false, reason: e instanceof Deadline ? "timeout" : "read" };
|
|
32799
|
+
}
|
|
32800
|
+
const sep19 = uploadUrl.includes("?") ? "&" : "?";
|
|
32801
|
+
let res;
|
|
32802
|
+
try {
|
|
32803
|
+
res = await bounded2(deps.fetch(`${uploadUrl}${sep19}filename=${encodeURIComponent(file.fileName)}`, {
|
|
32804
|
+
method: "PUT",
|
|
32805
|
+
headers: { "Content-Type": file.mimeType },
|
|
32806
|
+
body,
|
|
32807
|
+
...controller ? { signal: controller.signal } : {}
|
|
32808
|
+
}));
|
|
32809
|
+
} catch (e) {
|
|
32810
|
+
return { ok: false, reason: e instanceof Deadline || expired ? "timeout" : "put" };
|
|
32811
|
+
}
|
|
32812
|
+
if (!res.ok) return { ok: false, reason: "put" };
|
|
32813
|
+
let json6;
|
|
32814
|
+
try {
|
|
32815
|
+
json6 = await bounded2(res.json());
|
|
32816
|
+
} catch (e) {
|
|
32817
|
+
return { ok: false, reason: e instanceof Deadline || expired ? "timeout" : "bad_descriptor" };
|
|
32818
|
+
}
|
|
32819
|
+
const root = json6 && typeof json6 === "object" ? json6 : {};
|
|
32820
|
+
const d = root.file && typeof root.file === "object" ? root.file : root;
|
|
32821
|
+
const mediaId = typeof d.id === "string" ? d.id : "";
|
|
32822
|
+
if (!mediaId) return { ok: false, reason: "bad_descriptor" };
|
|
32823
|
+
const imageUrl = typeof d.url === "string" ? d.url : "";
|
|
32824
|
+
if (!await dispatched({ actionId: `tier5.${svc}.setMedia`, args: { mediaId, imageUrl } })) return { ok: false, reason: "set_media" };
|
|
32825
|
+
return { ok: true, mediaId, imageUrl };
|
|
32826
|
+
} finally {
|
|
32827
|
+
t.clearTimeout(timer);
|
|
32828
|
+
onExpire = [];
|
|
32829
|
+
}
|
|
32830
|
+
}
|
|
32831
|
+
var MEDIA_FIELD_DEFAULT_LABEL, MEDIA_FIELD_UPLOAD_TIMEOUT_MS, MEDIA_FIELD_UPLOAD_FAILED, Deadline, ActionRejected;
|
|
32832
|
+
var init_mediaFieldUpload = __esm({
|
|
32833
|
+
"../../core/web-renderer/src/mediaFieldUpload.ts"() {
|
|
32834
|
+
init_presigned_upload_policy();
|
|
32835
|
+
MEDIA_FIELD_DEFAULT_LABEL = "Add a photo";
|
|
32836
|
+
MEDIA_FIELD_UPLOAD_TIMEOUT_MS = 3e4;
|
|
32837
|
+
MEDIA_FIELD_UPLOAD_FAILED = "Upload failed";
|
|
32838
|
+
Deadline = class extends Error {
|
|
32839
|
+
};
|
|
32840
|
+
ActionRejected = class extends Error {
|
|
32841
|
+
};
|
|
32842
|
+
}
|
|
32843
|
+
});
|
|
32844
|
+
|
|
32631
32845
|
// ../../core/web-renderer/src/pdfSource.ts
|
|
32632
32846
|
function pdfEmbedPlan(url, pageOrigin = currentOrigin()) {
|
|
32633
32847
|
const target = classifyEmbedUrl(url, pageOrigin);
|
|
@@ -35832,9 +36046,10 @@ function renderInner(node, ctx) {
|
|
|
35832
36046
|
return /* @__PURE__ */ jsx8(IconNode, { props, ctx, wrap });
|
|
35833
36047
|
case "Button":
|
|
35834
36048
|
return /* @__PURE__ */ jsx8(ButtonNode, { props, ctx, wrap });
|
|
36049
|
+
case "MediaField":
|
|
36050
|
+
return /* @__PURE__ */ jsx8(MediaFieldNode, { props, ctx, wrap });
|
|
35835
36051
|
case "TextField":
|
|
35836
36052
|
case "RichTextField":
|
|
35837
|
-
case "MediaField":
|
|
35838
36053
|
return /* @__PURE__ */ jsx8(EditableField, { props, ctx, wrap, multiline: type === "RichTextField" });
|
|
35839
36054
|
case "Toggle":
|
|
35840
36055
|
return /* @__PURE__ */ jsx8(ToggleNode, { props, ctx, wrap });
|
|
@@ -36214,7 +36429,7 @@ function renderInner(node, ctx) {
|
|
|
36214
36429
|
}
|
|
36215
36430
|
}
|
|
36216
36431
|
}
|
|
36217
|
-
var useIsomorphicLayoutEffect, ResponsiveGrid, SPLIT_EXPANDED_MIN_WIDTH, SPLIT_COLUMN_GAP, ResponsiveSplitView, ABSOLUTE_URL_RE, appearKeyframesInjected, pressStylesInjected, FOCUS_RING_CSS, focusStylesInjected, HLIST_CHILD_CSS, hListStylesInjected, listAnimateRuntimeInstalled, transitionKeyframesInjected, countUpRuntimeInjected, MEASURE_PREFIX, measureRuntimeInjected, revealRuntimeInjected, vectorAnimStylesInjected, scrollProgressRuntimeInjected, confettiRuntimeInjected, lottieRuntimeInjected, riveRuntimeInjected, gradientKeyframesInjected, parallaxRuntimeInjected, spinKeyframesInjected, marqueeKeyframesInjected, alignItems, zJustifyItems, hAlignItems, bodyFont, kids2, rowKidCtx, rowKids, staggeredKids, asTextL10n, asBoundText, useBoundString, InterpolatedTextView, txt, selectFragmentCase, fragmentValueHash, fragmentSlotContent, FragmentSlotNode, RichContentEditorNode, WorkerSubtreeNode, RichContentNode, resolveItemDeep2, resolveSwipeActions, resolveModBindings, resolvedComponentId, directServiceBindings, withRootStyle, ReactiveDirectScalars, HiddenGate, KEYBOARD_INPUT_MODES, AUTOCAPITALIZE_VALUES, ENTER_KEY_HINTS, AUTOGROW_CEILING, EditableField, MenuNode, LoadMoreSentinel, FieldErrorNode, FormView, MediaSlotProvider, MEDIA_ITEM_BINDABLE, MediaPlayerView, VideoNode, PdfViewNode, WebViewNode, InteractivePicker, InteractiveDatePicker, InteractiveSearchField, InteractiveStepper, SYNTHETIC_TAP_ROLE, SYNTHETIC_TABINDEX, INFERRED_DECORATIVE, SELF_RENDERED_LEAF, ROLE_WHEN_NAMED, AUTHORED_ROLE, PENDING_RANGE, RANGE_ROLES, NODE_A11Y_ATTRS, INTERACTIVE_ROLES, ALWAYS_INTERACTIVE_COMPONENT_TYPES, controlNode, ToggleNode, SliderNode, SelectionControlNode, TabsNode, SegmentedControlNode, DisclosureGroupNode, GridNode, SplitViewNode, TextNode, ImageNode, ANIMATION_LEAF, LottieNode, RiveNode, AvatarNode, IconNode, ButtonNode, OtpInputNode, ProgressBarNode, ACTIVITY_DEFAULT_NAME, ActivityIndicatorNode, NATIVELY_TABBABLE, BottomSheetNode, PRESENTED_OVERLAY_ATTR, PopoverNode, ChipsInputNode, ChipNode, TableNode, GaugeRing, GaugeNode, RATING_METRICS, ratingMetrics, RatingNode, AvatarStripNode, CHART_STROKE_CYCLE, chartStrokeAt, chartBarCenter, ChartNode, donutSliceOpacity, DonutChartNode, LegendMarker, LegendNode, cellAlign, DataTableNode, voiceNoteState, voiceNoteDelivery, VOICE_NOTE_DEFAULT_BARS, clampBarCount, VoiceNoteNode, TimelineNode, WheelPickerNode, ColorPickerNode, FilterChipsNode, TILE_PX, MAX_MERCATOR_LAT, DEFAULT_TILE_MAX_ZOOM, CIRCLE_SEGMENTS, METRES_PER_DEG_LAT, MARKER_HIT_RADIUS, SHAPE_HIT_RADIUS, MapNode, CollapsingHeaderNode, UnsupportedOnSurface, CALENDAR_DATE_ONLY_RE, CAL_DEFAULT_MAX_DOTS, CAL_AGENDA_INITIAL_DAYS, CAL_AGENDA_PAGE_DAYS, CAL_DEFAULT_SNAP_MINUTES, CAL_UNASSIGNED_LANE_ID, MonthCalendarNode, TimeGridNode, AgendaNode, ARIA_ROLE, initialFocusScheduled, PRESENTED_SCOPE, focusRoots, A11yHintDescription, WebRenderer;
|
|
36432
|
+
var useIsomorphicLayoutEffect, ResponsiveGrid, SPLIT_EXPANDED_MIN_WIDTH, SPLIT_COLUMN_GAP, ResponsiveSplitView, ABSOLUTE_URL_RE, appearKeyframesInjected, pressStylesInjected, FOCUS_RING_CSS, focusStylesInjected, HLIST_CHILD_CSS, hListStylesInjected, listAnimateRuntimeInstalled, transitionKeyframesInjected, countUpRuntimeInjected, MEASURE_PREFIX, measureRuntimeInjected, revealRuntimeInjected, vectorAnimStylesInjected, scrollProgressRuntimeInjected, confettiRuntimeInjected, lottieRuntimeInjected, riveRuntimeInjected, gradientKeyframesInjected, parallaxRuntimeInjected, spinKeyframesInjected, marqueeKeyframesInjected, alignItems, zJustifyItems, hAlignItems, bodyFont, kids2, rowKidCtx, rowKids, staggeredKids, asTextL10n, asFinalTextL10n, asBoundText, useBoundString, InterpolatedTextView, txt, selectFragmentCase, fragmentValueHash, fragmentSlotContent, FragmentSlotNode, RichContentEditorNode, MediaFieldNode, WorkerSubtreeNode, RichContentNode, resolveItemDeep2, resolveSwipeActions, resolveModBindings, resolvedComponentId, directServiceBindings, withRootStyle, ReactiveDirectScalars, HiddenGate, KEYBOARD_INPUT_MODES, AUTOCAPITALIZE_VALUES, ENTER_KEY_HINTS, AUTOGROW_CEILING, EditableField, MenuNode, LoadMoreSentinel, FieldErrorNode, FormView, MediaSlotProvider, MEDIA_ITEM_BINDABLE, MediaPlayerView, VideoNode, PdfViewNode, WebViewNode, InteractivePicker, InteractiveDatePicker, InteractiveSearchField, InteractiveStepper, SYNTHETIC_TAP_ROLE, SYNTHETIC_TABINDEX, INFERRED_DECORATIVE, SELF_RENDERED_LEAF, ROLE_WHEN_NAMED, AUTHORED_ROLE, PENDING_RANGE, RANGE_ROLES, NODE_A11Y_ATTRS, INTERACTIVE_ROLES, ALWAYS_INTERACTIVE_COMPONENT_TYPES, controlNode, ToggleNode, SliderNode, SelectionControlNode, TabsNode, SegmentedControlNode, DisclosureGroupNode, GridNode, SplitViewNode, TextNode, ImageNode, ANIMATION_LEAF, LottieNode, RiveNode, AvatarNode, IconNode, ButtonNode, OtpInputNode, ProgressBarNode, ACTIVITY_DEFAULT_NAME, ActivityIndicatorNode, NATIVELY_TABBABLE, BottomSheetNode, PRESENTED_OVERLAY_ATTR, PopoverNode, ChipsInputNode, ChipNode, TableNode, GaugeRing, GaugeNode, RATING_METRICS, ratingMetrics, RatingNode, AvatarStripNode, CHART_STROKE_CYCLE, chartStrokeAt, chartBarCenter, ChartNode, donutSliceOpacity, DonutChartNode, LegendMarker, LegendNode, cellAlign, DataTableNode, voiceNoteState, voiceNoteDelivery, VOICE_NOTE_DEFAULT_BARS, clampBarCount, VoiceNoteNode, TimelineNode, WheelPickerNode, ColorPickerNode, FilterChipsNode, TILE_PX, MAX_MERCATOR_LAT, DEFAULT_TILE_MAX_ZOOM, CIRCLE_SEGMENTS, METRES_PER_DEG_LAT, MARKER_HIT_RADIUS, SHAPE_HIT_RADIUS, MapNode, CollapsingHeaderNode, UnsupportedOnSurface, CALENDAR_DATE_ONLY_RE, CAL_DEFAULT_MAX_DOTS, CAL_AGENDA_INITIAL_DAYS, CAL_AGENDA_PAGE_DAYS, CAL_DEFAULT_SNAP_MINUTES, CAL_UNASSIGNED_LANE_ID, MonthCalendarNode, TimeGridNode, AgendaNode, ARIA_ROLE, initialFocusScheduled, PRESENTED_SCOPE, focusRoots, A11yHintDescription, WebRenderer;
|
|
36218
36433
|
var init_renderNode = __esm({
|
|
36219
36434
|
"../../core/web-renderer/src/renderNode.tsx"() {
|
|
36220
36435
|
"use strict";
|
|
@@ -36233,6 +36448,7 @@ var init_renderNode = __esm({
|
|
|
36233
36448
|
init_icons();
|
|
36234
36449
|
init_webviewFrame();
|
|
36235
36450
|
init_richContentEditor();
|
|
36451
|
+
init_mediaFieldUpload();
|
|
36236
36452
|
init_pdfSource();
|
|
36237
36453
|
init_icon_catalog_generated();
|
|
36238
36454
|
init_controls();
|
|
@@ -36369,6 +36585,7 @@ var init_renderNode = __esm({
|
|
|
36369
36585
|
return React7.cloneElement(el, { key: n?.id ?? i, style: { ...prev, animationDelay: `${i * staggerMs}ms` } });
|
|
36370
36586
|
}) : null;
|
|
36371
36587
|
asTextL10n = (v, ctx) => typeof v === "string" && v.startsWith(TRANSLATION_PREFIX) ? asText2(resolveTranslation(v, ctx.catalog)) : asText2(v);
|
|
36588
|
+
asFinalTextL10n = (v, ctx) => typeof v === "string" ? v.startsWith(TRANSLATION_PREFIX) ? asText2(resolveTranslation(v, ctx.catalog)) : v : asText2(v);
|
|
36372
36589
|
asBoundText = (v, ctx) => isBinding(v) ? asTextL10n(resolveScalarStatic(v, ctx) ?? "", ctx) : asText2(v);
|
|
36373
36590
|
useBoundString = (v, ctx) => {
|
|
36374
36591
|
const resolved2 = useResolvedScalar(v, ctx);
|
|
@@ -36471,6 +36688,78 @@ var init_renderNode = __esm({
|
|
|
36471
36688
|
return fragmentSlotContent({ props, ctx, discriminator, slotId: nodeId, extra: wrap });
|
|
36472
36689
|
});
|
|
36473
36690
|
RichContentEditorNode = withExtras("RichContentEditorNode", ({ props, ctx, wrap, nodeId }) => /* @__PURE__ */ jsx8(RichContentEditorView, { props, ctx, wrap, nodeId, renderChild: (n) => renderNode(n, ctx) }));
|
|
36691
|
+
MediaFieldNode = withExtras("MediaFieldNode", ({ props, ctx, wrap }) => {
|
|
36692
|
+
const C = ctx.color;
|
|
36693
|
+
const servicePathStr = mediaFieldServicePath(props.valuePath);
|
|
36694
|
+
const bound = useBoundValue(ctx, servicePathStr ? String(props.valuePath) : "");
|
|
36695
|
+
const imageUrl = typeof bound === "string" ? bound : "";
|
|
36696
|
+
const [uploading, setUploading] = React7.useState(false);
|
|
36697
|
+
const [failed2, setFailed] = React7.useState(false);
|
|
36698
|
+
const fileRef = React7.useRef(null);
|
|
36699
|
+
const uploadService = typeof props.uploadService === "string" ? props.uploadService : "";
|
|
36700
|
+
const resolvedLabel = asText2(resolveScalarStatic(props.label, ctx));
|
|
36701
|
+
const name = mediaFieldName(resolvedLabel);
|
|
36702
|
+
const state = mediaFieldState(uploading, imageUrl !== "", failed2);
|
|
36703
|
+
const open = () => {
|
|
36704
|
+
if (!uploading) fileRef.current?.click();
|
|
36705
|
+
};
|
|
36706
|
+
const onPick = async (e) => {
|
|
36707
|
+
const input = e.currentTarget;
|
|
36708
|
+
const file = input.files?.[0];
|
|
36709
|
+
input.value = "";
|
|
36710
|
+
if (!file || !ctx.onAction || !ctx.provider || !uploadService) return;
|
|
36711
|
+
const provider = ctx.provider;
|
|
36712
|
+
const mimeType = file.type || "image/jpeg";
|
|
36713
|
+
setUploading(true);
|
|
36714
|
+
setFailed(false);
|
|
36715
|
+
try {
|
|
36716
|
+
const r = await runMediaFieldUpload({
|
|
36717
|
+
uploadService,
|
|
36718
|
+
file: { mimeType, fileName: mediaFieldFileName(file.size, mimeType), body: file },
|
|
36719
|
+
deps: {
|
|
36720
|
+
dispatch: (action) => ctx.onAction?.(action),
|
|
36721
|
+
value: (p) => provider.value(p),
|
|
36722
|
+
subscribe: (p, cb) => provider.subscribe(p, cb),
|
|
36723
|
+
fetch: (url, init) => fetch(url, init)
|
|
36724
|
+
}
|
|
36725
|
+
});
|
|
36726
|
+
if (!r.ok) setFailed(true);
|
|
36727
|
+
} catch {
|
|
36728
|
+
setFailed(true);
|
|
36729
|
+
} finally {
|
|
36730
|
+
setUploading(false);
|
|
36731
|
+
}
|
|
36732
|
+
};
|
|
36733
|
+
const f = ctx.font("bodyEmphasis");
|
|
36734
|
+
const radius = 12;
|
|
36735
|
+
return /* @__PURE__ */ jsxs5(
|
|
36736
|
+
"div",
|
|
36737
|
+
{
|
|
36738
|
+
role: "button",
|
|
36739
|
+
tabIndex: 0,
|
|
36740
|
+
"aria-label": state ? `${name}, ${state}` : name,
|
|
36741
|
+
"aria-busy": uploading || void 0,
|
|
36742
|
+
"data-media-service": uploadService,
|
|
36743
|
+
onClick: open,
|
|
36744
|
+
onKeyDown: (e) => {
|
|
36745
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
36746
|
+
e.preventDefault();
|
|
36747
|
+
open();
|
|
36748
|
+
}
|
|
36749
|
+
},
|
|
36750
|
+
style: { position: "relative", display: "flex", alignItems: "center", justifyContent: "center", width: "100%", height: 160, borderRadius: radius, overflow: "hidden", background: C("surfaceSecondary", "#F2F3F5"), cursor: "pointer", boxSizing: "border-box", ...wrap },
|
|
36751
|
+
children: [
|
|
36752
|
+
/* @__PURE__ */ jsx8("input", { ref: fileRef, type: "file", accept: "image/*", tabIndex: -1, "aria-hidden": "true", onChange: onPick, onClick: (e) => e.stopPropagation(), style: { display: "none" } }),
|
|
36753
|
+
imageUrl ? /* @__PURE__ */ jsx8("img", { src: resolveAssetUrl(imageUrl, ctx.assetBaseUrl), alt: "", "aria-hidden": "true", style: { position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover", display: "block" } }) : /* @__PURE__ */ jsxs5("div", { "aria-hidden": "true", style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 8, color: accentTextColor(ctx) }, children: [
|
|
36754
|
+
iconSvg("camera", { size: 28, color: accentTextColor(ctx) }),
|
|
36755
|
+
/* @__PURE__ */ jsx8("span", { style: { fontFamily: fontStack(f.family, ctx.idiom), fontWeight: f.weight, fontSize: f.remSize }, children: name })
|
|
36756
|
+
] }),
|
|
36757
|
+
uploading ? /* @__PURE__ */ jsx8("div", { "aria-hidden": "true", "data-media-uploading": "true", style: { position: "absolute", inset: 0, background: "rgba(0,0,0,0.35)" } }) : null,
|
|
36758
|
+
failed2 && !uploading ? /* @__PURE__ */ jsx8("span", { "aria-hidden": "true", "data-media-upload-error": "true", style: { position: "absolute", left: 8, right: 8, bottom: 8, textAlign: "center", fontSize: pxToRem(13), color: C("danger", "#E62214") }, children: MEDIA_FIELD_UPLOAD_FAILED }) : null
|
|
36759
|
+
]
|
|
36760
|
+
}
|
|
36761
|
+
);
|
|
36762
|
+
});
|
|
36474
36763
|
WorkerSubtreeNode = withExtras("WorkerSubtreeNode", ({ props, ctx, wrap, nodeId }) => {
|
|
36475
36764
|
const slotId = nodeId;
|
|
36476
36765
|
const extra = wrap;
|
|
@@ -36690,12 +36979,20 @@ var init_renderNode = __esm({
|
|
|
36690
36979
|
() => ctx.catalog ? new Proxy({}, { get: (_t, k) => typeof k === "string" ? ctx.catalog.get(k) : void 0 }) : void 0,
|
|
36691
36980
|
[ctx.catalog]
|
|
36692
36981
|
);
|
|
36693
|
-
const
|
|
36694
|
-
const
|
|
36695
|
-
const
|
|
36982
|
+
const translateOnly = (v) => asFinalTextL10n(v, ctx);
|
|
36983
|
+
const ruleMessageRaw = typeof rule?.message === "string" || rule?.message !== null && typeof rule?.message === "object" ? rule?.message : void 0;
|
|
36984
|
+
const ruleMessageBound = typeof ruleMessageRaw === "string" && isBinding(ruleMessageRaw) && !ruleMessageRaw.startsWith(TRANSLATION_PREFIX);
|
|
36985
|
+
const ruleMessageResolved = useResolvedScalar(ruleMessageBound ? ruleMessageRaw : void 0, ctx);
|
|
36986
|
+
const ruleMessageText = ruleMessageRaw == null ? "" : ruleMessageBound ? ruleMessageResolved == null ? "" : translateOnly(ruleMessageResolved) : translateOnly(ruleMessageRaw);
|
|
36987
|
+
const ruleMessagePending = ruleMessageBound && !ruleMessageText.trim() && ruleMessageRaw.startsWith("$service:") && !!ctx.provider && !(formBag?.submitAttempted ?? false);
|
|
36988
|
+
const effectiveRule = !rule || ruleMessageRaw == null ? rule : { ...rule, message: ruleMessageText };
|
|
36989
|
+
const rawMessage = errorMessageFor({ rule: effectiveRule, value: local, workerError, catalog: validationCatalog });
|
|
36990
|
+
const hasWorkerError = Boolean(workerError && workerError.trim());
|
|
36991
|
+
const painted2 = rawMessage === null ? "" : translateOnly(rawMessage);
|
|
36992
|
+
const message = !painted2.trim() || ruleMessagePending && !hasWorkerError ? null : painted2;
|
|
36696
36993
|
const revealed = message !== null && shouldRevealError({
|
|
36697
36994
|
rule,
|
|
36698
|
-
hasWorkerError
|
|
36995
|
+
hasWorkerError,
|
|
36699
36996
|
touched,
|
|
36700
36997
|
focused: isFocused,
|
|
36701
36998
|
submitAttempted: formBag?.submitAttempted ?? false
|
|
@@ -40401,6 +40698,10 @@ function buildRenderTree(node, path2 = "$", provider = null, itemScope = void 0,
|
|
|
40401
40698
|
}
|
|
40402
40699
|
}
|
|
40403
40700
|
if (type === "OtpInput" && props.secure === true) delete values.value;
|
|
40701
|
+
if (type === "MediaField" && typeof props.valuePath === "string" && props.valuePath.startsWith("$service:")) {
|
|
40702
|
+
const photo = resolveTreeScalar(props.valuePath, provider, itemScope);
|
|
40703
|
+
if (typeof photo === "string" && photo !== "") delete values.label;
|
|
40704
|
+
}
|
|
40404
40705
|
collectComponentMediaValues(type, props, { provider, itemScope, values, insideMediaProperty: false });
|
|
40405
40706
|
collectResolvedMediaValues(modifiers, "modifiers", {
|
|
40406
40707
|
provider,
|
|
@@ -56151,8 +56452,8 @@ function allowed(url, declared) {
|
|
|
56151
56452
|
if (declaredPort !== void 0 && (!/^\d+$/.test(declaredPort) || Number(declaredPort) > 65535)) return false;
|
|
56152
56453
|
const defaultPort = url.protocol === "https:" ? "443" : "80";
|
|
56153
56454
|
const portMatches = declaredPort !== void 0 ? String(Number(declaredPort)) === actualPort : actualPort === defaultPort;
|
|
56154
|
-
const
|
|
56155
|
-
return portMatches &&
|
|
56455
|
+
const hostMatches2 = wildcard ? value !== normalized && value.endsWith(`.${normalized}`) : value === normalized || value.endsWith(`.${normalized}`);
|
|
56456
|
+
return portMatches && hostMatches2;
|
|
56156
56457
|
});
|
|
56157
56458
|
}
|
|
56158
56459
|
function ipv4Private(address) {
|
|
@@ -61368,21 +61669,21 @@ var init_preview_assets_generated = __esm({
|
|
|
61368
61669
|
"../../packages/serve/src/preview-assets.generated.ts"() {
|
|
61369
61670
|
init_preview_assets_format();
|
|
61370
61671
|
PREVIEW_ASSET_MANIFEST = [
|
|
61371
|
-
{ key: "assets/index-
|
|
61372
|
-
{ key: "fonts/Roboto-LICENSE.txt", contentType: "application/octet-stream", offset:
|
|
61373
|
-
{ key: "fonts/Roboto-Variable.ttf", contentType: "font/ttf", offset:
|
|
61374
|
-
{ key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset:
|
|
61375
|
-
{ key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset:
|
|
61376
|
-
{ key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset:
|
|
61377
|
-
{ key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset:
|
|
61378
|
-
{ key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset:
|
|
61379
|
-
{ key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset:
|
|
61380
|
-
{ key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset:
|
|
61381
|
-
{ key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset:
|
|
61382
|
-
{ key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset:
|
|
61383
|
-
{ key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset:
|
|
61384
|
-
{ key: "index.html", contentType: "text/html; charset=utf-8", offset:
|
|
61385
|
-
{ key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset:
|
|
61672
|
+
{ key: "assets/index-CPRJc_Hj.js", contentType: "application/javascript; charset=utf-8", offset: 8, length: 1145737, sha256: "5e9c570a5baa2ef39ccf2d357c78631a2d5f9190acfb01dcc77ccce17538457a" },
|
|
61673
|
+
{ key: "fonts/Roboto-LICENSE.txt", contentType: "application/octet-stream", offset: 1145745, length: 4610, sha256: "994062dd7af4186a739de55dd9e151c63b6301f8e2cbafc608d35c2e87da0cd2" },
|
|
61674
|
+
{ key: "fonts/Roboto-Variable.ttf", contentType: "font/ttf", offset: 1150355, length: 488584, sha256: "d7598e12c5dbef095ff8272cfc55da0250bd07fbdecbac8a530b9b277872a134" },
|
|
61675
|
+
{ key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset: 1638939, length: 90924, sha256: "ec4c7d63772d980d6e147b2df6215fd2737e4b04cebe0cf7e11dc695fb63cdcf" },
|
|
61676
|
+
{ key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset: 1729863, length: 90984, sha256: "bf4c16a2774edd38a921edf3099469866cd74c094fd596f3fa4e81f54a04dfaa" },
|
|
61677
|
+
{ key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset: 1820847, length: 90980, sha256: "368faca44fb9f7207e4af784e94750b1ee59c1098b8689e0f4a918926f244fb5" },
|
|
61678
|
+
{ key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset: 1911827, length: 90872, sha256: "97ed8f1a6772abe26e3d8af5cecfc4b02faa94497d585b0398b5053b739a70c1" },
|
|
61679
|
+
{ key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset: 2002699, length: 90980, sha256: "642feab8a48ddf6c7a89d7c2a7c0edfa0e6e773f671287e460e222703563191e" },
|
|
61680
|
+
{ key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset: 2093679, length: 108636, sha256: "37c179b4fefb63ea9637322b84583a2df53aa226c150294eea1675c14b1b8e29" },
|
|
61681
|
+
{ key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset: 2202315, length: 109084, sha256: "62e2fe4718129f36ecdb0ae4de385bd6b81ecc876146447167c6c140fad699a9" },
|
|
61682
|
+
{ key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset: 2311399, length: 109048, sha256: "4ecf270136af928612c76fe4ebade91d8156975e5ea4c0cf9225501dd1788e02" },
|
|
61683
|
+
{ key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset: 2420447, length: 107700, sha256: "dee56f09fd3efc127c1ea95557edc74110c1460a46287da36e0af25efd341ef5" },
|
|
61684
|
+
{ key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset: 2528147, length: 88108, sha256: "dced97a77624bc5f8b1ae65850360908297f4588e09feb6f22792d29dc7e765b" },
|
|
61685
|
+
{ key: "index.html", contentType: "text/html; charset=utf-8", offset: 2616255, length: 4947, sha256: "20678191da952eca3f3fb8fb8b137db4cbb11dc84d0a8e59146cb669c5aa26b9" },
|
|
61686
|
+
{ key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset: 2621202, length: 17344, sha256: "d057298d75e7373e5e2c4d11b7d1bcbea88e03af555ba63d97641c78509c58e4" }
|
|
61386
61687
|
];
|
|
61387
61688
|
}
|
|
61388
61689
|
});
|
|
Binary file
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"_comment": "GENERATED by core/web-embed/authoring/gen-reference.mjs from core/ts/src/schema.ts — do not hand-edit. The schema is the source of truth; regenerate on schema changes.",
|
|
3
3
|
"schemaSource": "core/ts/src/schema.ts",
|
|
4
4
|
"bindingGrammar": "$service:<service>.<path> (worker state) · $item.<field> (list row) · $flag:<key> (feature flag) · $env:<key> (client environment — #1056). Bindings resolve in the text/value props marked 'binding-aware' below — INCLUDING Modifiers token refs — but only `background` and `border.color`, which are the two whose token a binding actually fills: a worker can drive per-item theming (e.g. a game board's per-square color), not just text. `shadow` is NOT binding-aware on any renderer, and a gradient is driven by its own `backgroundGradientPath` prop resolving to a gradient token NAME, not by a binding inside a token ref — so `shadow: { token: \"$item.x\" }` and `backgroundGradient: { token: \"$item.x\" }` keep the sentinel and silently lose the per-item styling. Colour slots split by LEVEL, not by component: inside modifiers a colour is a TokenRef OBJECT ({ token: \"…\" }), inside props it is a bare TokenName STRING — there is no modifiers.color or modifiers.tint (see the 'Token slots' section in component-reference.md). A few input props render the LITERAL and are NOT binding-aware — notably SearchField.placeholder and Chip.label; SearchField.value is live and binding-aware like other content props. Bindings also CANNOT target strict-enum fields (style, size, alignment, severity, presentation, contentMode, …) — those fail at render, not validation. $env: is client-resolved (no worker) and valid in modifiers.hiddenPath and FragmentSlot.casePath ONLY — keys reduceMotion/colorScheme/sizeClass/isRTL, e.g. hiddenPath:\"$env:reduceMotion\" or hiddenPath:\"$env:colorScheme==light\", casePath:\"$env:colorScheme\"; unknown key fails open (shown / defaultCase).",
|
|
5
|
-
"componentCount":
|
|
5
|
+
"componentCount": 85,
|
|
6
6
|
"notImplementedComponents": [
|
|
7
7
|
"Text",
|
|
8
8
|
"Carousel",
|
|
@@ -1057,6 +1057,15 @@
|
|
|
1057
1057
|
],
|
|
1058
1058
|
"propsSource": "export interface RichContentEditorProps {\n /** Form-bag key. Required inside a Form (validator). */\n name?: string;\n /** `$service:<svc>.<path>` → the document JSON string. Seeds ONCE (the first non-empty value). */\n documentPath?: string;\n /** Literal seed document JSON. At most one of documentPath / documentJson. */\n documentJson?: string;\n placeholder?: string;\n /** Empty ⇒ all, minus \"image\" unless uploadService is set. \"image\" requires uploadService. */\n tools?: RichContentEditorTool[];\n /** Debounced ≥ 500 ms; args = { dirty: \"true\" } — never the document. */\n onChange?: Action;\n /** Worker service made by `ricosUploadService` (@himalaya/wix-rich-content-editor). Enables \"image\". */\n uploadService?: string;\n /** Take the remaining height of a bounded parent; else `minHeight`. */\n fillAvailable?: boolean;\n /** Default 240. */\n minHeight?: number;\n /** Rendered when the engine page is unavailable (not bundled / missing / failed / 15 s timeout). */\n fallback?: Component;\n}"
|
|
1059
1059
|
},
|
|
1060
|
+
{
|
|
1061
|
+
"name": "MediaField",
|
|
1062
|
+
"category": "Image well + Wix Media upload (#3744)",
|
|
1063
|
+
"propsType": "MediaFieldProps",
|
|
1064
|
+
"bindings": [
|
|
1065
|
+
"valuePath"
|
|
1066
|
+
],
|
|
1067
|
+
"propsSource": "export interface MediaFieldProps {\n /** `$service:<svc>.<path>` → the current image URL; empty ⇒ the empty well with `label`. */\n valuePath: string;\n /** The worker service exposing `genUpload` / `setMedia` and the `uploadUrl` value. */\n uploadService: string;\n /** Empty-well copy (a message key or literal). Default \"Add a photo\". */\n label?: string;\n}"
|
|
1068
|
+
},
|
|
1060
1069
|
{
|
|
1061
1070
|
"name": "VoiceNote",
|
|
1062
1071
|
"category": "Recorded-audio bubble (messenger design G4)",
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
> GENERATED from `core/ts/src/schema.ts` by `core/web-embed/authoring/gen-reference.mjs`.
|
|
4
4
|
> The schema is the source of truth — regenerate on schema changes; do not hand-edit.
|
|
5
5
|
|
|
6
|
-
**
|
|
6
|
+
**85 core component types.** Every component body is `{ "package": "himalaya", "type": "<Type>", "props": { … } }`.
|
|
7
7
|
Binding grammar: `$service:<service>.<path>` (worker state) · `$item.<field>` (list row template) · `$flag:<key>` (feature flag) · `$env:<key>` (client environment — #1056).
|
|
8
8
|
Bindings resolve in the text/value props marked **binding-aware** below — **including two `Modifiers` token refs**, `background` and `border.color`, which are the only two whose token a binding actually fills: a worker can drive per-item **theming** (e.g. a game board's per-square color, `background: { token: "$item.bg" }`), not just text content. `shadow` and `backgroundGradient` are `TokenRef`s but are **not** binding-aware on any renderer — `shadow: { token: "$item.x" }` keeps the sentinel as a literal token name and silently loses the per-item styling, and a gradient is driven by its own `backgroundGradientPath` prop resolving to a gradient token NAME, not by a binding inside a token ref.
|
|
9
9
|
`$env:` is **client-resolved** (no worker) and valid in `modifiers.hiddenPath` and `FragmentSlot.casePath` **only** — keys `reduceMotion` / `colorScheme` / `sizeClass` / `isRTL`, with an optional `==`/`!=` comparison (e.g. `hiddenPath: "$env:reduceMotion"`, `hiddenPath: "$env:colorScheme==light"`, `casePath: "$env:colorScheme"`). An unknown key fails open (shown / `defaultCase`).
|
|
@@ -94,6 +94,7 @@ See also **[Modifiers](#modifiers)** (the `modifiers` block) and **[Actions](#ac
|
|
|
94
94
|
| `DataTable` | Analytics data-viz | `rowsPath`, `totalsPath` |
|
|
95
95
|
| `RichContent` | Rich content | `documentJsonPath` |
|
|
96
96
|
| `RichContentEditor` | Rich content editor | `documentPath` |
|
|
97
|
+
| `MediaField` | Image well + Wix Media upload (#3744) | `valuePath` |
|
|
97
98
|
| `VoiceNote` | Recorded-audio bubble (messenger design G4) | `waveformPath`, `durationMsPath`, `positionMsPath`, `statePath`, `deliveryPath`, `ratePath` |
|
|
98
99
|
| `Marquee` | Recorded-audio bubble (messenger design G4) | — |
|
|
99
100
|
| `Timeline` | Recorded-audio bubble (messenger design G4) | `entriesPath` |
|
|
@@ -116,7 +117,7 @@ See also **[Modifiers](#modifiers)** (the `modifiers` block) and **[Actions](#ac
|
|
|
116
117
|
|
|
117
118
|
These props are accepted by the schema and pass validation, but the named platform's renderer never reads them — they silently do nothing (no warning, no log). Prefer a prop NOT listed here, or drive the behaviour from a worker.
|
|
118
119
|
|
|
119
|
-
**Scope: 20 of
|
|
120
|
+
**Scope: 20 of 85 components, all of them web / android / ios-only** — every other component/platform pair reads every prop it decodes. The list splits in two, and the halves mean different things:
|
|
120
121
|
|
|
121
122
|
- **`category` (7: `Menu`, `Tooltip`, `Popover`, `ChipsInput`, `OtpInput`, `MediaPlayer`, `TimeGrid`)** — the prop changes the component's *kind*. These genuinely are **not implemented**: an overlay renders always-visible inline, so the component does not do the job its name implies. Check the row's note for a working alternative.
|
|
122
123
|
- **`styling` (13: `Text`, `Carousel`, `CollapsingHeader`, `Banner`, `Snackbar`, `WebView`, `Slider`, `SelectionControl`, `ActivityIndicator`, `Map`, `Video`, `PdfView`, `Agenda`)** — the component itself **works**; only the listed prop is inert. `Slider` on iOS is a working slider whose `debounceMs` does not throttle — not a broken `Slider`. Use the component; just do not depend on that one prop.
|
|
@@ -1667,6 +1668,21 @@ export interface RichContentEditorProps {
|
|
|
1667
1668
|
|
|
1668
1669
|
> ⚠️ **`onChange` on ios + android — DIVERGES:** renders `fallback` only — no editor exists yet, so nothing dispatches on_change. The editor has not reached these renderers yet, so they show the descriptor's `fallback`; the editor runs on the web and in React Native hosts that register its adapter.
|
|
1669
1670
|
|
|
1671
|
+
### Image well + Wix Media upload (#3744)
|
|
1672
|
+
|
|
1673
|
+
#### MediaField
|
|
1674
|
+
|
|
1675
|
+
```ts
|
|
1676
|
+
export interface MediaFieldProps {
|
|
1677
|
+
/** `$service:<svc>.<path>` → the current image URL; empty ⇒ the empty well with `label`. */
|
|
1678
|
+
valuePath: string;
|
|
1679
|
+
/** The worker service exposing `genUpload` / `setMedia` and the `uploadUrl` value. */
|
|
1680
|
+
uploadService: string;
|
|
1681
|
+
/** Empty-well copy (a message key or literal). Default "Add a photo". */
|
|
1682
|
+
label?: string;
|
|
1683
|
+
}
|
|
1684
|
+
```
|
|
1685
|
+
|
|
1670
1686
|
### Recorded-audio bubble (messenger design G4)
|
|
1671
1687
|
|
|
1672
1688
|
#### VoiceNote
|
package/guides/index.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_comment": "AUTO-GENERATED by tools/authoring-kit/bundle.mjs — DO NOT EDIT. Regenerate with: npm run authoring:gen",
|
|
3
3
|
"schemaStamp": {
|
|
4
|
-
"componentCount":
|
|
4
|
+
"componentCount": 85,
|
|
5
5
|
"schemaSource": "core/ts/src/schema.ts"
|
|
6
6
|
},
|
|
7
7
|
"portalUrl": "https://apps.wix.com/_api/himi-serve/docs",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/himalaya-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1203.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": "
|
|
70
|
+
"falconPackageHash": "36a72891777611eef63e609aa328947ea7a30540e4e0f9e4bc5e90ae"
|
|
71
71
|
}
|