@valbuild/react 0.101.1 → 0.103.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.
@@ -1,5 +1,5 @@
1
1
  import { RichTextNode as RichTextSourceNode, AllRichTextOptions, RichTextOptions, SelectorSource, Schema } from "@valbuild/core";
2
- import { CSSProperties, ReactNode } from "react";
2
+ import { CSSProperties, type JSX, ReactNode } from "react";
3
3
  import { RichText, StegaOfRichTextSource } from "../stega/index.js";
4
4
  type DefaultThemes = Partial<{
5
5
  br: string | null;
@@ -77,5 +77,5 @@ export declare function ValRichText<O extends RichTextOptions>({ className, styl
77
77
  children: RichText<O>;
78
78
  } | {
79
79
  content: RichText<O>;
80
- })): import("react/jsx-runtime").JSX.Element;
80
+ })): JSX.Element;
81
81
  export {};
@@ -1,2 +1,2 @@
1
- export function jsxDEV(type: any, props: any, key: any, isStaticChildren: any, source: any, self: any): any;
1
+ export function jsxDEV(type: any, props: any, key: any, isStaticChildren: any, source: any, self: any): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
2
2
  export * from "react/jsx-dev-runtime";
@@ -1,17 +1,20 @@
1
1
  import { Source, Val } from "@valbuild/core";
2
2
 
3
3
  // unpack all here to avoid infinite self-referencing when defining our own JSX namespace
4
- type ReactJSXElement = JSX.Element;
5
- type ReactJSXElementClass = JSX.ElementClass;
6
- type ReactJSXElementAttributesProperty = JSX.ElementAttributesProperty;
7
- type ReactJSXElementChildrenAttribute = JSX.ElementChildrenAttribute;
8
- type ReactJSXLibraryManagedAttributes<C, P> = JSX.LibraryManagedAttributes<
9
- C,
10
- P
11
- >;
12
- type ReactJSXIntrinsicAttributes = JSX.IntrinsicAttributes;
13
- type ReactJSXIntrinsicClassAttributes<T> = JSX.IntrinsicClassAttributes<T>;
14
- type ReactJSXIntrinsicElements = JSX.IntrinsicElements;
4
+ //
5
+ // `React.JSX` rather than the bare global `JSX`: @types/react 19 removed the
6
+ // global JSX namespace, so the only remaining declaration is the one on the
7
+ // react module itself.
8
+ type ReactJSXElement = React.JSX.Element;
9
+ type ReactJSXElementClass = React.JSX.ElementClass;
10
+ type ReactJSXElementAttributesProperty = React.JSX.ElementAttributesProperty;
11
+ type ReactJSXElementChildrenAttribute = React.JSX.ElementChildrenAttribute;
12
+ type ReactJSXLibraryManagedAttributes<C, P> =
13
+ React.JSX.LibraryManagedAttributes<C, P>;
14
+ type ReactJSXIntrinsicAttributes = React.JSX.IntrinsicAttributes;
15
+ type ReactJSXIntrinsicClassAttributes<T> =
16
+ React.JSX.IntrinsicClassAttributes<T>;
17
+ type ReactJSXIntrinsicElements = React.JSX.IntrinsicElements;
15
18
 
16
19
  type MaybeVal<T> = T extends Source ? Val<T> | T : T;
17
20
  type WithVal<T extends object> = {
@@ -1,4 +1,4 @@
1
- import { Json, RichTextSource, ImageMetadata, FileMetadata, RichTextOptions, ImageSource } from "@valbuild/core";
1
+ import { Json, RichTextSource, MediaHotspot, RichTextOptions, ImageSource } from "@valbuild/core";
2
2
  import { FileSource, Source, SourceObject } from "@valbuild/core";
3
3
  import { JsonPrimitive } from "@valbuild/core";
4
4
  import { SourceArray } from "@valbuild/core";
@@ -146,13 +146,25 @@ export type ValEncodedString = `${string}__VAL_ENCODED_STRING_INVISIBLE_CHARS` &
146
146
  length: never;
147
147
  [brand]: "ValEncodedString";
148
148
  };
149
+ /**
150
+ * An image as a consumer sees it: what was authored, plus the generated `url`.
151
+ *
152
+ * `path` stays a plain string — it is what `url` is derived from, so encoding it
153
+ * would corrupt every URL built from it.
154
+ */
149
155
  export type Image = {
156
+ readonly path: string;
150
157
  readonly url: ValEncodedString;
151
- readonly metadata?: ImageMetadata;
158
+ readonly width?: number;
159
+ readonly height?: number;
160
+ readonly mimeType?: string;
161
+ readonly alt?: string;
162
+ readonly hotspot?: MediaHotspot;
152
163
  };
153
- export type File<Metadata extends FileMetadata> = {
164
+ export type File = {
165
+ readonly path: string;
154
166
  readonly url: ValEncodedString;
155
- readonly metadata?: Metadata;
167
+ readonly mimeType?: string;
156
168
  };
157
169
  export type StegaOfRichTextSource<T extends Source> = Json extends T ? Json : T extends ImageSource ? Image : T extends SourceObject ? {
158
170
  [key in keyof T]: StegaOfRichTextSource<T[key]>;
@@ -163,7 +175,7 @@ export type StegaOfRichTextSource<T extends Source> = Json extends T ? Json : T
163
175
  export type RichText<O extends RichTextOptions> = StegaOfRichTextSource<RichTextSource<O>> & {
164
176
  readonly __brand?: "RichText";
165
177
  };
166
- export type StegaOfSource<T extends Source> = Json extends T ? Json : T extends RichTextSource<infer O> ? RichText<O> : T extends ImageSource ? Image : T extends FileSource<infer M> ? M extends FileMetadata ? File<M> : never : T extends SourceObject ? {
178
+ export type StegaOfSource<T extends Source> = Json extends T ? Json : T extends RichTextSource<infer O> ? RichText<O> : T extends ImageSource ? Image : T extends FileSource ? File : T extends SourceObject ? {
167
179
  [key in keyof T]: StegaOfSource<T[key]>;
168
180
  } : T extends SourceArray ? StegaOfSource<T[number]>[] : T extends RawString ? string : string extends T ? ValEncodedString : T extends JsonPrimitive ? T : never;
169
181
  export declare function stegaEncode(input: any, opts: {
@@ -149,6 +149,13 @@ function _toConsumableArray(r) {
149
149
  *
150
150
  */
151
151
 
152
+ /**
153
+ * An image as a consumer sees it: what was authored, plus the generated `url`.
154
+ *
155
+ * `path` stays a plain string — it is what `url` is derived from, so encoding it
156
+ * would corrupt every URL built from it.
157
+ */
158
+
152
159
  /**
153
160
  * RichText is accessible by users (after conversion via useVal / fetchVal)
154
161
  **/
@@ -206,6 +213,28 @@ function resolveLiteralUnionSchema(source, schema) {
206
213
  return matchingSchema || null;
207
214
  }
208
215
 
216
+ /**
217
+ * The image schema of a richtext's inline images.
218
+ *
219
+ * `inline.img` serializes as `true` when the author did not pass a schema, so
220
+ * there is nothing to hand down; a bare `{type: "image"}` is enough, since all
221
+ * the media branch needs is to know that it is looking at media.
222
+ */
223
+ function inlineImageSchemaOf(schema) {
224
+ var _schema$options;
225
+ if ((schema === null || schema === void 0 ? void 0 : schema.type) !== "richtext") {
226
+ return undefined;
227
+ }
228
+ var img = (_schema$options = schema.options) === null || _schema$options === void 0 || (_schema$options = _schema$options.inline) === null || _schema$options === void 0 ? void 0 : _schema$options.img;
229
+ if (!img) {
230
+ return undefined;
231
+ }
232
+ return img === true ? {
233
+ type: "image",
234
+ opt: false
235
+ } : img;
236
+ }
237
+
209
238
  /**
210
239
  * Handles richtext schema traversal with callback support.
211
240
  * Processes richtext structures (string, array, or object format).
@@ -231,13 +260,17 @@ function handleRichTextSchema(sourceOrSelector, recOpts, rec) {
231
260
  if (!sourceOrSelector) {
232
261
  return null;
233
262
  }
263
+ // An inline image's `src` is media, and media is now recognised only from
264
+ // the schema. Passing the richtext schema down (as every other key does)
265
+ // would leave it looking like a plain object, and it would lose its `url`.
266
+ var imgSchema = sourceOrSelector.tag === "img" ? inlineImageSchemaOf(recOpts.schema) : undefined;
234
267
  var richtextSelector = Object.fromEntries(Object.entries(sourceOrSelector).map(function (_ref2) {
235
268
  var _ref3 = slicedToArray._slicedToArray(_ref2, 2),
236
269
  key = _ref3[0],
237
270
  value = _ref3[1];
238
271
  return [key, key === "tag" || key === "styles" ? value : rec(value, {
239
272
  path: recOpts.path,
240
- schema: recOpts.schema
273
+ schema: key === "src" && imgSchema ? imgSchema : recOpts.schema
241
274
  })];
242
275
  }));
243
276
  return richtextSelector;
@@ -286,6 +319,14 @@ function stegaEncode(input, opts) {
286
319
  if (recOpts !== null && recOpts !== void 0 && recOpts.schema && isRichTextSchema(recOpts.schema)) {
287
320
  return handleRichTextSchema(sourceOrSelector, recOpts, rec);
288
321
  }
322
+ if (recOpts && (isImageSchema(recOpts.schema) || isFileSchema(recOpts.schema)) && sourceOrSelector && slicedToArray._typeof(sourceOrSelector) === "object") {
323
+ var src = opts.getModule ? core.Internal.media.fillFromGallery(sourceOrSelector, recOpts.schema, opts.getModule) : sourceOrSelector;
324
+ // `url` carries the edit tag, so a click on an image reaches its field.
325
+ // `path` must stay raw: it is what the URL was derived from.
326
+ return _objectSpread2(_objectSpread2({}, src), {}, {
327
+ url: rec(core.Internal.mediaUrl(src), recOpts)
328
+ });
329
+ }
289
330
  if (slicedToArray._typeof(sourceOrSelector) === "object") {
290
331
  if (!sourceOrSelector) {
291
332
  return null;
@@ -293,30 +334,11 @@ function stegaEncode(input, opts) {
293
334
  var selectorPath = core.Internal.getValPath(sourceOrSelector);
294
335
  if (selectorPath) {
295
336
  var newSchema = core.Internal.getSchema(sourceOrSelector);
296
- return rec(opts.getModule && opts.getModule(selectorPath) !== undefined ? opts.getModule(selectorPath) : core.Internal.getSource(sourceOrSelector), opts.disabled ? undefined : {
337
+ return rec(opts.getModule && opts.getModule(selectorPath) !== undefined ? opts.getModule(selectorPath) : core.Internal.getSource(sourceOrSelector), {
297
338
  path: selectorPath,
298
339
  schema: newSchema === null || newSchema === void 0 ? void 0 : newSchema["executeSerialize"]()
299
340
  });
300
341
  }
301
- if (core.VAL_EXTENSION in sourceOrSelector) {
302
- if (sourceOrSelector[core.VAL_EXTENSION] === "file" && typeof sourceOrSelector[core.FILE_REF_PROP] === "string") {
303
- var source = recOpts !== null && recOpts !== void 0 && recOpts.schema && opts.getModule ? augmentWithReferencedModuleMetadata(sourceOrSelector, recOpts.schema, opts.getModule) : sourceOrSelector;
304
- var fileSelector = core.Internal.convertFileSource(source);
305
- var url = fileSelector.url;
306
- return _objectSpread2(_objectSpread2({}, fileSelector), {}, {
307
- url: rec(url, recOpts)
308
- });
309
- } else if (sourceOrSelector[core.VAL_EXTENSION] === "remote") {
310
- var _source = recOpts !== null && recOpts !== void 0 && recOpts.schema && opts.getModule ? augmentWithReferencedModuleMetadata(sourceOrSelector, recOpts.schema, opts.getModule) : sourceOrSelector;
311
- var remoteSelector = core.Internal.convertFileSource(_source);
312
- var _url = remoteSelector.url;
313
- return _objectSpread2(_objectSpread2({}, remoteSelector), {}, {
314
- url: rec(_url, recOpts)
315
- });
316
- }
317
- console.error("Encountered unexpected extension: ".concat(sourceOrSelector[core.VAL_EXTENSION]));
318
- return sourceOrSelector;
319
- }
320
342
  if (Array.isArray(sourceOrSelector)) {
321
343
  return sourceOrSelector.map(function (el, i) {
322
344
  return rec(el, recOpts && {
@@ -344,7 +366,11 @@ function stegaEncode(input, opts) {
344
366
  }
345
367
  if (typeof sourceOrSelector === "string") {
346
368
  var _recOpts$schema, _recOpts$schema2;
347
- if (!recOpts) {
369
+ // `disabled` suppresses the steganography, NOT the schema. Media is
370
+ // recognised from the schema now, so dropping it here — which is what
371
+ // this function used to do — would strip `url` from every image on every
372
+ // production page, where `disabled` is the normal case.
373
+ if (!recOpts || opts.disabled) {
348
374
  return sourceOrSelector;
349
375
  }
350
376
  if ((_recOpts$schema = recOpts.schema) !== null && _recOpts$schema !== void 0 && _recOpts$schema.raw || ((_recOpts$schema2 = recOpts.schema) === null || _recOpts$schema2 === void 0 ? void 0 : _recOpts$schema2.type) === "literal") {
@@ -364,7 +390,7 @@ function stegaEncode(input, opts) {
364
390
  console.error("Unexpected type of source selector: ".concat(slicedToArray._typeof(sourceOrSelector)));
365
391
  return sourceOrSelector;
366
392
  }
367
- return rec(input, opts.disabled ? undefined : opts.root);
393
+ return rec(input, opts.root);
368
394
  }
369
395
  function isRecordSchema(schema) {
370
396
  return (schema === null || schema === void 0 ? void 0 : schema.type) === "record";
@@ -403,31 +429,6 @@ function isFileSchema(schema) {
403
429
  function isImageSchema(schema) {
404
430
  return (schema === null || schema === void 0 ? void 0 : schema.type) === "image";
405
431
  }
406
- function augmentWithReferencedModuleMetadata(source, schema, getModule) {
407
- if (source.metadata || !(isFileSchema(schema) || isImageSchema(schema)) || !schema.referencedModule) {
408
- return source;
409
- }
410
- var moduleSource = getModule(schema.referencedModule);
411
- if (!moduleSource || slicedToArray._typeof(moduleSource) !== "object" || Array.isArray(moduleSource)) {
412
- return source;
413
- }
414
- var ref = source[core.FILE_REF_PROP];
415
- // For local files the ref is the file path directly; for remote refs we
416
- // need to extract the file path from the remote URL.
417
- var fileRef = ref in moduleSource ? ref : null;
418
- if (!fileRef) {
419
- var splitResult = core.Internal.remote.splitRemoteRef(ref);
420
- if (splitResult.status === "success" && splitResult.filePath in moduleSource) {
421
- fileRef = splitResult.filePath;
422
- }
423
- }
424
- if (!fileRef) {
425
- return source;
426
- }
427
- return _objectSpread2(_objectSpread2({}, source), {}, {
428
- metadata: moduleSource[fileRef]
429
- });
430
- }
431
432
  function collectReferencedModulesFromSchema(schema, acc) {
432
433
  if (isFileSchema(schema) || isImageSchema(schema)) {
433
434
  if (schema.referencedModule) {
@@ -477,16 +478,6 @@ function getModuleIds(input) {
477
478
  }
478
479
  return;
479
480
  }
480
- if (core.VAL_EXTENSION in sourceOrSelector) {
481
- if (sourceOrSelector[core.VAL_EXTENSION] === "richtext") {
482
- return;
483
- }
484
- if (sourceOrSelector[core.VAL_EXTENSION] === "file" && typeof sourceOrSelector[core.FILE_REF_PROP] === "string") {
485
- return;
486
- }
487
- console.error("Encountered unexpected extension: ".concat(sourceOrSelector[core.VAL_EXTENSION]));
488
- return sourceOrSelector;
489
- }
490
481
  if (Array.isArray(sourceOrSelector)) {
491
482
  sourceOrSelector.forEach(rec);
492
483
  return;
@@ -1,5 +1,5 @@
1
1
  import { b as _unsupportedIterableToArray, a as _typeof, c as _arrayLikeToArray, _ as _slicedToArray } from './slicedToArray-9cce0d9f.browser.esm.js';
2
- import { Internal, VAL_EXTENSION, FILE_REF_PROP } from '@valbuild/core';
2
+ import { Internal } from '@valbuild/core';
3
3
  import { vercelStegaDecodeAll, vercelStegaSplit, vercelStegaCombine } from '@vercel/stega';
4
4
 
5
5
  function _createForOfIteratorHelper(r, e) {
@@ -147,6 +147,13 @@ function _toConsumableArray(r) {
147
147
  *
148
148
  */
149
149
 
150
+ /**
151
+ * An image as a consumer sees it: what was authored, plus the generated `url`.
152
+ *
153
+ * `path` stays a plain string — it is what `url` is derived from, so encoding it
154
+ * would corrupt every URL built from it.
155
+ */
156
+
150
157
  /**
151
158
  * RichText is accessible by users (after conversion via useVal / fetchVal)
152
159
  **/
@@ -204,6 +211,28 @@ function resolveLiteralUnionSchema(source, schema) {
204
211
  return matchingSchema || null;
205
212
  }
206
213
 
214
+ /**
215
+ * The image schema of a richtext's inline images.
216
+ *
217
+ * `inline.img` serializes as `true` when the author did not pass a schema, so
218
+ * there is nothing to hand down; a bare `{type: "image"}` is enough, since all
219
+ * the media branch needs is to know that it is looking at media.
220
+ */
221
+ function inlineImageSchemaOf(schema) {
222
+ var _schema$options;
223
+ if ((schema === null || schema === void 0 ? void 0 : schema.type) !== "richtext") {
224
+ return undefined;
225
+ }
226
+ var img = (_schema$options = schema.options) === null || _schema$options === void 0 || (_schema$options = _schema$options.inline) === null || _schema$options === void 0 ? void 0 : _schema$options.img;
227
+ if (!img) {
228
+ return undefined;
229
+ }
230
+ return img === true ? {
231
+ type: "image",
232
+ opt: false
233
+ } : img;
234
+ }
235
+
207
236
  /**
208
237
  * Handles richtext schema traversal with callback support.
209
238
  * Processes richtext structures (string, array, or object format).
@@ -229,13 +258,17 @@ function handleRichTextSchema(sourceOrSelector, recOpts, rec) {
229
258
  if (!sourceOrSelector) {
230
259
  return null;
231
260
  }
261
+ // An inline image's `src` is media, and media is now recognised only from
262
+ // the schema. Passing the richtext schema down (as every other key does)
263
+ // would leave it looking like a plain object, and it would lose its `url`.
264
+ var imgSchema = sourceOrSelector.tag === "img" ? inlineImageSchemaOf(recOpts.schema) : undefined;
232
265
  var richtextSelector = Object.fromEntries(Object.entries(sourceOrSelector).map(function (_ref2) {
233
266
  var _ref3 = _slicedToArray(_ref2, 2),
234
267
  key = _ref3[0],
235
268
  value = _ref3[1];
236
269
  return [key, key === "tag" || key === "styles" ? value : rec(value, {
237
270
  path: recOpts.path,
238
- schema: recOpts.schema
271
+ schema: key === "src" && imgSchema ? imgSchema : recOpts.schema
239
272
  })];
240
273
  }));
241
274
  return richtextSelector;
@@ -284,6 +317,14 @@ function stegaEncode(input, opts) {
284
317
  if (recOpts !== null && recOpts !== void 0 && recOpts.schema && isRichTextSchema(recOpts.schema)) {
285
318
  return handleRichTextSchema(sourceOrSelector, recOpts, rec);
286
319
  }
320
+ if (recOpts && (isImageSchema(recOpts.schema) || isFileSchema(recOpts.schema)) && sourceOrSelector && _typeof(sourceOrSelector) === "object") {
321
+ var src = opts.getModule ? Internal.media.fillFromGallery(sourceOrSelector, recOpts.schema, opts.getModule) : sourceOrSelector;
322
+ // `url` carries the edit tag, so a click on an image reaches its field.
323
+ // `path` must stay raw: it is what the URL was derived from.
324
+ return _objectSpread2(_objectSpread2({}, src), {}, {
325
+ url: rec(Internal.mediaUrl(src), recOpts)
326
+ });
327
+ }
287
328
  if (_typeof(sourceOrSelector) === "object") {
288
329
  if (!sourceOrSelector) {
289
330
  return null;
@@ -291,30 +332,11 @@ function stegaEncode(input, opts) {
291
332
  var selectorPath = Internal.getValPath(sourceOrSelector);
292
333
  if (selectorPath) {
293
334
  var newSchema = Internal.getSchema(sourceOrSelector);
294
- return rec(opts.getModule && opts.getModule(selectorPath) !== undefined ? opts.getModule(selectorPath) : Internal.getSource(sourceOrSelector), opts.disabled ? undefined : {
335
+ return rec(opts.getModule && opts.getModule(selectorPath) !== undefined ? opts.getModule(selectorPath) : Internal.getSource(sourceOrSelector), {
295
336
  path: selectorPath,
296
337
  schema: newSchema === null || newSchema === void 0 ? void 0 : newSchema["executeSerialize"]()
297
338
  });
298
339
  }
299
- if (VAL_EXTENSION in sourceOrSelector) {
300
- if (sourceOrSelector[VAL_EXTENSION] === "file" && typeof sourceOrSelector[FILE_REF_PROP] === "string") {
301
- var source = recOpts !== null && recOpts !== void 0 && recOpts.schema && opts.getModule ? augmentWithReferencedModuleMetadata(sourceOrSelector, recOpts.schema, opts.getModule) : sourceOrSelector;
302
- var fileSelector = Internal.convertFileSource(source);
303
- var url = fileSelector.url;
304
- return _objectSpread2(_objectSpread2({}, fileSelector), {}, {
305
- url: rec(url, recOpts)
306
- });
307
- } else if (sourceOrSelector[VAL_EXTENSION] === "remote") {
308
- var _source = recOpts !== null && recOpts !== void 0 && recOpts.schema && opts.getModule ? augmentWithReferencedModuleMetadata(sourceOrSelector, recOpts.schema, opts.getModule) : sourceOrSelector;
309
- var remoteSelector = Internal.convertFileSource(_source);
310
- var _url = remoteSelector.url;
311
- return _objectSpread2(_objectSpread2({}, remoteSelector), {}, {
312
- url: rec(_url, recOpts)
313
- });
314
- }
315
- console.error("Encountered unexpected extension: ".concat(sourceOrSelector[VAL_EXTENSION]));
316
- return sourceOrSelector;
317
- }
318
340
  if (Array.isArray(sourceOrSelector)) {
319
341
  return sourceOrSelector.map(function (el, i) {
320
342
  return rec(el, recOpts && {
@@ -342,7 +364,11 @@ function stegaEncode(input, opts) {
342
364
  }
343
365
  if (typeof sourceOrSelector === "string") {
344
366
  var _recOpts$schema, _recOpts$schema2;
345
- if (!recOpts) {
367
+ // `disabled` suppresses the steganography, NOT the schema. Media is
368
+ // recognised from the schema now, so dropping it here — which is what
369
+ // this function used to do — would strip `url` from every image on every
370
+ // production page, where `disabled` is the normal case.
371
+ if (!recOpts || opts.disabled) {
346
372
  return sourceOrSelector;
347
373
  }
348
374
  if ((_recOpts$schema = recOpts.schema) !== null && _recOpts$schema !== void 0 && _recOpts$schema.raw || ((_recOpts$schema2 = recOpts.schema) === null || _recOpts$schema2 === void 0 ? void 0 : _recOpts$schema2.type) === "literal") {
@@ -362,7 +388,7 @@ function stegaEncode(input, opts) {
362
388
  console.error("Unexpected type of source selector: ".concat(_typeof(sourceOrSelector)));
363
389
  return sourceOrSelector;
364
390
  }
365
- return rec(input, opts.disabled ? undefined : opts.root);
391
+ return rec(input, opts.root);
366
392
  }
367
393
  function isRecordSchema(schema) {
368
394
  return (schema === null || schema === void 0 ? void 0 : schema.type) === "record";
@@ -401,31 +427,6 @@ function isFileSchema(schema) {
401
427
  function isImageSchema(schema) {
402
428
  return (schema === null || schema === void 0 ? void 0 : schema.type) === "image";
403
429
  }
404
- function augmentWithReferencedModuleMetadata(source, schema, getModule) {
405
- if (source.metadata || !(isFileSchema(schema) || isImageSchema(schema)) || !schema.referencedModule) {
406
- return source;
407
- }
408
- var moduleSource = getModule(schema.referencedModule);
409
- if (!moduleSource || _typeof(moduleSource) !== "object" || Array.isArray(moduleSource)) {
410
- return source;
411
- }
412
- var ref = source[FILE_REF_PROP];
413
- // For local files the ref is the file path directly; for remote refs we
414
- // need to extract the file path from the remote URL.
415
- var fileRef = ref in moduleSource ? ref : null;
416
- if (!fileRef) {
417
- var splitResult = Internal.remote.splitRemoteRef(ref);
418
- if (splitResult.status === "success" && splitResult.filePath in moduleSource) {
419
- fileRef = splitResult.filePath;
420
- }
421
- }
422
- if (!fileRef) {
423
- return source;
424
- }
425
- return _objectSpread2(_objectSpread2({}, source), {}, {
426
- metadata: moduleSource[fileRef]
427
- });
428
- }
429
430
  function collectReferencedModulesFromSchema(schema, acc) {
430
431
  if (isFileSchema(schema) || isImageSchema(schema)) {
431
432
  if (schema.referencedModule) {
@@ -475,16 +476,6 @@ function getModuleIds(input) {
475
476
  }
476
477
  return;
477
478
  }
478
- if (VAL_EXTENSION in sourceOrSelector) {
479
- if (sourceOrSelector[VAL_EXTENSION] === "richtext") {
480
- return;
481
- }
482
- if (sourceOrSelector[VAL_EXTENSION] === "file" && typeof sourceOrSelector[FILE_REF_PROP] === "string") {
483
- return;
484
- }
485
- console.error("Encountered unexpected extension: ".concat(sourceOrSelector[VAL_EXTENSION]));
486
- return sourceOrSelector;
487
- }
488
479
  if (Array.isArray(sourceOrSelector)) {
489
480
  sourceOrSelector.forEach(rec);
490
481
  return;
@@ -1,5 +1,5 @@
1
1
  import { b as _unsupportedIterableToArray, a as _typeof, c as _arrayLikeToArray, _ as _slicedToArray } from './slicedToArray-7d0170b6.worker.esm.js';
2
- import { Internal, VAL_EXTENSION, FILE_REF_PROP } from '@valbuild/core';
2
+ import { Internal } from '@valbuild/core';
3
3
  import { vercelStegaDecodeAll, vercelStegaSplit, vercelStegaCombine } from '@vercel/stega';
4
4
 
5
5
  function _createForOfIteratorHelper(r, e) {
@@ -147,6 +147,13 @@ function _toConsumableArray(r) {
147
147
  *
148
148
  */
149
149
 
150
+ /**
151
+ * An image as a consumer sees it: what was authored, plus the generated `url`.
152
+ *
153
+ * `path` stays a plain string — it is what `url` is derived from, so encoding it
154
+ * would corrupt every URL built from it.
155
+ */
156
+
150
157
  /**
151
158
  * RichText is accessible by users (after conversion via useVal / fetchVal)
152
159
  **/
@@ -204,6 +211,28 @@ function resolveLiteralUnionSchema(source, schema) {
204
211
  return matchingSchema || null;
205
212
  }
206
213
 
214
+ /**
215
+ * The image schema of a richtext's inline images.
216
+ *
217
+ * `inline.img` serializes as `true` when the author did not pass a schema, so
218
+ * there is nothing to hand down; a bare `{type: "image"}` is enough, since all
219
+ * the media branch needs is to know that it is looking at media.
220
+ */
221
+ function inlineImageSchemaOf(schema) {
222
+ var _schema$options;
223
+ if ((schema === null || schema === void 0 ? void 0 : schema.type) !== "richtext") {
224
+ return undefined;
225
+ }
226
+ var img = (_schema$options = schema.options) === null || _schema$options === void 0 || (_schema$options = _schema$options.inline) === null || _schema$options === void 0 ? void 0 : _schema$options.img;
227
+ if (!img) {
228
+ return undefined;
229
+ }
230
+ return img === true ? {
231
+ type: "image",
232
+ opt: false
233
+ } : img;
234
+ }
235
+
207
236
  /**
208
237
  * Handles richtext schema traversal with callback support.
209
238
  * Processes richtext structures (string, array, or object format).
@@ -229,13 +258,17 @@ function handleRichTextSchema(sourceOrSelector, recOpts, rec) {
229
258
  if (!sourceOrSelector) {
230
259
  return null;
231
260
  }
261
+ // An inline image's `src` is media, and media is now recognised only from
262
+ // the schema. Passing the richtext schema down (as every other key does)
263
+ // would leave it looking like a plain object, and it would lose its `url`.
264
+ var imgSchema = sourceOrSelector.tag === "img" ? inlineImageSchemaOf(recOpts.schema) : undefined;
232
265
  var richtextSelector = Object.fromEntries(Object.entries(sourceOrSelector).map(function (_ref2) {
233
266
  var _ref3 = _slicedToArray(_ref2, 2),
234
267
  key = _ref3[0],
235
268
  value = _ref3[1];
236
269
  return [key, key === "tag" || key === "styles" ? value : rec(value, {
237
270
  path: recOpts.path,
238
- schema: recOpts.schema
271
+ schema: key === "src" && imgSchema ? imgSchema : recOpts.schema
239
272
  })];
240
273
  }));
241
274
  return richtextSelector;
@@ -284,6 +317,14 @@ function stegaEncode(input, opts) {
284
317
  if (recOpts !== null && recOpts !== void 0 && recOpts.schema && isRichTextSchema(recOpts.schema)) {
285
318
  return handleRichTextSchema(sourceOrSelector, recOpts, rec);
286
319
  }
320
+ if (recOpts && (isImageSchema(recOpts.schema) || isFileSchema(recOpts.schema)) && sourceOrSelector && _typeof(sourceOrSelector) === "object") {
321
+ var src = opts.getModule ? Internal.media.fillFromGallery(sourceOrSelector, recOpts.schema, opts.getModule) : sourceOrSelector;
322
+ // `url` carries the edit tag, so a click on an image reaches its field.
323
+ // `path` must stay raw: it is what the URL was derived from.
324
+ return _objectSpread2(_objectSpread2({}, src), {}, {
325
+ url: rec(Internal.mediaUrl(src), recOpts)
326
+ });
327
+ }
287
328
  if (_typeof(sourceOrSelector) === "object") {
288
329
  if (!sourceOrSelector) {
289
330
  return null;
@@ -291,30 +332,11 @@ function stegaEncode(input, opts) {
291
332
  var selectorPath = Internal.getValPath(sourceOrSelector);
292
333
  if (selectorPath) {
293
334
  var newSchema = Internal.getSchema(sourceOrSelector);
294
- return rec(opts.getModule && opts.getModule(selectorPath) !== undefined ? opts.getModule(selectorPath) : Internal.getSource(sourceOrSelector), opts.disabled ? undefined : {
335
+ return rec(opts.getModule && opts.getModule(selectorPath) !== undefined ? opts.getModule(selectorPath) : Internal.getSource(sourceOrSelector), {
295
336
  path: selectorPath,
296
337
  schema: newSchema === null || newSchema === void 0 ? void 0 : newSchema["executeSerialize"]()
297
338
  });
298
339
  }
299
- if (VAL_EXTENSION in sourceOrSelector) {
300
- if (sourceOrSelector[VAL_EXTENSION] === "file" && typeof sourceOrSelector[FILE_REF_PROP] === "string") {
301
- var source = recOpts !== null && recOpts !== void 0 && recOpts.schema && opts.getModule ? augmentWithReferencedModuleMetadata(sourceOrSelector, recOpts.schema, opts.getModule) : sourceOrSelector;
302
- var fileSelector = Internal.convertFileSource(source);
303
- var url = fileSelector.url;
304
- return _objectSpread2(_objectSpread2({}, fileSelector), {}, {
305
- url: rec(url, recOpts)
306
- });
307
- } else if (sourceOrSelector[VAL_EXTENSION] === "remote") {
308
- var _source = recOpts !== null && recOpts !== void 0 && recOpts.schema && opts.getModule ? augmentWithReferencedModuleMetadata(sourceOrSelector, recOpts.schema, opts.getModule) : sourceOrSelector;
309
- var remoteSelector = Internal.convertFileSource(_source);
310
- var _url = remoteSelector.url;
311
- return _objectSpread2(_objectSpread2({}, remoteSelector), {}, {
312
- url: rec(_url, recOpts)
313
- });
314
- }
315
- console.error("Encountered unexpected extension: ".concat(sourceOrSelector[VAL_EXTENSION]));
316
- return sourceOrSelector;
317
- }
318
340
  if (Array.isArray(sourceOrSelector)) {
319
341
  return sourceOrSelector.map(function (el, i) {
320
342
  return rec(el, recOpts && {
@@ -342,7 +364,11 @@ function stegaEncode(input, opts) {
342
364
  }
343
365
  if (typeof sourceOrSelector === "string") {
344
366
  var _recOpts$schema, _recOpts$schema2;
345
- if (!recOpts) {
367
+ // `disabled` suppresses the steganography, NOT the schema. Media is
368
+ // recognised from the schema now, so dropping it here — which is what
369
+ // this function used to do — would strip `url` from every image on every
370
+ // production page, where `disabled` is the normal case.
371
+ if (!recOpts || opts.disabled) {
346
372
  return sourceOrSelector;
347
373
  }
348
374
  if ((_recOpts$schema = recOpts.schema) !== null && _recOpts$schema !== void 0 && _recOpts$schema.raw || ((_recOpts$schema2 = recOpts.schema) === null || _recOpts$schema2 === void 0 ? void 0 : _recOpts$schema2.type) === "literal") {
@@ -362,7 +388,7 @@ function stegaEncode(input, opts) {
362
388
  console.error("Unexpected type of source selector: ".concat(_typeof(sourceOrSelector)));
363
389
  return sourceOrSelector;
364
390
  }
365
- return rec(input, opts.disabled ? undefined : opts.root);
391
+ return rec(input, opts.root);
366
392
  }
367
393
  function isRecordSchema(schema) {
368
394
  return (schema === null || schema === void 0 ? void 0 : schema.type) === "record";
@@ -401,31 +427,6 @@ function isFileSchema(schema) {
401
427
  function isImageSchema(schema) {
402
428
  return (schema === null || schema === void 0 ? void 0 : schema.type) === "image";
403
429
  }
404
- function augmentWithReferencedModuleMetadata(source, schema, getModule) {
405
- if (source.metadata || !(isFileSchema(schema) || isImageSchema(schema)) || !schema.referencedModule) {
406
- return source;
407
- }
408
- var moduleSource = getModule(schema.referencedModule);
409
- if (!moduleSource || _typeof(moduleSource) !== "object" || Array.isArray(moduleSource)) {
410
- return source;
411
- }
412
- var ref = source[FILE_REF_PROP];
413
- // For local files the ref is the file path directly; for remote refs we
414
- // need to extract the file path from the remote URL.
415
- var fileRef = ref in moduleSource ? ref : null;
416
- if (!fileRef) {
417
- var splitResult = Internal.remote.splitRemoteRef(ref);
418
- if (splitResult.status === "success" && splitResult.filePath in moduleSource) {
419
- fileRef = splitResult.filePath;
420
- }
421
- }
422
- if (!fileRef) {
423
- return source;
424
- }
425
- return _objectSpread2(_objectSpread2({}, source), {}, {
426
- metadata: moduleSource[fileRef]
427
- });
428
- }
429
430
  function collectReferencedModulesFromSchema(schema, acc) {
430
431
  if (isFileSchema(schema) || isImageSchema(schema)) {
431
432
  if (schema.referencedModule) {
@@ -475,16 +476,6 @@ function getModuleIds(input) {
475
476
  }
476
477
  return;
477
478
  }
478
- if (VAL_EXTENSION in sourceOrSelector) {
479
- if (sourceOrSelector[VAL_EXTENSION] === "richtext") {
480
- return;
481
- }
482
- if (sourceOrSelector[VAL_EXTENSION] === "file" && typeof sourceOrSelector[FILE_REF_PROP] === "string") {
483
- return;
484
- }
485
- console.error("Encountered unexpected extension: ".concat(sourceOrSelector[VAL_EXTENSION]));
486
- return sourceOrSelector;
487
- }
488
479
  if (Array.isArray(sourceOrSelector)) {
489
480
  sourceOrSelector.forEach(rec);
490
481
  return;
@@ -1,5 +1,5 @@
1
1
  import { b as _unsupportedIterableToArray, a as _typeof, c as _arrayLikeToArray, _ as _slicedToArray } from './slicedToArray-0c0a3b4a.esm.js';
2
- import { Internal, VAL_EXTENSION, FILE_REF_PROP } from '@valbuild/core';
2
+ import { Internal } from '@valbuild/core';
3
3
  import { vercelStegaDecodeAll, vercelStegaSplit, vercelStegaCombine } from '@vercel/stega';
4
4
 
5
5
  function _createForOfIteratorHelper(r, e) {
@@ -147,6 +147,13 @@ function _toConsumableArray(r) {
147
147
  *
148
148
  */
149
149
 
150
+ /**
151
+ * An image as a consumer sees it: what was authored, plus the generated `url`.
152
+ *
153
+ * `path` stays a plain string — it is what `url` is derived from, so encoding it
154
+ * would corrupt every URL built from it.
155
+ */
156
+
150
157
  /**
151
158
  * RichText is accessible by users (after conversion via useVal / fetchVal)
152
159
  **/
@@ -204,6 +211,28 @@ function resolveLiteralUnionSchema(source, schema) {
204
211
  return matchingSchema || null;
205
212
  }
206
213
 
214
+ /**
215
+ * The image schema of a richtext's inline images.
216
+ *
217
+ * `inline.img` serializes as `true` when the author did not pass a schema, so
218
+ * there is nothing to hand down; a bare `{type: "image"}` is enough, since all
219
+ * the media branch needs is to know that it is looking at media.
220
+ */
221
+ function inlineImageSchemaOf(schema) {
222
+ var _schema$options;
223
+ if ((schema === null || schema === void 0 ? void 0 : schema.type) !== "richtext") {
224
+ return undefined;
225
+ }
226
+ var img = (_schema$options = schema.options) === null || _schema$options === void 0 || (_schema$options = _schema$options.inline) === null || _schema$options === void 0 ? void 0 : _schema$options.img;
227
+ if (!img) {
228
+ return undefined;
229
+ }
230
+ return img === true ? {
231
+ type: "image",
232
+ opt: false
233
+ } : img;
234
+ }
235
+
207
236
  /**
208
237
  * Handles richtext schema traversal with callback support.
209
238
  * Processes richtext structures (string, array, or object format).
@@ -229,13 +258,17 @@ function handleRichTextSchema(sourceOrSelector, recOpts, rec) {
229
258
  if (!sourceOrSelector) {
230
259
  return null;
231
260
  }
261
+ // An inline image's `src` is media, and media is now recognised only from
262
+ // the schema. Passing the richtext schema down (as every other key does)
263
+ // would leave it looking like a plain object, and it would lose its `url`.
264
+ var imgSchema = sourceOrSelector.tag === "img" ? inlineImageSchemaOf(recOpts.schema) : undefined;
232
265
  var richtextSelector = Object.fromEntries(Object.entries(sourceOrSelector).map(function (_ref2) {
233
266
  var _ref3 = _slicedToArray(_ref2, 2),
234
267
  key = _ref3[0],
235
268
  value = _ref3[1];
236
269
  return [key, key === "tag" || key === "styles" ? value : rec(value, {
237
270
  path: recOpts.path,
238
- schema: recOpts.schema
271
+ schema: key === "src" && imgSchema ? imgSchema : recOpts.schema
239
272
  })];
240
273
  }));
241
274
  return richtextSelector;
@@ -284,6 +317,14 @@ function stegaEncode(input, opts) {
284
317
  if (recOpts !== null && recOpts !== void 0 && recOpts.schema && isRichTextSchema(recOpts.schema)) {
285
318
  return handleRichTextSchema(sourceOrSelector, recOpts, rec);
286
319
  }
320
+ if (recOpts && (isImageSchema(recOpts.schema) || isFileSchema(recOpts.schema)) && sourceOrSelector && _typeof(sourceOrSelector) === "object") {
321
+ var src = opts.getModule ? Internal.media.fillFromGallery(sourceOrSelector, recOpts.schema, opts.getModule) : sourceOrSelector;
322
+ // `url` carries the edit tag, so a click on an image reaches its field.
323
+ // `path` must stay raw: it is what the URL was derived from.
324
+ return _objectSpread2(_objectSpread2({}, src), {}, {
325
+ url: rec(Internal.mediaUrl(src), recOpts)
326
+ });
327
+ }
287
328
  if (_typeof(sourceOrSelector) === "object") {
288
329
  if (!sourceOrSelector) {
289
330
  return null;
@@ -291,30 +332,11 @@ function stegaEncode(input, opts) {
291
332
  var selectorPath = Internal.getValPath(sourceOrSelector);
292
333
  if (selectorPath) {
293
334
  var newSchema = Internal.getSchema(sourceOrSelector);
294
- return rec(opts.getModule && opts.getModule(selectorPath) !== undefined ? opts.getModule(selectorPath) : Internal.getSource(sourceOrSelector), opts.disabled ? undefined : {
335
+ return rec(opts.getModule && opts.getModule(selectorPath) !== undefined ? opts.getModule(selectorPath) : Internal.getSource(sourceOrSelector), {
295
336
  path: selectorPath,
296
337
  schema: newSchema === null || newSchema === void 0 ? void 0 : newSchema["executeSerialize"]()
297
338
  });
298
339
  }
299
- if (VAL_EXTENSION in sourceOrSelector) {
300
- if (sourceOrSelector[VAL_EXTENSION] === "file" && typeof sourceOrSelector[FILE_REF_PROP] === "string") {
301
- var source = recOpts !== null && recOpts !== void 0 && recOpts.schema && opts.getModule ? augmentWithReferencedModuleMetadata(sourceOrSelector, recOpts.schema, opts.getModule) : sourceOrSelector;
302
- var fileSelector = Internal.convertFileSource(source);
303
- var url = fileSelector.url;
304
- return _objectSpread2(_objectSpread2({}, fileSelector), {}, {
305
- url: rec(url, recOpts)
306
- });
307
- } else if (sourceOrSelector[VAL_EXTENSION] === "remote") {
308
- var _source = recOpts !== null && recOpts !== void 0 && recOpts.schema && opts.getModule ? augmentWithReferencedModuleMetadata(sourceOrSelector, recOpts.schema, opts.getModule) : sourceOrSelector;
309
- var remoteSelector = Internal.convertFileSource(_source);
310
- var _url = remoteSelector.url;
311
- return _objectSpread2(_objectSpread2({}, remoteSelector), {}, {
312
- url: rec(_url, recOpts)
313
- });
314
- }
315
- console.error("Encountered unexpected extension: ".concat(sourceOrSelector[VAL_EXTENSION]));
316
- return sourceOrSelector;
317
- }
318
340
  if (Array.isArray(sourceOrSelector)) {
319
341
  return sourceOrSelector.map(function (el, i) {
320
342
  return rec(el, recOpts && {
@@ -342,7 +364,11 @@ function stegaEncode(input, opts) {
342
364
  }
343
365
  if (typeof sourceOrSelector === "string") {
344
366
  var _recOpts$schema, _recOpts$schema2;
345
- if (!recOpts) {
367
+ // `disabled` suppresses the steganography, NOT the schema. Media is
368
+ // recognised from the schema now, so dropping it here — which is what
369
+ // this function used to do — would strip `url` from every image on every
370
+ // production page, where `disabled` is the normal case.
371
+ if (!recOpts || opts.disabled) {
346
372
  return sourceOrSelector;
347
373
  }
348
374
  if ((_recOpts$schema = recOpts.schema) !== null && _recOpts$schema !== void 0 && _recOpts$schema.raw || ((_recOpts$schema2 = recOpts.schema) === null || _recOpts$schema2 === void 0 ? void 0 : _recOpts$schema2.type) === "literal") {
@@ -362,7 +388,7 @@ function stegaEncode(input, opts) {
362
388
  console.error("Unexpected type of source selector: ".concat(_typeof(sourceOrSelector)));
363
389
  return sourceOrSelector;
364
390
  }
365
- return rec(input, opts.disabled ? undefined : opts.root);
391
+ return rec(input, opts.root);
366
392
  }
367
393
  function isRecordSchema(schema) {
368
394
  return (schema === null || schema === void 0 ? void 0 : schema.type) === "record";
@@ -401,31 +427,6 @@ function isFileSchema(schema) {
401
427
  function isImageSchema(schema) {
402
428
  return (schema === null || schema === void 0 ? void 0 : schema.type) === "image";
403
429
  }
404
- function augmentWithReferencedModuleMetadata(source, schema, getModule) {
405
- if (source.metadata || !(isFileSchema(schema) || isImageSchema(schema)) || !schema.referencedModule) {
406
- return source;
407
- }
408
- var moduleSource = getModule(schema.referencedModule);
409
- if (!moduleSource || _typeof(moduleSource) !== "object" || Array.isArray(moduleSource)) {
410
- return source;
411
- }
412
- var ref = source[FILE_REF_PROP];
413
- // For local files the ref is the file path directly; for remote refs we
414
- // need to extract the file path from the remote URL.
415
- var fileRef = ref in moduleSource ? ref : null;
416
- if (!fileRef) {
417
- var splitResult = Internal.remote.splitRemoteRef(ref);
418
- if (splitResult.status === "success" && splitResult.filePath in moduleSource) {
419
- fileRef = splitResult.filePath;
420
- }
421
- }
422
- if (!fileRef) {
423
- return source;
424
- }
425
- return _objectSpread2(_objectSpread2({}, source), {}, {
426
- metadata: moduleSource[fileRef]
427
- });
428
- }
429
430
  function collectReferencedModulesFromSchema(schema, acc) {
430
431
  if (isFileSchema(schema) || isImageSchema(schema)) {
431
432
  if (schema.referencedModule) {
@@ -475,16 +476,6 @@ function getModuleIds(input) {
475
476
  }
476
477
  return;
477
478
  }
478
- if (VAL_EXTENSION in sourceOrSelector) {
479
- if (sourceOrSelector[VAL_EXTENSION] === "richtext") {
480
- return;
481
- }
482
- if (sourceOrSelector[VAL_EXTENSION] === "file" && typeof sourceOrSelector[FILE_REF_PROP] === "string") {
483
- return;
484
- }
485
- console.error("Encountered unexpected extension: ".concat(sourceOrSelector[VAL_EXTENSION]));
486
- return sourceOrSelector;
487
- }
488
479
  if (Array.isArray(sourceOrSelector)) {
489
480
  sourceOrSelector.forEach(rec);
490
481
  return;
@@ -149,6 +149,13 @@ function _toConsumableArray(r) {
149
149
  *
150
150
  */
151
151
 
152
+ /**
153
+ * An image as a consumer sees it: what was authored, plus the generated `url`.
154
+ *
155
+ * `path` stays a plain string — it is what `url` is derived from, so encoding it
156
+ * would corrupt every URL built from it.
157
+ */
158
+
152
159
  /**
153
160
  * RichText is accessible by users (after conversion via useVal / fetchVal)
154
161
  **/
@@ -206,6 +213,28 @@ function resolveLiteralUnionSchema(source, schema) {
206
213
  return matchingSchema || null;
207
214
  }
208
215
 
216
+ /**
217
+ * The image schema of a richtext's inline images.
218
+ *
219
+ * `inline.img` serializes as `true` when the author did not pass a schema, so
220
+ * there is nothing to hand down; a bare `{type: "image"}` is enough, since all
221
+ * the media branch needs is to know that it is looking at media.
222
+ */
223
+ function inlineImageSchemaOf(schema) {
224
+ var _schema$options;
225
+ if ((schema === null || schema === void 0 ? void 0 : schema.type) !== "richtext") {
226
+ return undefined;
227
+ }
228
+ var img = (_schema$options = schema.options) === null || _schema$options === void 0 || (_schema$options = _schema$options.inline) === null || _schema$options === void 0 ? void 0 : _schema$options.img;
229
+ if (!img) {
230
+ return undefined;
231
+ }
232
+ return img === true ? {
233
+ type: "image",
234
+ opt: false
235
+ } : img;
236
+ }
237
+
209
238
  /**
210
239
  * Handles richtext schema traversal with callback support.
211
240
  * Processes richtext structures (string, array, or object format).
@@ -231,13 +260,17 @@ function handleRichTextSchema(sourceOrSelector, recOpts, rec) {
231
260
  if (!sourceOrSelector) {
232
261
  return null;
233
262
  }
263
+ // An inline image's `src` is media, and media is now recognised only from
264
+ // the schema. Passing the richtext schema down (as every other key does)
265
+ // would leave it looking like a plain object, and it would lose its `url`.
266
+ var imgSchema = sourceOrSelector.tag === "img" ? inlineImageSchemaOf(recOpts.schema) : undefined;
234
267
  var richtextSelector = Object.fromEntries(Object.entries(sourceOrSelector).map(function (_ref2) {
235
268
  var _ref3 = slicedToArray._slicedToArray(_ref2, 2),
236
269
  key = _ref3[0],
237
270
  value = _ref3[1];
238
271
  return [key, key === "tag" || key === "styles" ? value : rec(value, {
239
272
  path: recOpts.path,
240
- schema: recOpts.schema
273
+ schema: key === "src" && imgSchema ? imgSchema : recOpts.schema
241
274
  })];
242
275
  }));
243
276
  return richtextSelector;
@@ -286,6 +319,14 @@ function stegaEncode(input, opts) {
286
319
  if (recOpts !== null && recOpts !== void 0 && recOpts.schema && isRichTextSchema(recOpts.schema)) {
287
320
  return handleRichTextSchema(sourceOrSelector, recOpts, rec);
288
321
  }
322
+ if (recOpts && (isImageSchema(recOpts.schema) || isFileSchema(recOpts.schema)) && sourceOrSelector && slicedToArray._typeof(sourceOrSelector) === "object") {
323
+ var src = opts.getModule ? core.Internal.media.fillFromGallery(sourceOrSelector, recOpts.schema, opts.getModule) : sourceOrSelector;
324
+ // `url` carries the edit tag, so a click on an image reaches its field.
325
+ // `path` must stay raw: it is what the URL was derived from.
326
+ return _objectSpread2(_objectSpread2({}, src), {}, {
327
+ url: rec(core.Internal.mediaUrl(src), recOpts)
328
+ });
329
+ }
289
330
  if (slicedToArray._typeof(sourceOrSelector) === "object") {
290
331
  if (!sourceOrSelector) {
291
332
  return null;
@@ -293,30 +334,11 @@ function stegaEncode(input, opts) {
293
334
  var selectorPath = core.Internal.getValPath(sourceOrSelector);
294
335
  if (selectorPath) {
295
336
  var newSchema = core.Internal.getSchema(sourceOrSelector);
296
- return rec(opts.getModule && opts.getModule(selectorPath) !== undefined ? opts.getModule(selectorPath) : core.Internal.getSource(sourceOrSelector), opts.disabled ? undefined : {
337
+ return rec(opts.getModule && opts.getModule(selectorPath) !== undefined ? opts.getModule(selectorPath) : core.Internal.getSource(sourceOrSelector), {
297
338
  path: selectorPath,
298
339
  schema: newSchema === null || newSchema === void 0 ? void 0 : newSchema["executeSerialize"]()
299
340
  });
300
341
  }
301
- if (core.VAL_EXTENSION in sourceOrSelector) {
302
- if (sourceOrSelector[core.VAL_EXTENSION] === "file" && typeof sourceOrSelector[core.FILE_REF_PROP] === "string") {
303
- var source = recOpts !== null && recOpts !== void 0 && recOpts.schema && opts.getModule ? augmentWithReferencedModuleMetadata(sourceOrSelector, recOpts.schema, opts.getModule) : sourceOrSelector;
304
- var fileSelector = core.Internal.convertFileSource(source);
305
- var url = fileSelector.url;
306
- return _objectSpread2(_objectSpread2({}, fileSelector), {}, {
307
- url: rec(url, recOpts)
308
- });
309
- } else if (sourceOrSelector[core.VAL_EXTENSION] === "remote") {
310
- var _source = recOpts !== null && recOpts !== void 0 && recOpts.schema && opts.getModule ? augmentWithReferencedModuleMetadata(sourceOrSelector, recOpts.schema, opts.getModule) : sourceOrSelector;
311
- var remoteSelector = core.Internal.convertFileSource(_source);
312
- var _url = remoteSelector.url;
313
- return _objectSpread2(_objectSpread2({}, remoteSelector), {}, {
314
- url: rec(_url, recOpts)
315
- });
316
- }
317
- console.error("Encountered unexpected extension: ".concat(sourceOrSelector[core.VAL_EXTENSION]));
318
- return sourceOrSelector;
319
- }
320
342
  if (Array.isArray(sourceOrSelector)) {
321
343
  return sourceOrSelector.map(function (el, i) {
322
344
  return rec(el, recOpts && {
@@ -344,7 +366,11 @@ function stegaEncode(input, opts) {
344
366
  }
345
367
  if (typeof sourceOrSelector === "string") {
346
368
  var _recOpts$schema, _recOpts$schema2;
347
- if (!recOpts) {
369
+ // `disabled` suppresses the steganography, NOT the schema. Media is
370
+ // recognised from the schema now, so dropping it here — which is what
371
+ // this function used to do — would strip `url` from every image on every
372
+ // production page, where `disabled` is the normal case.
373
+ if (!recOpts || opts.disabled) {
348
374
  return sourceOrSelector;
349
375
  }
350
376
  if ((_recOpts$schema = recOpts.schema) !== null && _recOpts$schema !== void 0 && _recOpts$schema.raw || ((_recOpts$schema2 = recOpts.schema) === null || _recOpts$schema2 === void 0 ? void 0 : _recOpts$schema2.type) === "literal") {
@@ -364,7 +390,7 @@ function stegaEncode(input, opts) {
364
390
  console.error("Unexpected type of source selector: ".concat(slicedToArray._typeof(sourceOrSelector)));
365
391
  return sourceOrSelector;
366
392
  }
367
- return rec(input, opts.disabled ? undefined : opts.root);
393
+ return rec(input, opts.root);
368
394
  }
369
395
  function isRecordSchema(schema) {
370
396
  return (schema === null || schema === void 0 ? void 0 : schema.type) === "record";
@@ -403,31 +429,6 @@ function isFileSchema(schema) {
403
429
  function isImageSchema(schema) {
404
430
  return (schema === null || schema === void 0 ? void 0 : schema.type) === "image";
405
431
  }
406
- function augmentWithReferencedModuleMetadata(source, schema, getModule) {
407
- if (source.metadata || !(isFileSchema(schema) || isImageSchema(schema)) || !schema.referencedModule) {
408
- return source;
409
- }
410
- var moduleSource = getModule(schema.referencedModule);
411
- if (!moduleSource || slicedToArray._typeof(moduleSource) !== "object" || Array.isArray(moduleSource)) {
412
- return source;
413
- }
414
- var ref = source[core.FILE_REF_PROP];
415
- // For local files the ref is the file path directly; for remote refs we
416
- // need to extract the file path from the remote URL.
417
- var fileRef = ref in moduleSource ? ref : null;
418
- if (!fileRef) {
419
- var splitResult = core.Internal.remote.splitRemoteRef(ref);
420
- if (splitResult.status === "success" && splitResult.filePath in moduleSource) {
421
- fileRef = splitResult.filePath;
422
- }
423
- }
424
- if (!fileRef) {
425
- return source;
426
- }
427
- return _objectSpread2(_objectSpread2({}, source), {}, {
428
- metadata: moduleSource[fileRef]
429
- });
430
- }
431
432
  function collectReferencedModulesFromSchema(schema, acc) {
432
433
  if (isFileSchema(schema) || isImageSchema(schema)) {
433
434
  if (schema.referencedModule) {
@@ -477,16 +478,6 @@ function getModuleIds(input) {
477
478
  }
478
479
  return;
479
480
  }
480
- if (core.VAL_EXTENSION in sourceOrSelector) {
481
- if (sourceOrSelector[core.VAL_EXTENSION] === "richtext") {
482
- return;
483
- }
484
- if (sourceOrSelector[core.VAL_EXTENSION] === "file" && typeof sourceOrSelector[core.FILE_REF_PROP] === "string") {
485
- return;
486
- }
487
- console.error("Encountered unexpected extension: ".concat(sourceOrSelector[core.VAL_EXTENSION]));
488
- return sourceOrSelector;
489
- }
490
481
  if (Array.isArray(sourceOrSelector)) {
491
482
  sourceOrSelector.forEach(rec);
492
483
  return;
@@ -1,4 +1,4 @@
1
- import { d as _objectSpread2, r as raw, c as attrs, e as _toConsumableArray } from '../../dist/raw-0293ccee.browser.esm.js';
1
+ import { d as _objectSpread2, r as raw, c as attrs, e as _toConsumableArray } from '../../dist/raw-31c1b7d6.browser.esm.js';
2
2
  import React from 'react';
3
3
  import { jsx } from 'react/jsx-runtime';
4
4
  import '../../dist/slicedToArray-9cce0d9f.browser.esm.js';
@@ -87,7 +87,6 @@ function ValRichText(_ref) {
87
87
  }
88
88
  var className = classNameOfTag(child.tag, child.tag === "span" ? child.styles : [], theme);
89
89
  if (child.tag === "img") {
90
- var _child$src$metadata, _child$src$metadata2;
91
90
  var _transformed = transform && transform(child, [], undefined, key);
92
91
  if (_transformed !== undefined) {
93
92
  return _transformed;
@@ -97,8 +96,8 @@ function ValRichText(_ref) {
97
96
  className: className,
98
97
  src: child.src.url,
99
98
  // alt: child.alt, TODO: add alt to the img html object
100
- width: (_child$src$metadata = child.src.metadata) === null || _child$src$metadata === void 0 ? void 0 : _child$src$metadata.width,
101
- height: (_child$src$metadata2 = child.src.metadata) === null || _child$src$metadata2 === void 0 ? void 0 : _child$src$metadata2.height
99
+ width: child.src.width,
100
+ height: child.src.height
102
101
  });
103
102
  }
104
103
  var children = "children" in child ?
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var raw = require('../../dist/raw-af73dda7.cjs.dev.js');
5
+ var raw = require('../../dist/raw-9e45e445.cjs.dev.js');
6
6
  var React = require('react');
7
7
  var ReactJSXRuntime = require('react/jsx-runtime');
8
8
  require('../../dist/slicedToArray-e9e8e991.cjs.dev.js');
@@ -95,7 +95,6 @@ function ValRichText(_ref) {
95
95
  }
96
96
  var className = classNameOfTag(child.tag, child.tag === "span" ? child.styles : [], theme);
97
97
  if (child.tag === "img") {
98
- var _child$src$metadata, _child$src$metadata2;
99
98
  var _transformed = transform && transform(child, [], undefined, key);
100
99
  if (_transformed !== undefined) {
101
100
  return _transformed;
@@ -105,8 +104,8 @@ function ValRichText(_ref) {
105
104
  className: className,
106
105
  src: child.src.url,
107
106
  // alt: child.alt, TODO: add alt to the img html object
108
- width: (_child$src$metadata = child.src.metadata) === null || _child$src$metadata === void 0 ? void 0 : _child$src$metadata.width,
109
- height: (_child$src$metadata2 = child.src.metadata) === null || _child$src$metadata2 === void 0 ? void 0 : _child$src$metadata2.height
107
+ width: child.src.width,
108
+ height: child.src.height
110
109
  });
111
110
  }
112
111
  var children = "children" in child ?
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var raw = require('../../dist/raw-bac58cc7.cjs.prod.js');
5
+ var raw = require('../../dist/raw-18eb953f.cjs.prod.js');
6
6
  var React = require('react');
7
7
  var ReactJSXRuntime = require('react/jsx-runtime');
8
8
  require('../../dist/slicedToArray-86004d59.cjs.prod.js');
@@ -95,7 +95,6 @@ function ValRichText(_ref) {
95
95
  }
96
96
  var className = classNameOfTag(child.tag, child.tag === "span" ? child.styles : [], theme);
97
97
  if (child.tag === "img") {
98
- var _child$src$metadata, _child$src$metadata2;
99
98
  var _transformed = transform && transform(child, [], undefined, key);
100
99
  if (_transformed !== undefined) {
101
100
  return _transformed;
@@ -105,8 +104,8 @@ function ValRichText(_ref) {
105
104
  className: className,
106
105
  src: child.src.url,
107
106
  // alt: child.alt, TODO: add alt to the img html object
108
- width: (_child$src$metadata = child.src.metadata) === null || _child$src$metadata === void 0 ? void 0 : _child$src$metadata.width,
109
- height: (_child$src$metadata2 = child.src.metadata) === null || _child$src$metadata2 === void 0 ? void 0 : _child$src$metadata2.height
107
+ width: child.src.width,
108
+ height: child.src.height
110
109
  });
111
110
  }
112
111
  var children = "children" in child ?
@@ -1,4 +1,4 @@
1
- import { d as _objectSpread2, r as raw, c as attrs, e as _toConsumableArray } from '../../dist/raw-e561ced7.esm.js';
1
+ import { d as _objectSpread2, r as raw, c as attrs, e as _toConsumableArray } from '../../dist/raw-628bf5e1.esm.js';
2
2
  import React from 'react';
3
3
  import { jsx } from 'react/jsx-runtime';
4
4
  import '../../dist/slicedToArray-0c0a3b4a.esm.js';
@@ -87,7 +87,6 @@ function ValRichText(_ref) {
87
87
  }
88
88
  var className = classNameOfTag(child.tag, child.tag === "span" ? child.styles : [], theme);
89
89
  if (child.tag === "img") {
90
- var _child$src$metadata, _child$src$metadata2;
91
90
  var _transformed = transform && transform(child, [], undefined, key);
92
91
  if (_transformed !== undefined) {
93
92
  return _transformed;
@@ -97,8 +96,8 @@ function ValRichText(_ref) {
97
96
  className: className,
98
97
  src: child.src.url,
99
98
  // alt: child.alt, TODO: add alt to the img html object
100
- width: (_child$src$metadata = child.src.metadata) === null || _child$src$metadata === void 0 ? void 0 : _child$src$metadata.width,
101
- height: (_child$src$metadata2 = child.src.metadata) === null || _child$src$metadata2 === void 0 ? void 0 : _child$src$metadata2.height
99
+ width: child.src.width,
100
+ height: child.src.height
102
101
  });
103
102
  }
104
103
  var children = "children" in child ?
@@ -1,4 +1,4 @@
1
- import { d as _objectSpread2, r as raw, c as attrs, e as _toConsumableArray } from '../../dist/raw-a20b5f53.worker.esm.js';
1
+ import { d as _objectSpread2, r as raw, c as attrs, e as _toConsumableArray } from '../../dist/raw-5a505416.worker.esm.js';
2
2
  import React from 'react';
3
3
  import { jsx } from 'react/jsx-runtime';
4
4
  import '../../dist/slicedToArray-7d0170b6.worker.esm.js';
@@ -87,7 +87,6 @@ function ValRichText(_ref) {
87
87
  }
88
88
  var className = classNameOfTag(child.tag, child.tag === "span" ? child.styles : [], theme);
89
89
  if (child.tag === "img") {
90
- var _child$src$metadata, _child$src$metadata2;
91
90
  var _transformed = transform && transform(child, [], undefined, key);
92
91
  if (_transformed !== undefined) {
93
92
  return _transformed;
@@ -97,8 +96,8 @@ function ValRichText(_ref) {
97
96
  className: className,
98
97
  src: child.src.url,
99
98
  // alt: child.alt, TODO: add alt to the img html object
100
- width: (_child$src$metadata = child.src.metadata) === null || _child$src$metadata === void 0 ? void 0 : _child$src$metadata.width,
101
- height: (_child$src$metadata2 = child.src.metadata) === null || _child$src$metadata2 === void 0 ? void 0 : _child$src$metadata2.height
99
+ width: child.src.width,
100
+ height: child.src.height
102
101
  });
103
102
  }
104
103
  var children = "children" in child ?
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@valbuild/react",
3
- "version": "0.101.1",
3
+ "version": "0.103.0",
4
4
  "private": false,
5
5
  "description": "Val - React internal helpers",
6
6
  "repository": {
@@ -11,21 +11,21 @@
11
11
  "dependencies": {
12
12
  "@vercel/stega": "^0.1.0",
13
13
  "base64-arraybuffer": "^1.0.2",
14
- "@valbuild/core": "0.101.0",
15
- "@valbuild/shared": "0.101.1",
16
- "@valbuild/ui": "0.101.1"
14
+ "@valbuild/core": "0.103.0",
15
+ "@valbuild/shared": "0.103.0",
16
+ "@valbuild/ui": "0.103.0"
17
17
  },
18
18
  "devDependencies": {
19
- "@testing-library/react": "^14.0.0",
20
- "@types/react": "^18.2.38",
19
+ "@testing-library/react": "^16.3.2",
20
+ "@types/react": "^19.2.18",
21
21
  "jest-environment-jsdom": "^29.5.0",
22
- "react": "^18.2.0",
23
- "react-dom": "^18.2.0",
22
+ "react": "^19.2.8",
23
+ "react-dom": "^19.2.8",
24
24
  "typescript": "^5.9.3"
25
25
  },
26
26
  "peerDependencies": {
27
- "react": ">=18.2.0 || ^19.0 || ^19.0.0-rc",
28
- "react-dom": ">=18.2.0 || ^19.0 || ^19.0.0-rc"
27
+ "react": ">=19.0.0",
28
+ "react-dom": ">=19.0.0"
29
29
  },
30
30
  "peerDependenciesMeta": {
31
31
  "@types/react": {
@@ -1,6 +1,6 @@
1
1
  import { a as _typeof, _ as _slicedToArray } from '../../dist/slicedToArray-9cce0d9f.browser.esm.js';
2
- import { s as stegaDecodeStrings, _ as _createForOfIteratorHelper } from '../../dist/raw-0293ccee.browser.esm.js';
3
- export { c as attrs, g as getModuleIds, r as raw, b as stegaClean, s as stegaDecodeStrings, a as stegaEncode } from '../../dist/raw-0293ccee.browser.esm.js';
2
+ import { s as stegaDecodeStrings, _ as _createForOfIteratorHelper } from '../../dist/raw-31c1b7d6.browser.esm.js';
3
+ export { c as attrs, g as getModuleIds, r as raw, b as stegaClean, s as stegaDecodeStrings, a as stegaEncode } from '../../dist/raw-31c1b7d6.browser.esm.js';
4
4
  import ReactJSXRuntime__default from 'react/jsx-runtime';
5
5
  import jsxRuntimeDev__default from 'react/jsx-dev-runtime';
6
6
  import React from 'react';
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var slicedToArray = require('../../dist/slicedToArray-e9e8e991.cjs.dev.js');
6
- var raw = require('../../dist/raw-af73dda7.cjs.dev.js');
6
+ var raw = require('../../dist/raw-9e45e445.cjs.dev.js');
7
7
  var ReactJSXRuntime = require('react/jsx-runtime');
8
8
  var jsxRuntimeDev = require('react/jsx-dev-runtime');
9
9
  var React = require('react');
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var slicedToArray = require('../../dist/slicedToArray-86004d59.cjs.prod.js');
6
- var raw = require('../../dist/raw-bac58cc7.cjs.prod.js');
6
+ var raw = require('../../dist/raw-18eb953f.cjs.prod.js');
7
7
  var ReactJSXRuntime = require('react/jsx-runtime');
8
8
  var jsxRuntimeDev = require('react/jsx-dev-runtime');
9
9
  var React = require('react');
@@ -1,6 +1,6 @@
1
1
  import { a as _typeof, _ as _slicedToArray } from '../../dist/slicedToArray-0c0a3b4a.esm.js';
2
- import { s as stegaDecodeStrings, _ as _createForOfIteratorHelper } from '../../dist/raw-e561ced7.esm.js';
3
- export { c as attrs, g as getModuleIds, r as raw, b as stegaClean, s as stegaDecodeStrings, a as stegaEncode } from '../../dist/raw-e561ced7.esm.js';
2
+ import { s as stegaDecodeStrings, _ as _createForOfIteratorHelper } from '../../dist/raw-628bf5e1.esm.js';
3
+ export { c as attrs, g as getModuleIds, r as raw, b as stegaClean, s as stegaDecodeStrings, a as stegaEncode } from '../../dist/raw-628bf5e1.esm.js';
4
4
  import ReactJSXRuntime__default from 'react/jsx-runtime';
5
5
  import jsxRuntimeDev__default from 'react/jsx-dev-runtime';
6
6
  import React from 'react';
@@ -1,6 +1,6 @@
1
1
  import { a as _typeof, _ as _slicedToArray } from '../../dist/slicedToArray-7d0170b6.worker.esm.js';
2
- import { s as stegaDecodeStrings, _ as _createForOfIteratorHelper } from '../../dist/raw-a20b5f53.worker.esm.js';
3
- export { c as attrs, g as getModuleIds, r as raw, b as stegaClean, s as stegaDecodeStrings, a as stegaEncode } from '../../dist/raw-a20b5f53.worker.esm.js';
2
+ import { s as stegaDecodeStrings, _ as _createForOfIteratorHelper } from '../../dist/raw-5a505416.worker.esm.js';
3
+ export { c as attrs, g as getModuleIds, r as raw, b as stegaClean, s as stegaDecodeStrings, a as stegaEncode } from '../../dist/raw-5a505416.worker.esm.js';
4
4
  import ReactJSXRuntime__default from 'react/jsx-runtime';
5
5
  import jsxRuntimeDev__default from 'react/jsx-dev-runtime';
6
6
  import React from 'react';