webstudio 0.292.0 → 0.293.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/lib/cli.js CHANGED
@@ -749,7 +749,7 @@ const baseAsset = {
749
749
  createdAt: z$4.string(),
750
750
  updatedAt: z$4.string().optional()
751
751
  };
752
- const assetType = z$4.enum(["font", "image", "file"]);
752
+ const assetType = z$4.enum(["font", "image", "video", "file"]);
753
753
  const fontAsset = z$4.object({
754
754
  ...baseAsset,
755
755
  format: fontFormat,
@@ -760,6 +760,10 @@ const imageMeta = z$4.object({
760
760
  width: z$4.number(),
761
761
  height: z$4.number()
762
762
  });
763
+ const videoMeta = z$4.object({
764
+ width: z$4.number(),
765
+ height: z$4.number()
766
+ });
763
767
  const assetMetaUpdate = z$4.union([
764
768
  fontMetaUpdate,
765
769
  imageMeta.partial().strict(),
@@ -771,15 +775,22 @@ const imageAsset = z$4.object({
771
775
  meta: imageMeta,
772
776
  type: z$4.literal(assetType.enum.image)
773
777
  });
778
+ const videoAsset = z$4.object({
779
+ ...baseAsset,
780
+ format: z$4.string(),
781
+ meta: videoMeta,
782
+ type: z$4.literal(assetType.enum.video)
783
+ });
774
784
  const fileAsset = z$4.object({
775
785
  ...baseAsset,
776
786
  format: z$4.string(),
777
787
  meta: z$4.object({}),
778
788
  type: z$4.literal(assetType.enum.file)
779
789
  });
780
- const asset$1 = z$4.union([fontAsset, imageAsset, fileAsset]);
790
+ const asset$1 = z$4.union([fontAsset, imageAsset, videoAsset, fileAsset]);
781
791
  const assetMetaSchemas = {
782
792
  image: imageMeta,
793
+ video: videoMeta,
783
794
  file: z$4.object({})
784
795
  };
785
796
  const mergeAssetMeta = (type2, current4, override) => {
@@ -8142,7 +8153,8 @@ const contentArtifactV1 = strictObject({
8142
8153
  strictObject({
8143
8154
  path: array(string$5().min(1).or(number$3().int().nonnegative())).min(1),
8144
8155
  assetId: string$5().min(1),
8145
- suffix: string$5().min(1).optional()
8156
+ suffix: string$5().min(1).optional(),
8157
+ structured: literal$2(true).optional()
8146
8158
  })
8147
8159
  )
8148
8160
  ).optional(),
@@ -9174,6 +9186,17 @@ const normalizeAssetFileDocument = ({
9174
9186
  ...metadataError === void 0 ? {} : { metadataError }
9175
9187
  });
9176
9188
  };
9189
+ const isJsonObject$1 = (value2) => typeof value2 === "object" && value2 !== null && Array.isArray(value2) === false;
9190
+ const getJsonReferenceMarkerValue = (value2) => {
9191
+ if (isJsonObject$1(value2) === false) {
9192
+ return;
9193
+ }
9194
+ const keys2 = Object.keys(value2);
9195
+ if (keys2.length !== 1 || keys2[0] !== "$ref") {
9196
+ return;
9197
+ }
9198
+ return value2.$ref;
9199
+ };
9177
9200
  const selectAssetDocumentFields = ({
9178
9201
  document: document2,
9179
9202
  includes
@@ -9187,64 +9210,42 @@ const selectAssetDocumentFields = ({
9187
9210
  }
9188
9211
  return selected;
9189
9212
  };
9190
- const selectPropertyPath = ({
9191
- source,
9192
- target,
9193
- path: path2
9194
- }) => {
9195
- const [key2, ...rest] = path2;
9196
- if (key2 === void 0 || Object.hasOwn(source, key2) === false) {
9197
- return;
9213
+ const missing = Symbol("missing property selection");
9214
+ const selectValuePaths = (value2, paths) => {
9215
+ if (paths.some((path2) => path2.length === 0) || typeof getJsonReferenceMarkerValue(value2) === "string") {
9216
+ return value2;
9198
9217
  }
9199
- const value2 = source[key2];
9200
- if (rest.length === 0) {
9201
- Object.defineProperty(target, key2, {
9202
- value: value2,
9203
- enumerable: true,
9204
- configurable: true,
9205
- writable: true
9206
- });
9207
- return;
9218
+ if (Array.isArray(value2)) {
9219
+ const childPaths = paths.filter(([segment]) => segment === "*").map((path2) => path2.slice(1));
9220
+ if (childPaths.length === 0) {
9221
+ return missing;
9222
+ }
9223
+ const selected2 = value2.map((item) => selectValuePaths(item, childPaths));
9224
+ return selected2.some((item) => item !== missing) ? selected2.map((item) => item === missing ? null : item) : missing;
9208
9225
  }
9209
- if (typeof value2 !== "object" || value2 === null || Array.isArray(value2)) {
9210
- return;
9226
+ if (typeof value2 !== "object" || value2 === null) {
9227
+ return missing;
9211
9228
  }
9212
9229
  const selected = {};
9213
- selectPropertyPath({
9214
- source: value2,
9215
- target: selected,
9216
- path: rest
9217
- });
9218
- if (Object.keys(selected).length === 0) {
9219
- return;
9230
+ for (const [key2, item] of Object.entries(value2)) {
9231
+ const childPaths = paths.filter(([segment]) => segment === key2).map((path2) => path2.slice(1));
9232
+ if (childPaths.length === 0) {
9233
+ continue;
9234
+ }
9235
+ const child = selectValuePaths(item, childPaths);
9236
+ if (child !== missing) {
9237
+ selected[key2] = child;
9238
+ }
9220
9239
  }
9221
- const existing = target[key2];
9222
- Object.defineProperty(target, key2, {
9223
- value: {
9224
- ...typeof existing === "object" && existing !== null && Array.isArray(existing) === false ? existing : {},
9225
- ...selected
9226
- },
9227
- enumerable: true,
9228
- configurable: true,
9229
- writable: true
9230
- });
9240
+ return Object.keys(selected).length === 0 ? missing : selected;
9231
9241
  };
9232
9242
  const selectAssetProperties = ({
9233
9243
  properties: properties2,
9234
9244
  fields
9235
9245
  }) => {
9236
- const selected = {};
9237
- for (const field of fields) {
9238
- if (field[0] !== "properties") {
9239
- continue;
9240
- }
9241
- selectPropertyPath({
9242
- source: properties2,
9243
- target: selected,
9244
- path: field.slice(1)
9245
- });
9246
- }
9247
- return selected;
9246
+ const paths = fields.filter(([root2]) => root2 === "properties").map((field) => field.slice(1));
9247
+ const selected = selectValuePaths(properties2, paths);
9248
+ return selected === missing ? {} : selected;
9248
9249
  };
9249
9250
  const createUniqueAssetIdsByPath = (assets) => {
9250
9251
  const ambiguousPaths = /* @__PURE__ */ new Set();
@@ -9355,7 +9356,8 @@ const getUrlSuffix = (value2) => {
9355
9356
  const discoverAssetValueReferences = ({
9356
9357
  properties: properties2,
9357
9358
  sourcePath,
9358
- assetIdsByPath
9359
+ assetIdsByPath,
9360
+ structuredAssetIds
9359
9361
  }) => {
9360
9362
  const resolveAssetId = createAssetIdResolver(assetIdsByPath, sourcePath);
9361
9363
  const references = [];
@@ -9372,6 +9374,20 @@ const discoverAssetValueReferences = ({
9372
9374
  }
9373
9375
  return;
9374
9376
  }
9377
+ const marker = getJsonReferenceMarkerValue(value2);
9378
+ if (typeof marker === "string") {
9379
+ const assetId2 = resolveAssetId(marker);
9380
+ if (assetId2 !== void 0 && structuredAssetIds?.has(assetId2)) {
9381
+ const suffix = getUrlSuffix(marker);
9382
+ references.push({
9383
+ path: path2,
9384
+ assetId: assetId2,
9385
+ ...suffix === void 0 ? {} : { suffix },
9386
+ structured: true
9387
+ });
9388
+ }
9389
+ return;
9390
+ }
9375
9391
  if (Array.isArray(value2)) {
9376
9392
  for (const [index2, item] of value2.entries()) {
9377
9393
  visit2(item, [...path2, index2]);
@@ -9445,21 +9461,34 @@ const replaceValueAtPath = ({
9445
9461
  })
9446
9462
  };
9447
9463
  };
9464
+ const toStructuredAssetValue = ({
9465
+ reference,
9466
+ runtimeAsset
9467
+ }) => {
9468
+ const { url: url2, contentRef: _contentRef, ...asset2 } = runtimeAsset;
9469
+ return {
9470
+ ...asset2,
9471
+ id: reference.assetId,
9472
+ src: mergeAssetUrlSuffix(url2, reference.suffix)
9473
+ };
9474
+ };
9448
9475
  const resolveAssetValueReferences = ({
9449
9476
  value: value2,
9450
9477
  references,
9478
+ runtimeAssets = {},
9451
9479
  assetUrls
9452
9480
  }) => {
9453
9481
  let resolved = value2;
9454
9482
  for (const reference of references ?? []) {
9455
- const assetUrl = assetUrls[reference.assetId];
9456
- if (assetUrl === void 0) {
9483
+ const assetUrl = assetUrls?.[reference.assetId];
9484
+ const runtimeAsset = runtimeAssets[reference.assetId] ?? (assetUrl === void 0 ? void 0 : { url: assetUrl });
9485
+ if (runtimeAsset === void 0) {
9457
9486
  continue;
9458
9487
  }
9459
9488
  resolved = replaceValueAtPath({
9460
9489
  value: resolved,
9461
9490
  path: reference.path,
9462
- replacement: mergeAssetUrlSuffix(assetUrl, reference.suffix)
9491
+ replacement: reference.structured === true ? toStructuredAssetValue({ reference, runtimeAsset }) : mergeAssetUrlSuffix(runtimeAsset.url, reference.suffix)
9463
9492
  });
9464
9493
  }
9465
9494
  return resolved;
@@ -9915,14 +9944,13 @@ const executeAssetQueries = async ({
9915
9944
  });
9916
9945
  return requireSettledAssetQueryResults(results);
9917
9946
  }
9918
- const assetUrls = getRuntimeAssetUrls(runtimeAssets);
9919
9947
  let resolvedDocuments;
9920
9948
  try {
9921
9949
  resolvedDocuments = documents.map(
9922
9950
  (document2) => resolveAssetValueReferences({
9923
9951
  value: document2,
9924
9952
  references: assetValueReferences?.[document2._id],
9925
- assetUrls
9953
+ runtimeAssets: runtimeAssets ?? {}
9926
9954
  })
9927
9955
  );
9928
9956
  } catch (error) {
@@ -9941,6 +9969,7 @@ const executeAssetQueries = async ({
9941
9969
  results,
9942
9970
  runtimeAssets
9943
9971
  });
9972
+ const assetUrls = getRuntimeAssetUrls(runtimeAssets);
9944
9973
  await finalizeAssetQueries({
9945
9974
  preparedQueries,
9946
9975
  results,
@@ -9963,17 +9992,6 @@ async function executeAssetQuery({
9963
9992
  }
9964
9993
  return result2.value;
9965
9994
  }
9966
- const isJsonObject$1 = (value2) => typeof value2 === "object" && value2 !== null && Array.isArray(value2) === false;
9967
- const getJsonReferenceMarkerValue = (value2) => {
9968
- if (isJsonObject$1(value2) === false) {
9969
- return;
9970
- }
9971
- const keys2 = Object.keys(value2);
9972
- if (keys2.length !== 1 || keys2[0] !== "$ref") {
9973
- return;
9974
- }
9975
- return value2.$ref;
9976
- };
9977
9995
  const compareContentEntryPriority = (left, right) => {
9978
9996
  const leftCreatedAt = left.document.createdAt === void 0 ? void 0 : Date.parse(left.document.createdAt);
9979
9997
  const rightCreatedAt = right.document.createdAt === void 0 ? void 0 : Date.parse(right.document.createdAt);
@@ -17094,6 +17112,7 @@ const compileDocumentSourceGraph = async ({
17094
17112
  rootIds,
17095
17113
  concurrency = contentEngineLimits.concurrentContentReads,
17096
17114
  maximumBytes = contentEngineLimits.hydratedFileBytes,
17115
+ ignoredReferenceUrls,
17097
17116
  signal
17098
17117
  }) => {
17099
17118
  assertActive(signal);
@@ -17147,8 +17166,11 @@ const compileDocumentSourceGraph = async ({
17147
17166
  analyzedIds.add(document2.id);
17148
17167
  }
17149
17168
  for (const result2 of analyzed) {
17150
- references.push(...result2.references);
17151
17169
  for (const occurrence of result2.references) {
17170
+ if (ignoredReferenceUrls?.has(occurrence.reference.documentUrl)) {
17171
+ continue;
17172
+ }
17173
+ references.push(occurrence);
17152
17174
  const target = documentsByUrl.get(occurrence.reference.documentUrl);
17153
17175
  if (target !== void 0 && analyzedIds.has(target.id) === false) {
17154
17176
  pendingIds.add(target.id);
@@ -24520,7 +24542,9 @@ const resource$1 = z$4.object({
24520
24542
  ...common,
24521
24543
  control: z$4.literal("resource"),
24522
24544
  type: z$4.literal("resource"),
24523
- defaultValue: z$4.string().optional()
24545
+ defaultValue: z$4.string().optional(),
24546
+ // Safe resource fields copied to same-named props in generated components.
24547
+ generatedProps: z$4.array(z$4.enum(["method"])).optional()
24524
24548
  });
24525
24549
  const code$3 = z$4.object({
24526
24550
  ...common,
@@ -24911,6 +24935,24 @@ const getMimeTypeByFilename = (fileName) => {
24911
24935
  return getMimeTypeByExtension(extension2) ?? "application/octet-stream";
24912
24936
  };
24913
24937
  const isResizableImageFileName = (fileName) => RESIZABLE_IMAGE_MIME_TYPES.includes(getMimeTypeByFilename(fileName));
24938
+ const getAssetMime = ({
24939
+ type: type2,
24940
+ format: format2
24941
+ }) => {
24942
+ const lowerFormat = format2.toLowerCase();
24943
+ const mime = `${type2}/${lowerFormat}`;
24944
+ if (mimeTypes.has(mime)) {
24945
+ return mime;
24946
+ }
24947
+ const mime2 = extensionToMime.get(`.${lowerFormat}`);
24948
+ if (mime2 === void 0) {
24949
+ warnOnce$1(
24950
+ true,
24951
+ `Couldn't determine mime type of asset: ${type2}, ${format2}.`
24952
+ );
24953
+ }
24954
+ return mime2;
24955
+ };
24914
24956
  const getAssetUrl = (asset2, origin) => {
24915
24957
  const path2 = isResizableImageFileName(asset2.name) ? `/cgi/image/${asset2.name}?format=raw` : `/cgi/asset/${asset2.name}?format=raw`;
24916
24958
  return new URL(path2, origin);
@@ -24939,12 +24981,24 @@ const extractFontMetadata = (asset2) => {
24939
24981
  }
24940
24982
  return metadata;
24941
24983
  };
24984
+ const extractVideoMetadata = (asset2) => {
24985
+ if (asset2.type !== "video") {
24986
+ return;
24987
+ }
24988
+ if (asset2.meta.width && asset2.meta.height) {
24989
+ return {
24990
+ width: asset2.meta.width,
24991
+ height: asset2.meta.height
24992
+ };
24993
+ }
24994
+ };
24942
24995
  const extractFileMetadata = (_asset) => {
24943
24996
  return;
24944
24997
  };
24945
24998
  const metadataExtractors = {
24946
24999
  image: extractImageMetadata,
24947
25000
  font: extractFontMetadata,
25001
+ video: extractVideoMetadata,
24948
25002
  file: extractFileMetadata
24949
25003
  };
24950
25004
  const toRuntimeAsset = (asset2, origin) => {
@@ -24957,6 +25011,15 @@ const toRuntimeAsset = (asset2, origin) => {
24957
25011
  ...metadata
24958
25012
  };
24959
25013
  };
25014
+ const toAssetReferenceRuntimeData = (asset2, origin) => {
25015
+ const name2 = formatAssetName(asset2);
25016
+ return {
25017
+ ...asset2,
25018
+ ...toRuntimeAsset(asset2, origin),
25019
+ name: name2,
25020
+ mimeType: getAssetMime(asset2) ?? getMimeTypeByFilename(name2)
25021
+ };
25022
+ };
24960
25023
  const createJsonStringifyProxy = (target) => {
24961
25024
  return new Proxy(target, {
24962
25025
  get(target2, prop2, receiver) {
@@ -31023,6 +31086,72 @@ const runtimeOperationContractData = [
31023
31086
  "type"
31024
31087
  ]
31025
31088
  },
31089
+ {
31090
+ type: "object",
31091
+ properties: {
31092
+ id: {
31093
+ type: "string"
31094
+ },
31095
+ size: {
31096
+ type: "number"
31097
+ },
31098
+ name: {
31099
+ type: "string"
31100
+ },
31101
+ filename: {
31102
+ type: "string"
31103
+ },
31104
+ description: {
31105
+ anyOf: [
31106
+ {
31107
+ type: "string"
31108
+ },
31109
+ {
31110
+ type: "null"
31111
+ }
31112
+ ]
31113
+ },
31114
+ folderId: {
31115
+ type: "string",
31116
+ minLength: 1,
31117
+ maxLength: 256
31118
+ },
31119
+ createdAt: {
31120
+ type: "string"
31121
+ },
31122
+ updatedAt: {
31123
+ type: "string"
31124
+ },
31125
+ format: {
31126
+ type: "string"
31127
+ },
31128
+ meta: {
31129
+ type: "object",
31130
+ properties: {
31131
+ width: {
31132
+ type: "number"
31133
+ },
31134
+ height: {
31135
+ type: "number"
31136
+ }
31137
+ },
31138
+ required: ["width", "height"]
31139
+ },
31140
+ type: {
31141
+ type: "string",
31142
+ const: "video"
31143
+ }
31144
+ },
31145
+ required: [
31146
+ "id",
31147
+ "size",
31148
+ "name",
31149
+ "createdAt",
31150
+ "format",
31151
+ "meta",
31152
+ "type"
31153
+ ]
31154
+ },
31026
31155
  {
31027
31156
  type: "object",
31028
31157
  properties: {
@@ -34115,6 +34244,72 @@ const runtimeOperationContractData = [
34115
34244
  "type"
34116
34245
  ]
34117
34246
  },
34247
+ {
34248
+ type: "object",
34249
+ properties: {
34250
+ id: {
34251
+ type: "string"
34252
+ },
34253
+ size: {
34254
+ type: "number"
34255
+ },
34256
+ name: {
34257
+ type: "string"
34258
+ },
34259
+ filename: {
34260
+ type: "string"
34261
+ },
34262
+ description: {
34263
+ anyOf: [
34264
+ {
34265
+ type: "string"
34266
+ },
34267
+ {
34268
+ type: "null"
34269
+ }
34270
+ ]
34271
+ },
34272
+ folderId: {
34273
+ type: "string",
34274
+ minLength: 1,
34275
+ maxLength: 256
34276
+ },
34277
+ createdAt: {
34278
+ type: "string"
34279
+ },
34280
+ updatedAt: {
34281
+ type: "string"
34282
+ },
34283
+ format: {
34284
+ type: "string"
34285
+ },
34286
+ meta: {
34287
+ type: "object",
34288
+ properties: {
34289
+ width: {
34290
+ type: "number"
34291
+ },
34292
+ height: {
34293
+ type: "number"
34294
+ }
34295
+ },
34296
+ required: ["width", "height"]
34297
+ },
34298
+ type: {
34299
+ type: "string",
34300
+ const: "video"
34301
+ }
34302
+ },
34303
+ required: [
34304
+ "id",
34305
+ "size",
34306
+ "name",
34307
+ "createdAt",
34308
+ "format",
34309
+ "meta",
34310
+ "type"
34311
+ ]
34312
+ },
34118
34313
  {
34119
34314
  type: "object",
34120
34315
  properties: {
@@ -37218,6 +37413,72 @@ const runtimeOperationContractData = [
37218
37413
  "type"
37219
37414
  ]
37220
37415
  },
37416
+ {
37417
+ type: "object",
37418
+ properties: {
37419
+ id: {
37420
+ type: "string"
37421
+ },
37422
+ size: {
37423
+ type: "number"
37424
+ },
37425
+ name: {
37426
+ type: "string"
37427
+ },
37428
+ filename: {
37429
+ type: "string"
37430
+ },
37431
+ description: {
37432
+ anyOf: [
37433
+ {
37434
+ type: "string"
37435
+ },
37436
+ {
37437
+ type: "null"
37438
+ }
37439
+ ]
37440
+ },
37441
+ folderId: {
37442
+ type: "string",
37443
+ minLength: 1,
37444
+ maxLength: 256
37445
+ },
37446
+ createdAt: {
37447
+ type: "string"
37448
+ },
37449
+ updatedAt: {
37450
+ type: "string"
37451
+ },
37452
+ format: {
37453
+ type: "string"
37454
+ },
37455
+ meta: {
37456
+ type: "object",
37457
+ properties: {
37458
+ width: {
37459
+ type: "number"
37460
+ },
37461
+ height: {
37462
+ type: "number"
37463
+ }
37464
+ },
37465
+ required: ["width", "height"]
37466
+ },
37467
+ type: {
37468
+ type: "string",
37469
+ const: "video"
37470
+ }
37471
+ },
37472
+ required: [
37473
+ "id",
37474
+ "size",
37475
+ "name",
37476
+ "createdAt",
37477
+ "format",
37478
+ "meta",
37479
+ "type"
37480
+ ]
37481
+ },
37221
37482
  {
37222
37483
  type: "object",
37223
37484
  properties: {
@@ -40310,6 +40571,72 @@ const runtimeOperationContractData = [
40310
40571
  "type"
40311
40572
  ]
40312
40573
  },
40574
+ {
40575
+ type: "object",
40576
+ properties: {
40577
+ id: {
40578
+ type: "string"
40579
+ },
40580
+ size: {
40581
+ type: "number"
40582
+ },
40583
+ name: {
40584
+ type: "string"
40585
+ },
40586
+ filename: {
40587
+ type: "string"
40588
+ },
40589
+ description: {
40590
+ anyOf: [
40591
+ {
40592
+ type: "string"
40593
+ },
40594
+ {
40595
+ type: "null"
40596
+ }
40597
+ ]
40598
+ },
40599
+ folderId: {
40600
+ type: "string",
40601
+ minLength: 1,
40602
+ maxLength: 256
40603
+ },
40604
+ createdAt: {
40605
+ type: "string"
40606
+ },
40607
+ updatedAt: {
40608
+ type: "string"
40609
+ },
40610
+ format: {
40611
+ type: "string"
40612
+ },
40613
+ meta: {
40614
+ type: "object",
40615
+ properties: {
40616
+ width: {
40617
+ type: "number"
40618
+ },
40619
+ height: {
40620
+ type: "number"
40621
+ }
40622
+ },
40623
+ required: ["width", "height"]
40624
+ },
40625
+ type: {
40626
+ type: "string",
40627
+ const: "video"
40628
+ }
40629
+ },
40630
+ required: [
40631
+ "id",
40632
+ "size",
40633
+ "name",
40634
+ "createdAt",
40635
+ "format",
40636
+ "meta",
40637
+ "type"
40638
+ ]
40639
+ },
40313
40640
  {
40314
40641
  type: "object",
40315
40642
  properties: {
@@ -46114,6 +46441,72 @@ const runtimeOperationContractData = [
46114
46441
  "type"
46115
46442
  ]
46116
46443
  },
46444
+ {
46445
+ type: "object",
46446
+ properties: {
46447
+ id: {
46448
+ type: "string"
46449
+ },
46450
+ size: {
46451
+ type: "number"
46452
+ },
46453
+ name: {
46454
+ type: "string"
46455
+ },
46456
+ filename: {
46457
+ type: "string"
46458
+ },
46459
+ description: {
46460
+ anyOf: [
46461
+ {
46462
+ type: "string"
46463
+ },
46464
+ {
46465
+ type: "null"
46466
+ }
46467
+ ]
46468
+ },
46469
+ folderId: {
46470
+ type: "string",
46471
+ minLength: 1,
46472
+ maxLength: 256
46473
+ },
46474
+ createdAt: {
46475
+ type: "string"
46476
+ },
46477
+ updatedAt: {
46478
+ type: "string"
46479
+ },
46480
+ format: {
46481
+ type: "string"
46482
+ },
46483
+ meta: {
46484
+ type: "object",
46485
+ properties: {
46486
+ width: {
46487
+ type: "number"
46488
+ },
46489
+ height: {
46490
+ type: "number"
46491
+ }
46492
+ },
46493
+ required: ["width", "height"]
46494
+ },
46495
+ type: {
46496
+ type: "string",
46497
+ const: "video"
46498
+ }
46499
+ },
46500
+ required: [
46501
+ "id",
46502
+ "size",
46503
+ "name",
46504
+ "createdAt",
46505
+ "format",
46506
+ "meta",
46507
+ "type"
46508
+ ]
46509
+ },
46117
46510
  {
46118
46511
  type: "object",
46119
46512
  properties: {
@@ -49251,6 +49644,72 @@ const runtimeOperationContractData = [
49251
49644
  "type"
49252
49645
  ]
49253
49646
  },
49647
+ {
49648
+ type: "object",
49649
+ properties: {
49650
+ id: {
49651
+ type: "string"
49652
+ },
49653
+ size: {
49654
+ type: "number"
49655
+ },
49656
+ name: {
49657
+ type: "string"
49658
+ },
49659
+ filename: {
49660
+ type: "string"
49661
+ },
49662
+ description: {
49663
+ anyOf: [
49664
+ {
49665
+ type: "string"
49666
+ },
49667
+ {
49668
+ type: "null"
49669
+ }
49670
+ ]
49671
+ },
49672
+ folderId: {
49673
+ type: "string",
49674
+ minLength: 1,
49675
+ maxLength: 256
49676
+ },
49677
+ createdAt: {
49678
+ type: "string"
49679
+ },
49680
+ updatedAt: {
49681
+ type: "string"
49682
+ },
49683
+ format: {
49684
+ type: "string"
49685
+ },
49686
+ meta: {
49687
+ type: "object",
49688
+ properties: {
49689
+ width: {
49690
+ type: "number"
49691
+ },
49692
+ height: {
49693
+ type: "number"
49694
+ }
49695
+ },
49696
+ required: ["width", "height"]
49697
+ },
49698
+ type: {
49699
+ type: "string",
49700
+ const: "video"
49701
+ }
49702
+ },
49703
+ required: [
49704
+ "id",
49705
+ "size",
49706
+ "name",
49707
+ "createdAt",
49708
+ "format",
49709
+ "meta",
49710
+ "type"
49711
+ ]
49712
+ },
49254
49713
  {
49255
49714
  type: "object",
49256
49715
  properties: {
@@ -63606,6 +64065,72 @@ const runtimeOperationContractData = [
63606
64065
  "type"
63607
64066
  ]
63608
64067
  },
64068
+ {
64069
+ type: "object",
64070
+ properties: {
64071
+ id: {
64072
+ type: "string"
64073
+ },
64074
+ size: {
64075
+ type: "number"
64076
+ },
64077
+ name: {
64078
+ type: "string"
64079
+ },
64080
+ filename: {
64081
+ type: "string"
64082
+ },
64083
+ description: {
64084
+ anyOf: [
64085
+ {
64086
+ type: "string"
64087
+ },
64088
+ {
64089
+ type: "null"
64090
+ }
64091
+ ]
64092
+ },
64093
+ folderId: {
64094
+ type: "string",
64095
+ minLength: 1,
64096
+ maxLength: 256
64097
+ },
64098
+ createdAt: {
64099
+ type: "string"
64100
+ },
64101
+ updatedAt: {
64102
+ type: "string"
64103
+ },
64104
+ format: {
64105
+ type: "string"
64106
+ },
64107
+ meta: {
64108
+ type: "object",
64109
+ properties: {
64110
+ width: {
64111
+ type: "number"
64112
+ },
64113
+ height: {
64114
+ type: "number"
64115
+ }
64116
+ },
64117
+ required: ["width", "height"]
64118
+ },
64119
+ type: {
64120
+ type: "string",
64121
+ const: "video"
64122
+ }
64123
+ },
64124
+ required: [
64125
+ "id",
64126
+ "size",
64127
+ "name",
64128
+ "createdAt",
64129
+ "format",
64130
+ "meta",
64131
+ "type"
64132
+ ]
64133
+ },
63609
64134
  {
63610
64135
  type: "object",
63611
64136
  properties: {
@@ -66772,6 +67297,72 @@ const runtimeOperationContractData = [
66772
67297
  "type"
66773
67298
  ]
66774
67299
  },
67300
+ {
67301
+ type: "object",
67302
+ properties: {
67303
+ id: {
67304
+ type: "string"
67305
+ },
67306
+ size: {
67307
+ type: "number"
67308
+ },
67309
+ name: {
67310
+ type: "string"
67311
+ },
67312
+ filename: {
67313
+ type: "string"
67314
+ },
67315
+ description: {
67316
+ anyOf: [
67317
+ {
67318
+ type: "string"
67319
+ },
67320
+ {
67321
+ type: "null"
67322
+ }
67323
+ ]
67324
+ },
67325
+ folderId: {
67326
+ type: "string",
67327
+ minLength: 1,
67328
+ maxLength: 256
67329
+ },
67330
+ createdAt: {
67331
+ type: "string"
67332
+ },
67333
+ updatedAt: {
67334
+ type: "string"
67335
+ },
67336
+ format: {
67337
+ type: "string"
67338
+ },
67339
+ meta: {
67340
+ type: "object",
67341
+ properties: {
67342
+ width: {
67343
+ type: "number"
67344
+ },
67345
+ height: {
67346
+ type: "number"
67347
+ }
67348
+ },
67349
+ required: ["width", "height"]
67350
+ },
67351
+ type: {
67352
+ type: "string",
67353
+ const: "video"
67354
+ }
67355
+ },
67356
+ required: [
67357
+ "id",
67358
+ "size",
67359
+ "name",
67360
+ "createdAt",
67361
+ "format",
67362
+ "meta",
67363
+ "type"
67364
+ ]
67365
+ },
66775
67366
  {
66776
67367
  type: "object",
66777
67368
  properties: {
@@ -73039,6 +73630,72 @@ const runtimeOperationContractData = [
73039
73630
  "type"
73040
73631
  ]
73041
73632
  },
73633
+ {
73634
+ type: "object",
73635
+ properties: {
73636
+ id: {
73637
+ type: "string"
73638
+ },
73639
+ size: {
73640
+ type: "number"
73641
+ },
73642
+ name: {
73643
+ type: "string"
73644
+ },
73645
+ filename: {
73646
+ type: "string"
73647
+ },
73648
+ description: {
73649
+ anyOf: [
73650
+ {
73651
+ type: "string"
73652
+ },
73653
+ {
73654
+ type: "null"
73655
+ }
73656
+ ]
73657
+ },
73658
+ folderId: {
73659
+ type: "string",
73660
+ minLength: 1,
73661
+ maxLength: 256
73662
+ },
73663
+ createdAt: {
73664
+ type: "string"
73665
+ },
73666
+ updatedAt: {
73667
+ type: "string"
73668
+ },
73669
+ format: {
73670
+ type: "string"
73671
+ },
73672
+ meta: {
73673
+ type: "object",
73674
+ properties: {
73675
+ width: {
73676
+ type: "number"
73677
+ },
73678
+ height: {
73679
+ type: "number"
73680
+ }
73681
+ },
73682
+ required: ["width", "height"]
73683
+ },
73684
+ type: {
73685
+ type: "string",
73686
+ const: "video"
73687
+ }
73688
+ },
73689
+ required: [
73690
+ "id",
73691
+ "size",
73692
+ "name",
73693
+ "createdAt",
73694
+ "format",
73695
+ "meta",
73696
+ "type"
73697
+ ]
73698
+ },
73042
73699
  {
73043
73700
  type: "object",
73044
73701
  properties: {
@@ -78848,6 +79505,72 @@ const runtimeOperationContractData = [
78848
79505
  "type"
78849
79506
  ]
78850
79507
  },
79508
+ {
79509
+ type: "object",
79510
+ properties: {
79511
+ id: {
79512
+ type: "string"
79513
+ },
79514
+ size: {
79515
+ type: "number"
79516
+ },
79517
+ name: {
79518
+ type: "string"
79519
+ },
79520
+ filename: {
79521
+ type: "string"
79522
+ },
79523
+ description: {
79524
+ anyOf: [
79525
+ {
79526
+ type: "string"
79527
+ },
79528
+ {
79529
+ type: "null"
79530
+ }
79531
+ ]
79532
+ },
79533
+ folderId: {
79534
+ type: "string",
79535
+ minLength: 1,
79536
+ maxLength: 256
79537
+ },
79538
+ createdAt: {
79539
+ type: "string"
79540
+ },
79541
+ updatedAt: {
79542
+ type: "string"
79543
+ },
79544
+ format: {
79545
+ type: "string"
79546
+ },
79547
+ meta: {
79548
+ type: "object",
79549
+ properties: {
79550
+ width: {
79551
+ type: "number"
79552
+ },
79553
+ height: {
79554
+ type: "number"
79555
+ }
79556
+ },
79557
+ required: ["width", "height"]
79558
+ },
79559
+ type: {
79560
+ type: "string",
79561
+ const: "video"
79562
+ }
79563
+ },
79564
+ required: [
79565
+ "id",
79566
+ "size",
79567
+ "name",
79568
+ "createdAt",
79569
+ "format",
79570
+ "meta",
79571
+ "type"
79572
+ ]
79573
+ },
78851
79574
  {
78852
79575
  type: "object",
78853
79576
  properties: {
@@ -96766,7 +97489,7 @@ const runtimeOperationContractData = [
96766
97489
  properties: {
96767
97490
  type: {
96768
97491
  type: "string",
96769
- enum: ["font", "image", "file"]
97492
+ enum: ["font", "image", "video", "file"]
96770
97493
  },
96771
97494
  sort: {
96772
97495
  type: "string",
@@ -96812,7 +97535,7 @@ const runtimeOperationContractData = [
96812
97535
  },
96813
97536
  type: {
96814
97537
  type: "string",
96815
- enum: ["font", "image", "file"]
97538
+ enum: ["font", "image", "video", "file"]
96816
97539
  },
96817
97540
  size: {
96818
97541
  type: "number"
@@ -96855,7 +97578,7 @@ const runtimeOperationContractData = [
96855
97578
  },
96856
97579
  type: {
96857
97580
  type: "string",
96858
- enum: ["font", "image", "file"]
97581
+ enum: ["font", "image", "video", "file"]
96859
97582
  },
96860
97583
  size: {
96861
97584
  type: "number"
@@ -96993,7 +97716,7 @@ const runtimeOperationContractData = [
96993
97716
  },
96994
97717
  type: {
96995
97718
  type: "string",
96996
- enum: ["font", "image", "file"]
97719
+ enum: ["font", "image", "video", "file"]
96997
97720
  },
96998
97721
  size: {
96999
97722
  type: "number"
@@ -97439,7 +98162,7 @@ const runtimeOperationContractData = [
97439
98162
  required: []
97440
98163
  }
97441
98164
  ],
97442
- description: "Type-specific metadata: family and style plus weight for static fonts or variationAxes for variable fonts, width/height for images, and no fields for generic files."
98165
+ description: "Type-specific metadata: family and style plus weight for static fonts or variationAxes for variable fonts, width/height for images and videos, and no fields for generic files."
97443
98166
  }
97444
98167
  },
97445
98168
  required: []
@@ -97750,6 +98473,72 @@ const runtimeOperationContractData = [
97750
98473
  "type"
97751
98474
  ]
97752
98475
  },
98476
+ {
98477
+ type: "object",
98478
+ properties: {
98479
+ id: {
98480
+ type: "string"
98481
+ },
98482
+ size: {
98483
+ type: "number"
98484
+ },
98485
+ name: {
98486
+ type: "string"
98487
+ },
98488
+ filename: {
98489
+ type: "string"
98490
+ },
98491
+ description: {
98492
+ anyOf: [
98493
+ {
98494
+ type: "string"
98495
+ },
98496
+ {
98497
+ type: "null"
98498
+ }
98499
+ ]
98500
+ },
98501
+ folderId: {
98502
+ type: "string",
98503
+ minLength: 1,
98504
+ maxLength: 256
98505
+ },
98506
+ createdAt: {
98507
+ type: "string"
98508
+ },
98509
+ updatedAt: {
98510
+ type: "string"
98511
+ },
98512
+ format: {
98513
+ type: "string"
98514
+ },
98515
+ meta: {
98516
+ type: "object",
98517
+ properties: {
98518
+ width: {
98519
+ type: "number"
98520
+ },
98521
+ height: {
98522
+ type: "number"
98523
+ }
98524
+ },
98525
+ required: ["width", "height"]
98526
+ },
98527
+ type: {
98528
+ type: "string",
98529
+ const: "video"
98530
+ }
98531
+ },
98532
+ required: [
98533
+ "id",
98534
+ "size",
98535
+ "name",
98536
+ "createdAt",
98537
+ "format",
98538
+ "meta",
98539
+ "type"
98540
+ ]
98541
+ },
97753
98542
  {
97754
98543
  type: "object",
97755
98544
  properties: {
@@ -99353,7 +100142,7 @@ const assetUpdateInput = z$4.object({
99353
100142
  description: z$4.union([z$4.string(), z$4.null()]).optional(),
99354
100143
  folderId: z$4.union([z$4.string().min(1), z$4.null()]).optional(),
99355
100144
  meta: assetMetaUpdate.describe(
99356
- "Type-specific metadata: family and style plus weight for static fonts or variationAxes for variable fonts, width/height for images, and no fields for generic files."
100145
+ "Type-specific metadata: family and style plus weight for static fonts or variationAxes for variable fonts, width/height for images and videos, and no fields for generic files."
99357
100146
  ).optional()
99358
100147
  }).refine(
99359
100148
  (values) => Object.keys(values).length > 0,
@@ -99402,6 +100191,7 @@ const imageDescriptionsSetInput = z$4.object({
99402
100191
  const addableAsset = z$4.union([
99403
100192
  fontAsset.omit({ projectId: true }),
99404
100193
  imageAsset.omit({ projectId: true }),
100194
+ videoAsset.omit({ projectId: true }),
99405
100195
  fileAsset.omit({ projectId: true })
99406
100196
  ]);
99407
100197
  const assetAddInput = z$4.object({ asset: addableAsset });
@@ -139611,7 +140401,7 @@ const getRequiredProps = (state) => {
139611
140401
  return state.props;
139612
140402
  };
139613
140403
  const getRequiredBuildData = (state) => {
139614
- const missing = [
140404
+ const missing2 = [
139615
140405
  "pages",
139616
140406
  "instances",
139617
140407
  "props",
@@ -139622,10 +140412,10 @@ const getRequiredBuildData = (state) => {
139622
140412
  "styleSourceSelections",
139623
140413
  "styles"
139624
140414
  ].find((namespace2) => state[namespace2] === void 0);
139625
- if (missing !== void 0) {
140415
+ if (missing2 !== void 0) {
139626
140416
  return throwBuilderRuntimeError(
139627
140417
  "BAD_REQUEST",
139628
- `${missing} namespace is missing`
140418
+ `${missing2} namespace is missing`
139629
140419
  );
139630
140420
  }
139631
140421
  return {
@@ -143085,7 +143875,8 @@ const meta$Q = {
143085
143875
  type: "resource",
143086
143876
  control: "resource",
143087
143877
  description: "The URI of a program that processes the information submitted via the form.",
143088
- required: false
143878
+ required: false,
143879
+ generatedProps: ["method"]
143089
143880
  }
143090
143881
  }
143091
143882
  };
@@ -157328,6 +158119,7 @@ const generateJsxElement = ({
157328
158119
  tagsOverrides,
157329
158120
  instance: instance2,
157330
158121
  props: props2,
158122
+ resources,
157331
158123
  dataSources,
157332
158124
  usedDataSources,
157333
158125
  indexesWithinAncestors,
@@ -157354,10 +158146,18 @@ ${tagProperty}=${JSON.stringify(instance2.tag)}`;
157354
158146
  let collectionItemValue;
157355
158147
  let collectionItemKeyValue;
157356
158148
  let classNameValue;
157357
- for (const prop2 of props2.values()) {
157358
- if (prop2.instanceId !== instance2.id) {
157359
- continue;
158149
+ const instanceProps = Array.from(props2.values()).filter(
158150
+ (prop2) => prop2.instanceId === instance2.id
158151
+ );
158152
+ const instancePropNames = new Set(instanceProps.map((prop2) => prop2.name));
158153
+ const projectedResourceProps = /* @__PURE__ */ new Map();
158154
+ const getGeneratedPropName = (name2) => {
158155
+ if (hasTags && !meta2?.props?.[name2]) {
158156
+ return standardAttributesToReactProps[name2] ?? name2;
157360
158157
  }
158158
+ return name2;
158159
+ };
158160
+ for (const prop2 of instanceProps) {
157361
158161
  const propValue = generatePropValue({
157362
158162
  scope: scope2,
157363
158163
  prop: prop2,
@@ -157367,10 +158167,18 @@ ${tagProperty}=${JSON.stringify(instance2.tag)}`;
157367
158167
  if (isAttributeNameSafe(prop2.name) === false) {
157368
158168
  continue;
157369
158169
  }
157370
- let name2 = prop2.name;
157371
- if (hasTags && !meta2?.props?.[prop2.name]) {
157372
- name2 = standardAttributesToReactProps[prop2.name] ?? prop2.name;
158170
+ if (prop2.type === "resource") {
158171
+ const propMeta2 = meta2?.props?.[prop2.name];
158172
+ const resource2 = resources?.get(prop2.value);
158173
+ if (propMeta2?.type === "resource" && resource2 !== void 0) {
158174
+ for (const name22 of propMeta2.generatedProps ?? []) {
158175
+ if (instancePropNames.has(name22) === false && isAttributeNameSafe(name22)) {
158176
+ projectedResourceProps.set(name22, resource2[name22]);
158177
+ }
158178
+ }
158179
+ }
157373
158180
  }
158181
+ const name2 = getGeneratedPropName(prop2.name);
157374
158182
  if (prop2.name === showAttribute) {
157375
158183
  if (propValue === "true") {
157376
158184
  continue;
@@ -157402,6 +158210,11 @@ ${tagProperty}=${JSON.stringify(instance2.tag)}`;
157402
158210
  ${name2}={${propValue}}`;
157403
158211
  }
157404
158212
  }
158213
+ for (const [propName, value2] of projectedResourceProps) {
158214
+ const name2 = getGeneratedPropName(propName);
158215
+ generatedProps += `
158216
+ ${name2}={${JSON.stringify(value2)}}`;
158217
+ }
157405
158218
  const classMapArray = classesMap?.get(instance2.id);
157406
158219
  if (classMapArray || classNameValue) {
157407
158220
  let classNameTemplate = classMapArray ? classMapArray.join(" ") : "";
@@ -157496,6 +158309,7 @@ const generateJsxChildren = ({
157496
158309
  children,
157497
158310
  instances,
157498
158311
  props: props2,
158312
+ resources,
157499
158313
  dataSources,
157500
158314
  usedDataSources,
157501
158315
  indexesWithinAncestors,
@@ -157537,6 +158351,7 @@ const generateJsxChildren = ({
157537
158351
  tagsOverrides,
157538
158352
  instance: instance2,
157539
158353
  props: props2,
158354
+ resources,
157540
158355
  dataSources,
157541
158356
  usedDataSources,
157542
158357
  indexesWithinAncestors,
@@ -157549,6 +158364,7 @@ const generateJsxChildren = ({
157549
158364
  children: instance2.children,
157550
158365
  instances,
157551
158366
  props: props2,
158367
+ resources,
157552
158368
  dataSources,
157553
158369
  usedDataSources,
157554
158370
  indexesWithinAncestors,
@@ -157567,6 +158383,7 @@ const generateWebstudioComponent = ({
157567
158383
  parameters,
157568
158384
  instances,
157569
158385
  props: props2,
158386
+ resources,
157570
158387
  dataSources,
157571
158388
  metas,
157572
158389
  tagsOverrides,
@@ -157586,6 +158403,7 @@ const generateWebstudioComponent = ({
157586
158403
  tagsOverrides,
157587
158404
  instance: instance2,
157588
158405
  props: props2,
158406
+ resources,
157589
158407
  dataSources,
157590
158408
  usedDataSources,
157591
158409
  indexesWithinAncestors,
@@ -157597,6 +158415,7 @@ const generateWebstudioComponent = ({
157597
158415
  children: instance2.children,
157598
158416
  instances,
157599
158417
  props: props2,
158418
+ resources,
157600
158419
  dataSources,
157601
158420
  usedDataSources,
157602
158421
  indexesWithinAncestors,
@@ -259083,11 +259902,11 @@ class ProjectSession {
259083
259902
  }
259084
259903
  async ensureNamespaces(namespaces) {
259085
259904
  const snapshot = await this.#loadLocalSnapshot();
259086
- const missing = getNamespacesNeedingRemote(snapshot, namespaces);
259087
- if (missing.length === 0 && snapshot !== void 0) {
259905
+ const missing2 = getNamespacesNeedingRemote(snapshot, namespaces);
259906
+ if (missing2.length === 0 && snapshot !== void 0) {
259088
259907
  return snapshot;
259089
259908
  }
259090
- return await this.fetchAndSave(missing.length === 0 ? namespaces : missing);
259909
+ return await this.fetchAndSave(missing2.length === 0 ? namespaces : missing2);
259091
259910
  }
259092
259911
  async fetchAndSave(namespaces, options = {}) {
259093
259912
  const current4 = await this.#loadLocalSnapshot();
@@ -271997,7 +272816,7 @@ const getComponentCoverageStatus = async ({
271997
272816
  const covered = availableEntries.filter(
271998
272817
  (entry2) => presentComponents.has(entry2.component)
271999
272818
  );
272000
- const missing = availableEntries.filter(
272819
+ const missing2 = availableEntries.filter(
272001
272820
  (entry2) => presentComponents.has(entry2.component) === false
272002
272821
  );
272003
272822
  const toCoverageEntry = ({
@@ -272019,11 +272838,11 @@ const getComponentCoverageStatus = async ({
272019
272838
  documentType,
272020
272839
  total: availableEntries.length,
272021
272840
  coveredCount: covered.length,
272022
- missingCount: missing.length,
272841
+ missingCount: missing2.length,
272023
272842
  covered: covered.map(toCoverageEntry),
272024
- missing: missing.map(toCoverageEntry),
272025
- missingRoots: missing.filter((entry2) => entry2.standaloneInsertable).map(toCoverageEntry),
272026
- missingParts: missing.filter((entry2) => entry2.standaloneInsertable === false).map(toCoverageEntry),
272843
+ missing: missing2.map(toCoverageEntry),
272844
+ missingRoots: missing2.filter((entry2) => entry2.standaloneInsertable).map(toCoverageEntry),
272845
+ missingParts: missing2.filter((entry2) => entry2.standaloneInsertable === false).map(toCoverageEntry),
272027
272846
  session: serializeProjectSessionMeta(envelope)
272028
272847
  };
272029
272848
  };
@@ -276526,7 +277345,7 @@ const serverOnlyRouterOperationMetadata = {
276526
277345
  };
276527
277346
  const assetUploadDescriptor = z$4.object({
276528
277347
  name: z$4.string(),
276529
- type: z$4.enum(["image", "font", "file"]),
277348
+ type: assetType,
276530
277349
  format: z$4.string().optional(),
276531
277350
  description: z$4.string().optional(),
276532
277351
  folderId: z$4.string().min(1).optional(),
@@ -278151,7 +278970,7 @@ const getAssetUploadUrl = ({
278151
278970
  if (asset2.folderId !== void 0) {
278152
278971
  url2.searchParams.set("folderId", asset2.folderId);
278153
278972
  }
278154
- if (asset2.type === "image") {
278973
+ if (asset2.type === "image" || asset2.type === "video") {
278155
278974
  url2.searchParams.set("width", String(asset2.meta.width));
278156
278975
  url2.searchParams.set("height", String(asset2.meta.height));
278157
278976
  }
@@ -278271,17 +279090,17 @@ const toUploadAsset = ({
278271
279090
  size: 0,
278272
279091
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
278273
279092
  };
278274
- if (descriptor.type === "image") {
279093
+ if (descriptor.type === "image" || descriptor.type === "video") {
278275
279094
  const width2 = descriptor.meta?.width;
278276
279095
  const height2 = descriptor.meta?.height;
278277
279096
  if (typeof width2 !== "number" || typeof height2 !== "number" || descriptor.format === void 0) {
278278
279097
  throw new Error(
278279
- `Image asset "${descriptor.name}" requires format, meta.width, and meta.height.`
279098
+ `${descriptor.type === "image" ? "Image" : "Video"} asset "${descriptor.name}" requires format, meta.width, and meta.height.`
278280
279099
  );
278281
279100
  }
278282
279101
  return {
278283
279102
  ...base2,
278284
- type: "image",
279103
+ type: descriptor.type,
278285
279104
  format: descriptor.format,
278286
279105
  meta: { width: width2, height: height2 }
278287
279106
  };
@@ -279178,7 +279997,7 @@ class HandledCliError extends Error {
279178
279997
  }
279179
279998
  const isHandledCliError = (error) => error instanceof HandledCliError;
279180
279999
  const name = "webstudio";
279181
- const version$1 = "0.292.0";
280000
+ const version$1 = "0.293.0";
279182
280001
  const description = "Webstudio CLI";
279183
280002
  const author = "Webstudio <github@webstudio.is>";
279184
280003
  const homepage = "https://webstudio.is";
@@ -291671,6 +292490,7 @@ Please check webstudio --help for more details`
291671
292490
  ],
291672
292491
  instances,
291673
292492
  props: props2,
292493
+ resources,
291674
292494
  dataSources,
291675
292495
  classesMap: classes,
291676
292496
  metas: usedMetas,
@@ -291837,7 +292657,10 @@ Please check webstudio --help for more details`
291837
292657
  );
291838
292658
  const assetsById = Object.fromEntries(
291839
292659
  siteData.assets.map((asset2) => {
291840
- const runtimeAsset = toRuntimeAsset(asset2, "https://placeholder.local");
292660
+ const runtimeAsset = toAssetReferenceRuntimeData(
292661
+ asset2,
292662
+ "https://placeholder.local"
292663
+ );
291841
292664
  return [
291842
292665
  asset2.id,
291843
292666
  {
@@ -292387,6 +293210,35 @@ const renderContentEngineReferenceMarkdown = ({
292387
293210
  "",
292388
293211
  `Choose \`fields\` and disable \`includeMetadata\` when the page needs only selected values. Fields used only for static filtering or sorting do not need to be returned. When enabled, \`includeMetadata\` adds ${assetQueryMetadataFields.filter((field) => field !== "id").map((field) => `\`${field}\``).join(", ")}. Every result includes \`id\`.`,
292389
293212
  "",
293213
+ heading(1, "Asset reference metadata"),
293214
+ "",
293215
+ "A plain local asset path in Markdown frontmatter or JSON properties keeps the backward-compatible URL string result. Wrap the path in an exact `$ref` object only when consumers need structured Asset Manager metadata:",
293216
+ "",
293217
+ "```yaml",
293218
+ "featureImage:",
293219
+ " $ref: ./assets/hero.png",
293220
+ "```",
293221
+ "",
293222
+ "The reference declares only the relationship. The query decides which metadata enters its result and published database. A complete `properties.featureImage` selection returns the Asset Manager asset metadata together with its resolved `src`. This includes fields such as `id`, `name`, `description`, `mimeType`, `width`, and `height`; new asset metadata becomes available to references without changing the document. Select only the nested fields the page uses:",
293223
+ "",
293224
+ "```json",
293225
+ "{",
293226
+ ' "output": {',
293227
+ ' "mode": "fields",',
293228
+ ' "includeMetadata": false,',
293229
+ ' "fields": [',
293230
+ ' ["properties", "title"],',
293231
+ ' ["properties", "featureImage", "src"],',
293232
+ ' ["properties", "featureImage", "description"]',
293233
+ " ]",
293234
+ " }",
293235
+ "}",
293236
+ "```",
293237
+ "",
293238
+ "The selected value becomes an object. Bind an Image source to `post.properties.featureImage.src` and its alternative text to `post.properties.featureImage.description ?? post.properties.title`. A missing description therefore falls back to the article title without duplicating text in frontmatter.",
293239
+ "",
293240
+ "External URLs remain ordinary strings. Existing local path strings also keep their URL string shape, so adopting structured references does not change existing queries or bindings.",
293241
+ "",
292390
293242
  heading(1, "Content modes"),
292391
293243
  "",
292392
293244
  renderRows(contentRows),
@@ -299003,6 +299855,7 @@ const discoverMarkdownAssetReferenceRanges = ({
299003
299855
  return [{ start, end, assetId: assetId2, ...suffix === "" ? {} : { suffix } }];
299004
299856
  });
299005
299857
  };
299858
+ const isDocumentFile = ({ contentType }) => getDocumentFormatByContentType(contentType) !== void 0;
299006
299859
  const measureContentSourcePerformance = async ({
299007
299860
  phase,
299008
299861
  operation,
@@ -299111,6 +299964,9 @@ const discoverSnapshotAssetValueReferences = ({
299111
299964
  entries
299112
299965
  }) => {
299113
299966
  const assetIdsByPath = createUniqueAssetIdsByPath(snapshot.files);
299967
+ const structuredAssetIds = new Set(
299968
+ snapshot.files.filter((file2) => isDocumentFile(file2) === false).map(({ id: id2 }) => id2)
299969
+ );
299114
299970
  const references = {};
299115
299971
  for (const entry2 of [...entries].sort(
299116
299972
  (left, right) => compareStrings(left.assetId, right.assetId)
@@ -299118,7 +299974,8 @@ const discoverSnapshotAssetValueReferences = ({
299118
299974
  const discovered = discoverAssetValueReferences({
299119
299975
  properties: entry2.document.properties ?? {},
299120
299976
  sourcePath: entry2.document.path,
299121
- assetIdsByPath
299977
+ assetIdsByPath,
299978
+ structuredAssetIds
299122
299979
  });
299123
299980
  if (discovered.length > 0) {
299124
299981
  references[entry2.assetId] = discovered;
@@ -299156,8 +300013,9 @@ const discoverSnapshotDocumentGraph = async (snapshot, entries, plan) => {
299156
300013
  }
299157
300014
  sourcesById.set(document2.id, document2.source);
299158
300015
  }
299159
- const supportedFiles = snapshot.files.filter(
299160
- (file2) => getDocumentFormatByContentType(file2.contentType) !== void 0
300016
+ const supportedFiles = snapshot.files.filter(isDocumentFile);
300017
+ const ignoredReferenceUrls = new Set(
300018
+ snapshot.files.filter((file2) => isDocumentFile(file2) === false).map((file2) => getDocumentUrl(file2.path))
299161
300019
  );
299162
300020
  if (supportedFiles.some((file2) => sourcesById.has(file2.id) === false)) {
299163
300021
  throw new Error("Content source omitted a supported document source");
@@ -299178,6 +300036,7 @@ const discoverSnapshotDocumentGraph = async (snapshot, entries, plan) => {
299178
300036
  source
299179
300037
  };
299180
300038
  }),
300039
+ ignoredReferenceUrls,
299181
300040
  ...plan === void 0 ? {} : {
299182
300041
  rootIds: entries.flatMap(
299183
300042
  ({ assetId: assetId2 }) => sourcesById.has(assetId2) ? [assetId2] : []
@@ -300025,13 +300884,13 @@ const loadCliProjectSessionAssetIndex = async (snapshot, connection, assetsDirec
300025
300884
  return artifact;
300026
300885
  };
300027
300886
  const createLocalProjectBundleFromSessionSnapshot = (snapshot, options = {}) => {
300028
- const missing = getMissingBuilderStateNamespaces(
300887
+ const missing2 = getMissingBuilderStateNamespaces(
300029
300888
  snapshot.state,
300030
300889
  webstudioDataNamespaces
300031
300890
  );
300032
- if (missing.length > 0) {
300891
+ if (missing2.length > 0) {
300033
300892
  throw new Error(
300034
- `Project session is missing preview data: ${missing.join(", ")}`
300893
+ `Project session is missing preview data: ${missing2.join(", ")}`
300035
300894
  );
300036
300895
  }
300037
300896
  const pages2 = snapshot.state.pages;
@@ -306836,6 +307695,36 @@ const createMcpRunErrorPayload = ({
306836
307695
  elapsedMs
306837
307696
  }
306838
307697
  });
307698
+ const reportMcpSingleOpCallTermination = ({
307699
+ termination,
307700
+ tool,
307701
+ elapsedMs,
307702
+ writeStatus = (message) => stderr.write(`${message}
307703
+ `),
307704
+ writeResult = printJson,
307705
+ setExitCode = (code2) => {
307706
+ process.exitCode = code2;
307707
+ }
307708
+ }) => {
307709
+ const error = {
307710
+ code: "MCP_CALL_TERMINATED",
307711
+ message: `MCP single-op-call ${tool} terminated before returning a result.`
307712
+ };
307713
+ const payload = createMcpSingleOpCallErrorPayload({ error, elapsedMs });
307714
+ writeStatus(
307715
+ formatMcpStatusLine(`single-op-call ${tool} terminated: ${error.message}`)
307716
+ );
307717
+ writeResult({
307718
+ ...payload,
307719
+ meta: {
307720
+ ...payload.meta,
307721
+ termination
307722
+ }
307723
+ });
307724
+ if (termination.type === "beforeExit") {
307725
+ setExitCode(1);
307726
+ }
307727
+ };
306839
307728
  const mcpRunTerminationCleanupTimeout = 5e3;
306840
307729
  const reportMcpRunTermination = ({
306841
307730
  termination,
@@ -306928,14 +307817,16 @@ const installMcpRunTerminationHandlers = ({
306928
307817
  totalCalls,
306929
307818
  results,
306930
307819
  startedAt,
306931
- disposeHost
307820
+ disposeHost,
307821
+ reportTermination = reportMcpRunTermination
306932
307822
  }) => {
306933
307823
  const controller = createMcpRunTerminationController({
306934
307824
  getActiveCall,
306935
307825
  totalCalls,
306936
307826
  results,
306937
307827
  startedAt,
306938
- disposeHost
307828
+ disposeHost,
307829
+ reportTermination
306939
307830
  });
306940
307831
  const terminationSignals = ["SIGHUP", "SIGINT", "SIGTERM"];
306941
307832
  const signalHandlers = /* @__PURE__ */ new Map();
@@ -307329,30 +308220,71 @@ const mcpSingleOpCall = async (options) => {
307329
308220
  )}
307330
308221
  `
307331
308222
  );
308223
+ let activeCall = { number: 1, tool };
308224
+ let didTerminate = false;
308225
+ let disposeHost = async () => void 0;
308226
+ const disposeTerminationHandlers = installMcpRunTerminationHandlers({
308227
+ getActiveCall: () => activeCall,
308228
+ totalCalls: 1,
308229
+ results: [],
308230
+ startedAt,
308231
+ disposeHost: () => disposeHost(),
308232
+ reportTermination: ({ termination, activeCall: activeCall2, elapsedMs }) => {
308233
+ didTerminate = true;
308234
+ reportMcpSingleOpCallTermination({
308235
+ termination,
308236
+ tool: activeCall2.tool,
308237
+ elapsedMs
308238
+ });
308239
+ }
308240
+ });
307332
308241
  try {
307333
308242
  assertSingleOpCallToolSupported(tool);
307334
308243
  const input2 = await parseMcpSingleOpCallInput(options);
307335
308244
  validateSingleOpCallInput(tool, input2);
308245
+ if (didTerminate) {
308246
+ throw new HandledCliError();
308247
+ }
307336
308248
  await withMcpHost(
307337
- () => createCliMcpHost({ projectId: options.project }),
308249
+ async () => {
308250
+ const mcpHost = await createCliMcpHost({ projectId: options.project });
308251
+ disposeHost = mcpHost.dispose;
308252
+ if (didTerminate) {
308253
+ throw new HandledCliError();
308254
+ }
308255
+ return mcpHost;
308256
+ },
307338
308257
  async ({ host, apiContract, scope: scope2 }) => {
307339
308258
  assertMcpToolServerSupport(tool, apiContract);
307340
308259
  const core2 = createCliMcpCore(host);
307341
308260
  const persistedCheckpoint = tool === "checkpoint.ack" ? await readPersistedMcpCheckpoint(scope2) : void 0;
308261
+ if (didTerminate) {
308262
+ throw new HandledCliError();
308263
+ }
307342
308264
  await assertPersistedMcpCheckpointAcknowledged(
307343
308265
  tool,
307344
308266
  core2.listTools(),
307345
308267
  scope2
307346
308268
  );
308269
+ if (didTerminate) {
308270
+ throw new HandledCliError();
308271
+ }
307347
308272
  if (options.refresh === true && tool !== "refresh") {
307348
308273
  await core2.callTool({ name: "refresh" });
308274
+ if (didTerminate) {
308275
+ throw new HandledCliError();
308276
+ }
307349
308277
  }
307350
308278
  const result2 = await core2.callTool({
307351
308279
  name: tool,
307352
308280
  input: input2,
307353
308281
  dryRun: options.dryRun
307354
308282
  });
308283
+ if (didTerminate) {
308284
+ throw new HandledCliError();
308285
+ }
307355
308286
  if (isMcpToolCallFailure(result2)) {
308287
+ activeCall = void 0;
307356
308288
  stderr.write(
307357
308289
  `${formatMcpStatusLine(
307358
308290
  `single-op-call ${tool} failed in ${Date.now() - startedAt}ms`
@@ -307370,8 +308302,12 @@ const mcpSingleOpCall = async (options) => {
307370
308302
  structuredContent: result2.structuredContent,
307371
308303
  scope: scope2
307372
308304
  });
308305
+ if (didTerminate) {
308306
+ throw new HandledCliError();
308307
+ }
307373
308308
  const session = result2.structuredContent.meta.session;
307374
308309
  const committed = session === void 0 ? "" : `; committed=${session.committed}`;
308310
+ activeCall = void 0;
307375
308311
  stderr.write(
307376
308312
  `${formatMcpStatusLine(
307377
308313
  `single-op-call ${tool} succeeded in ${Date.now() - startedAt}ms${committed}`
@@ -307386,6 +308322,10 @@ const mcpSingleOpCall = async (options) => {
307386
308322
  }
307387
308323
  );
307388
308324
  } catch (error) {
308325
+ activeCall = void 0;
308326
+ if (didTerminate) {
308327
+ throw new HandledCliError();
308328
+ }
307389
308329
  if (isHandledCliError(error)) {
307390
308330
  throw error;
307391
308331
  }
@@ -307401,6 +308341,9 @@ const mcpSingleOpCall = async (options) => {
307401
308341
  );
307402
308342
  printJson(payload);
307403
308343
  throw new HandledCliError();
308344
+ } finally {
308345
+ activeCall = void 0;
308346
+ disposeTerminationHandlers();
307404
308347
  }
307405
308348
  };
307406
308349
  class McpRunCheckpointStop extends Error {
@@ -307776,6 +308719,7 @@ const __testing__ = {
307776
308719
  meta: { elapsedMs }
307777
308720
  }),
307778
308721
  createMcpRunErrorPayload,
308722
+ reportMcpSingleOpCallTermination,
307779
308723
  reportMcpRunTermination,
307780
308724
  createMcpRunTerminationController,
307781
308725
  createMcpRunCheckpointStopPayload,