webstudio 0.299.0 → 0.300.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
@@ -8054,7 +8054,10 @@ const videoAsset = object({
8054
8054
  });
8055
8055
  const fileAsset = object({
8056
8056
  ...baseAsset,
8057
- format: string$5(),
8057
+ format: string$5().refine(
8058
+ (format2) => FONT_FORMATS.has(format2) === false,
8059
+ "Font formats must use font asset type"
8060
+ ),
8058
8061
  meta: object({}),
8059
8062
  type: literal$2(assetType.enum.file)
8060
8063
  });
@@ -16058,6 +16061,92 @@ const mapBounded = async (values, concurrency, run) => {
16058
16061
  }
16059
16062
  return results;
16060
16063
  };
16064
+ const getAbortReason = (signal) => signal.reason ?? new DOMException("The operation was aborted", "AbortError");
16065
+ const throwIfSignalAborted = (signal) => {
16066
+ if (signal?.aborted) {
16067
+ throw getAbortReason(signal);
16068
+ }
16069
+ };
16070
+ const awaitWithSignal = async (task, signal) => {
16071
+ if (signal === void 0) {
16072
+ return await task;
16073
+ }
16074
+ return await new Promise((resolve2, reject) => {
16075
+ const cleanup = () => signal.removeEventListener("abort", onAbort);
16076
+ const onAbort = () => {
16077
+ cleanup();
16078
+ reject(getAbortReason(signal));
16079
+ };
16080
+ signal.addEventListener("abort", onAbort, { once: true });
16081
+ Promise.resolve(task).then(
16082
+ (value2) => {
16083
+ cleanup();
16084
+ resolve2(value2);
16085
+ },
16086
+ (error) => {
16087
+ cleanup();
16088
+ reject(error);
16089
+ }
16090
+ );
16091
+ if (signal.aborted) {
16092
+ onAbort();
16093
+ }
16094
+ });
16095
+ };
16096
+ const createConcurrencyLimiter = ({
16097
+ concurrency,
16098
+ signal
16099
+ }) => {
16100
+ if (Number.isSafeInteger(concurrency) === false || concurrency <= 0) {
16101
+ throw new TypeError("Concurrency must be a positive safe integer");
16102
+ }
16103
+ let active = 0;
16104
+ const waiters = [];
16105
+ const acquire = async () => {
16106
+ throwIfSignalAborted(signal);
16107
+ if (active < concurrency) {
16108
+ active += 1;
16109
+ return;
16110
+ }
16111
+ await new Promise((resolve2, reject) => {
16112
+ let waiter;
16113
+ const onAbort = () => {
16114
+ const index2 = waiters.indexOf(waiter);
16115
+ if (index2 !== -1) {
16116
+ waiters.splice(index2, 1);
16117
+ }
16118
+ if (signal !== void 0) {
16119
+ reject(getAbortReason(signal));
16120
+ }
16121
+ };
16122
+ waiter = {
16123
+ start: () => {
16124
+ signal?.removeEventListener("abort", onAbort);
16125
+ resolve2();
16126
+ }
16127
+ };
16128
+ waiters.push(waiter);
16129
+ signal?.addEventListener("abort", onAbort, { once: true });
16130
+ });
16131
+ };
16132
+ const release2 = () => {
16133
+ const next = waiters.shift();
16134
+ if (next === void 0) {
16135
+ active -= 1;
16136
+ return;
16137
+ }
16138
+ next.start();
16139
+ };
16140
+ return async (run) => {
16141
+ await acquire();
16142
+ try {
16143
+ throwIfSignalAborted(signal);
16144
+ return await run();
16145
+ } finally {
16146
+ release2();
16147
+ }
16148
+ };
16149
+ };
16061
16150
  const isJsonObject$1 = (value2) => typeof value2 === "object" && value2 !== null && Array.isArray(value2) === false;
16062
16151
  const getJsonReferenceMarkerValue = (value2) => {
16063
16152
  if (isJsonObject$1(value2) === false) {
@@ -17916,7 +18005,7 @@ const includesField = (query, predicate) => {
17916
18005
  return included;
17917
18006
  };
17918
18007
  const requiresRuntimeDocumentData = (plan) => plan.queries.some(
17919
- (query) => includesField(
18008
+ (query) => query.content.mode !== "none" || includesField(
17920
18009
  query,
17921
18010
  (field) => field.length === 1 && isAssetQueryRuntimeField(field[0])
17922
18011
  )
@@ -25301,7 +25390,7 @@ class DocumentSourceCompilationAggregateError extends Error {
25301
25390
  this.errors = Object.freeze([...errors]);
25302
25391
  }
25303
25392
  }
25304
- const assertActive$1 = (signal) => {
25393
+ const assertActive$2 = (signal) => {
25305
25394
  if (signal?.aborted) {
25306
25395
  throw new DocumentSourceCompilationError({
25307
25396
  code: "REQUEST_CANCELLED",
@@ -25320,7 +25409,7 @@ const compileDocumentSourceGraph = async ({
25320
25409
  onDocumentProperties,
25321
25410
  signal
25322
25411
  }) => {
25323
- assertActive$1(signal);
25412
+ assertActive$2(signal);
25324
25413
  const getDocumentPath = (documentId) => {
25325
25414
  const document2 = documentId === void 0 ? void 0 : documents.find(({ id: id2 }) => id2 === documentId);
25326
25415
  if (document2 === void 0) {
@@ -25399,7 +25488,7 @@ const compileDocumentSourceGraph = async ({
25399
25488
  documentId
25400
25489
  });
25401
25490
  }
25402
- assertActive$1(signal);
25491
+ assertActive$2(signal);
25403
25492
  const result2 = await analyzeDocumentSource({
25404
25493
  format: document2.format,
25405
25494
  source: document2.source,
@@ -25412,7 +25501,7 @@ const compileDocumentSourceGraph = async ({
25412
25501
  value: { document: document2, analyzedDocument: result2 }
25413
25502
  };
25414
25503
  } catch (cause) {
25415
- assertActive$1(signal);
25504
+ assertActive$2(signal);
25416
25505
  if (cause instanceof DocumentSourceCompilationError) {
25417
25506
  return { status: "rejected", reason: cause, documentId };
25418
25507
  }
@@ -25488,7 +25577,7 @@ const compileDocumentSourceGraph = async ({
25488
25577
  }
25489
25578
  }
25490
25579
  }
25491
- assertActive$1(signal);
25580
+ assertActive$2(signal);
25492
25581
  if (compilationErrors.length === 1) {
25493
25582
  throw compilationErrors[0];
25494
25583
  }
@@ -26939,6 +27028,176 @@ const getDocumentSourceCacheKey = ({
26939
27028
  revision,
26940
27029
  format: format2
26941
27030
  }) => serializeJsonDeterministically([contentRef, revision, format2 ?? null]);
27031
+ class ResourceResolutionError extends Error {
27032
+ code;
27033
+ resourceIds;
27034
+ constructor({
27035
+ code: code2,
27036
+ message,
27037
+ resourceIds = [],
27038
+ cause
27039
+ }) {
27040
+ super(message, { cause });
27041
+ this.name = "ResourceResolutionError";
27042
+ this.code = code2;
27043
+ this.resourceIds = Object.freeze([...resourceIds]);
27044
+ }
27045
+ }
27046
+ const assertActive$1 = (signal) => {
27047
+ if (signal?.aborted) {
27048
+ throw new ResourceResolutionError({
27049
+ code: "REQUEST_CANCELLED",
27050
+ message: "Resource resolution was cancelled",
27051
+ cause: signal.reason
27052
+ });
27053
+ }
27054
+ };
27055
+ const getReachableResources = ({
27056
+ resourcesById,
27057
+ rootIds
27058
+ }) => {
27059
+ const state = /* @__PURE__ */ new Map();
27060
+ const stack = [];
27061
+ const ordered = [];
27062
+ const visit2 = (resourceId2, sourceId) => {
27063
+ const resource2 = resourcesById.get(resourceId2);
27064
+ if (resource2 === void 0) {
27065
+ throw new ResourceResolutionError({
27066
+ code: sourceId === void 0 ? "ROOT_NOT_FOUND" : "DEPENDENCY_NOT_FOUND",
27067
+ message: sourceId === void 0 ? `Resource graph root ${resourceId2} does not exist` : `Resource ${sourceId} dependency ${resourceId2} does not exist`,
27068
+ resourceIds: sourceId === void 0 ? [resourceId2] : [sourceId, resourceId2]
27069
+ });
27070
+ }
27071
+ const resourceState = state.get(resourceId2);
27072
+ if (resourceState === "visited") {
27073
+ return;
27074
+ }
27075
+ if (resourceState === "visiting") {
27076
+ const cycleStart = stack.indexOf(resourceId2);
27077
+ const cycle = [...stack.slice(cycleStart), resourceId2];
27078
+ throw new ResourceResolutionError({
27079
+ code: "CYCLE",
27080
+ message: `Resource graph contains a cycle: ${cycle.join(" -> ")}`,
27081
+ resourceIds: cycle
27082
+ });
27083
+ }
27084
+ state.set(resourceId2, "visiting");
27085
+ stack.push(resourceId2);
27086
+ for (const dependencyId of resource2.dependencies) {
27087
+ visit2(dependencyId, resource2.id);
27088
+ }
27089
+ stack.pop();
27090
+ state.set(resourceId2, "visited");
27091
+ ordered.push(resource2);
27092
+ };
27093
+ for (const rootId of new Set(rootIds)) {
27094
+ visit2(rootId);
27095
+ }
27096
+ return ordered;
27097
+ };
27098
+ const resolveResources = async ({
27099
+ resources,
27100
+ rootIds,
27101
+ concurrency,
27102
+ signal
27103
+ }) => {
27104
+ if (Number.isSafeInteger(concurrency) === false || concurrency <= 0) {
27105
+ throw new TypeError("Resource resolution concurrency must be positive");
27106
+ }
27107
+ assertActive$1(signal);
27108
+ const resourcesById = /* @__PURE__ */ new Map();
27109
+ for (const resource2 of resources) {
27110
+ if (resourcesById.has(resource2.id)) {
27111
+ throw new ResourceResolutionError({
27112
+ code: "DUPLICATE_RESOURCE",
27113
+ message: `Resource graph contains duplicate resource ${resource2.id}`,
27114
+ resourceIds: [resource2.id]
27115
+ });
27116
+ }
27117
+ resourcesById.set(resource2.id, resource2);
27118
+ }
27119
+ const reachableResources = getReachableResources({
27120
+ resourcesById,
27121
+ rootIds
27122
+ });
27123
+ const limit2 = createConcurrencyLimiter({ concurrency, signal });
27124
+ const documents = /* @__PURE__ */ new Map();
27125
+ const pending = /* @__PURE__ */ new Map();
27126
+ const resolveResource = (resourceId2) => {
27127
+ const previous2 = pending.get(resourceId2);
27128
+ if (previous2 !== void 0) {
27129
+ return previous2;
27130
+ }
27131
+ const resource2 = resourcesById.get(resourceId2);
27132
+ const resolution2 = (async () => {
27133
+ const dependencyDocuments = /* @__PURE__ */ new Map();
27134
+ let dependencyValues;
27135
+ try {
27136
+ dependencyValues = await Promise.all(
27137
+ resource2.dependencies.map(resolveResource)
27138
+ );
27139
+ } catch (cause) {
27140
+ if (cause instanceof ResourceResolutionError && cause.code === "RESOLUTION_FAILED") {
27141
+ throw new ResourceResolutionError({
27142
+ code: cause.code,
27143
+ message: `Resource dependency path ${[
27144
+ resource2.id,
27145
+ ...cause.resourceIds
27146
+ ].join(" -> ")} could not be resolved`,
27147
+ resourceIds: [resource2.id, ...cause.resourceIds],
27148
+ cause: cause.cause
27149
+ });
27150
+ }
27151
+ throw cause;
27152
+ }
27153
+ for (const [index2, dependencyId] of resource2.dependencies.entries()) {
27154
+ dependencyDocuments.set(
27155
+ dependencyId,
27156
+ dependencyValues[index2]
27157
+ );
27158
+ }
27159
+ assertActive$1(signal);
27160
+ try {
27161
+ return await limit2(async () => {
27162
+ assertActive$1(signal);
27163
+ const document2 = await awaitWithSignal(
27164
+ resource2.resolve({
27165
+ documents: dependencyDocuments,
27166
+ signal
27167
+ }),
27168
+ signal
27169
+ );
27170
+ assertActive$1(signal);
27171
+ return document2;
27172
+ });
27173
+ } catch (cause) {
27174
+ if (signal?.aborted) {
27175
+ assertActive$1(signal);
27176
+ }
27177
+ if (cause instanceof ResourceResolutionError) {
27178
+ throw cause;
27179
+ }
27180
+ throw new ResourceResolutionError({
27181
+ code: "RESOLUTION_FAILED",
27182
+ message: `Resource ${resource2.id} could not be resolved`,
27183
+ resourceIds: [resource2.id],
27184
+ cause
27185
+ });
27186
+ }
27187
+ })();
27188
+ pending.set(resourceId2, resolution2);
27189
+ return resolution2;
27190
+ };
27191
+ const roots = await Promise.all(rootIds.map(resolveResource));
27192
+ for (const resource2 of reachableResources) {
27193
+ const document2 = await pending.get(resource2.id);
27194
+ documents.set(resource2.id, document2);
27195
+ }
27196
+ return Object.freeze({
27197
+ roots: Object.freeze(roots),
27198
+ documents
27199
+ });
27200
+ };
26942
27201
  class DocumentGraphResolutionError extends Error {
26943
27202
  code;
26944
27203
  documentId;
@@ -26992,7 +27251,7 @@ const resolveDocumentGraph = async ({
26992
27251
  assertActive(signal);
26993
27252
  const node2 = group.representative;
26994
27253
  try {
26995
- const source = await load2(node2, { signal });
27254
+ const source = await awaitWithSignal(load2(node2, { signal }), signal);
26996
27255
  for (const groupedNode of group.nodes) {
26997
27256
  sources.set(groupedNode.id, source);
26998
27257
  }
@@ -27009,75 +27268,105 @@ const resolveDocumentGraph = async ({
27009
27268
  }
27010
27269
  });
27011
27270
  const edgesBySourceId = getDocumentGraphEdgesBySourceId(graph.edges);
27012
- const values = /* @__PURE__ */ new Map();
27013
- for (const node2 of closure) {
27014
- assertActive(signal);
27015
- const references = /* @__PURE__ */ new Map();
27016
- for (const edge of edgesBySourceId.get(node2.id) ?? []) {
27017
- const targetNode = nodesById.get(edge.reference.documentId);
27018
- if (targetNode === void 0 || values.has(edge.reference.documentId) === false) {
27019
- throw new DocumentGraphResolutionError({
27020
- code: "DOCUMENT_ASSEMBLY_FAILED",
27021
- message: `Document ${node2.id} dependency ${edge.reference.documentId} is unavailable`,
27022
- documentId: node2.id,
27023
- referenceId: edge.referenceId
27024
- });
27025
- }
27026
- const targetValue = values.get(edge.reference.documentId);
27027
- let selected;
27028
- if (select2 === void 0) {
27029
- if (edge.reference.representation.type !== "document") {
27271
+ const resources = closure.map((node2) => ({
27272
+ id: node2.id,
27273
+ dependencies: (edgesBySourceId.get(node2.id) ?? []).map(
27274
+ (edge) => edge.reference.documentId
27275
+ ),
27276
+ resolve: async ({ documents }) => {
27277
+ assertActive(signal);
27278
+ const references = /* @__PURE__ */ new Map();
27279
+ for (const edge of edgesBySourceId.get(node2.id) ?? []) {
27280
+ const targetNode = nodesById.get(edge.reference.documentId);
27281
+ if (targetNode === void 0 || documents.has(edge.reference.documentId) === false) {
27030
27282
  throw new DocumentGraphResolutionError({
27031
- code: "REPRESENTATION_SELECTOR_REQUIRED",
27032
- message: `Document ${node2.id} reference ${edge.referenceId} requires a representation selector`,
27283
+ code: "DOCUMENT_ASSEMBLY_FAILED",
27284
+ message: `Document ${node2.id} dependency ${edge.reference.documentId} is unavailable`,
27033
27285
  documentId: node2.id,
27034
27286
  referenceId: edge.referenceId
27035
27287
  });
27036
27288
  }
27037
- selected = targetValue;
27038
- } else {
27039
- try {
27040
- selected = await select2({
27041
- reference: edge.reference,
27042
- value: targetValue,
27043
- sourceNode: node2,
27044
- targetNode
27045
- });
27046
- } catch (error) {
27047
- throw new DocumentGraphResolutionError({
27048
- code: "DOCUMENT_SELECTION_FAILED",
27049
- message: `Document ${node2.id} reference ${edge.referenceId} could not be selected`,
27050
- documentId: node2.id,
27051
- referenceId: edge.referenceId,
27052
- cause: error
27053
- });
27289
+ const targetValue = documents.get(edge.reference.documentId);
27290
+ let selected;
27291
+ if (select2 === void 0) {
27292
+ if (edge.reference.representation.type !== "document") {
27293
+ throw new DocumentGraphResolutionError({
27294
+ code: "REPRESENTATION_SELECTOR_REQUIRED",
27295
+ message: `Document ${node2.id} reference ${edge.referenceId} requires a representation selector`,
27296
+ documentId: node2.id,
27297
+ referenceId: edge.referenceId
27298
+ });
27299
+ }
27300
+ selected = targetValue;
27301
+ } else {
27302
+ try {
27303
+ selected = await select2({
27304
+ reference: edge.reference,
27305
+ value: targetValue,
27306
+ sourceNode: node2,
27307
+ targetNode
27308
+ });
27309
+ } catch (error) {
27310
+ throw new DocumentGraphResolutionError({
27311
+ code: "DOCUMENT_SELECTION_FAILED",
27312
+ message: `Document ${node2.id} reference ${edge.referenceId} could not be selected`,
27313
+ documentId: node2.id,
27314
+ referenceId: edge.referenceId,
27315
+ cause: error
27316
+ });
27317
+ }
27318
+ }
27319
+ references.set(edge.referenceId, selected);
27320
+ }
27321
+ if (sources.has(node2.id) === false) {
27322
+ throw new DocumentGraphResolutionError({
27323
+ code: "DOCUMENT_ASSEMBLY_FAILED",
27324
+ message: `Document ${node2.id} source is unavailable`,
27325
+ documentId: node2.id
27326
+ });
27327
+ }
27328
+ const source = sources.get(node2.id);
27329
+ try {
27330
+ return await assemble({ node: node2, source, references });
27331
+ } catch (error) {
27332
+ if (error instanceof DocumentGraphResolutionError) {
27333
+ throw error;
27054
27334
  }
27335
+ throw new DocumentGraphResolutionError({
27336
+ code: "DOCUMENT_ASSEMBLY_FAILED",
27337
+ message: `Document ${node2.id} could not be assembled`,
27338
+ documentId: node2.id,
27339
+ cause: error
27340
+ });
27055
27341
  }
27056
- references.set(edge.referenceId, selected);
27057
27342
  }
27058
- if (sources.has(node2.id) === false) {
27059
- throw new DocumentGraphResolutionError({
27060
- code: "DOCUMENT_ASSEMBLY_FAILED",
27061
- message: `Document ${node2.id} source is unavailable`,
27062
- documentId: node2.id
27063
- });
27343
+ }));
27344
+ try {
27345
+ const resolved = await resolveResources({
27346
+ resources,
27347
+ rootIds,
27348
+ // Preserve deterministic dependency-first document assembly. Source
27349
+ // loading above remains bounded and concurrent.
27350
+ concurrency: 1,
27351
+ signal
27352
+ });
27353
+ return Object.freeze({
27354
+ roots: resolved.roots,
27355
+ values: resolved.documents
27356
+ });
27357
+ } catch (error) {
27358
+ if (error instanceof ResourceResolutionError && error.cause instanceof DocumentGraphResolutionError) {
27359
+ throw error.cause;
27064
27360
  }
27065
- const source = sources.get(node2.id);
27066
- try {
27067
- values.set(node2.id, await assemble({ node: node2, source, references }));
27068
- } catch (error) {
27361
+ if (error instanceof ResourceResolutionError && error.code === "REQUEST_CANCELLED") {
27069
27362
  throw new DocumentGraphResolutionError({
27070
- code: "DOCUMENT_ASSEMBLY_FAILED",
27071
- message: `Document ${node2.id} could not be assembled`,
27072
- documentId: node2.id,
27073
- cause: error
27363
+ code: "REQUEST_CANCELLED",
27364
+ message: "Document graph resolution was cancelled",
27365
+ cause: error.cause
27074
27366
  });
27075
27367
  }
27368
+ throw error;
27076
27369
  }
27077
- return Object.freeze({
27078
- roots: Object.freeze(rootIds.map((rootId) => values.get(rootId))),
27079
- values
27080
- });
27081
27370
  };
27082
27371
  class DocumentResolutionLimitError extends Error {
27083
27372
  code;
@@ -27109,55 +27398,6 @@ class DocumentResolutionLimitError extends Error {
27109
27398
  this.totalByteLimit = totalByteLimit;
27110
27399
  }
27111
27400
  }
27112
- const createConcurrencyLimiter = (concurrency, signal) => {
27113
- let active = 0;
27114
- const waiters = [];
27115
- const acquire = async () => {
27116
- signal?.throwIfAborted();
27117
- if (active < concurrency) {
27118
- active += 1;
27119
- return;
27120
- }
27121
- await new Promise((resolve2, reject) => {
27122
- let waiter;
27123
- const onAbort = () => {
27124
- const index2 = waiters.indexOf(waiter);
27125
- if (index2 !== -1) {
27126
- waiters.splice(index2, 1);
27127
- }
27128
- try {
27129
- signal?.throwIfAborted();
27130
- } catch (error) {
27131
- reject(error);
27132
- }
27133
- };
27134
- waiter = {
27135
- start: () => {
27136
- signal?.removeEventListener("abort", onAbort);
27137
- resolve2();
27138
- }
27139
- };
27140
- waiters.push(waiter);
27141
- signal?.addEventListener("abort", onAbort, { once: true });
27142
- });
27143
- };
27144
- const release2 = () => {
27145
- const next = waiters.shift();
27146
- if (next === void 0) {
27147
- active -= 1;
27148
- return;
27149
- }
27150
- next.start();
27151
- };
27152
- return async (run) => {
27153
- await acquire();
27154
- try {
27155
- return await run();
27156
- } finally {
27157
- release2();
27158
- }
27159
- };
27160
- };
27161
27401
  const resolveWithSessionDocumentLoader = async ({
27162
27402
  graph,
27163
27403
  rootIds,
@@ -27286,7 +27526,7 @@ const createDocumentResolutionSession = ({
27286
27526
  sizeCalculation: ({ byteLength }) => Math.max(1, byteLength)
27287
27527
  });
27288
27528
  const pending = /* @__PURE__ */ new Map();
27289
- const limit2 = createConcurrencyLimiter(concurrency, signal);
27529
+ const limit2 = createConcurrencyLimiter({ concurrency, signal });
27290
27530
  const assertSessionSignal = (requestedSignal) => {
27291
27531
  if (requestedSignal !== void 0 && requestedSignal !== signal) {
27292
27532
  throw new TypeError("Document resolution session signal does not match");
@@ -27295,34 +27535,7 @@ const createDocumentResolutionSession = ({
27295
27535
  };
27296
27536
  const waitForSessionTask = async (task) => {
27297
27537
  assertSessionSignal();
27298
- if (signal === void 0) {
27299
- return await task;
27300
- }
27301
- return await new Promise((resolve2, reject) => {
27302
- const cleanup = () => signal.removeEventListener("abort", onAbort);
27303
- const onAbort = () => {
27304
- cleanup();
27305
- try {
27306
- signal.throwIfAborted();
27307
- } catch (error) {
27308
- reject(error);
27309
- }
27310
- };
27311
- signal.addEventListener("abort", onAbort, { once: true });
27312
- task.then(
27313
- (value2) => {
27314
- cleanup();
27315
- resolve2(value2);
27316
- },
27317
- (error) => {
27318
- cleanup();
27319
- reject(error);
27320
- }
27321
- );
27322
- if (signal.aborted) {
27323
- onAbort();
27324
- }
27325
- });
27538
+ return await awaitWithSignal(task, signal);
27326
27539
  };
27327
27540
  const loadSessionDocument = async (node2, options) => {
27328
27541
  assertSessionSignal(options.signal);
@@ -27561,7 +27774,7 @@ const getInlineDocumentIds = (artifact) => {
27561
27774
  )
27562
27775
  );
27563
27776
  };
27564
- const createContentRuntimeArtifact = (artifact) => {
27777
+ const createContentRuntimeArtifact = (artifact, { includeContents = true } = {}) => {
27565
27778
  const inlineDocumentIds = getInlineDocumentIds(artifact);
27566
27779
  const documentGraph = artifact.documentGraph === void 0 ? void 0 : {
27567
27780
  nodes: artifact.documentGraph.nodes.filter(
@@ -27580,7 +27793,7 @@ const createContentRuntimeArtifact = (artifact) => {
27580
27793
  revision: artifact.integrity.checksum,
27581
27794
  documents: artifact.documents,
27582
27795
  ...documentGraph === void 0 ? {} : { documentGraph },
27583
- ...artifact.contents === void 0 ? {} : { contents: artifact.contents },
27796
+ ...includeContents && artifact.contents !== void 0 ? { contents: artifact.contents } : {},
27584
27797
  ...artifact.assetReferences === void 0 ? {} : { assetReferences: artifact.assetReferences },
27585
27798
  ...artifact.assetValueReferences === void 0 ? {} : { assetValueReferences: artifact.assetValueReferences },
27586
27799
  ...artifact.queries === void 0 ? {} : { queries: artifact.queries }
@@ -59147,6 +59360,7 @@ const templates = _enum([
59147
59360
  "ssg-netlify",
59148
59361
  "ssg-vercel"
59149
59362
  ]);
59363
+ const publishedDeploymentDestination = "saas";
59150
59364
  const deployment = union([
59151
59365
  object({
59152
59366
  destination: literal$2("static"),
@@ -59156,7 +59370,7 @@ const deployment = union([
59156
59370
  templates: array(templates)
59157
59371
  }),
59158
59372
  object({
59159
- destination: literal$2("saas").optional(),
59373
+ destination: literal$2(publishedDeploymentDestination).optional(),
59160
59374
  target: _enum(["staging", "production"]).optional(),
59161
59375
  domains: array(string$5()),
59162
59376
  assetsDomain: string$5().optional(),
@@ -59167,6 +59381,7 @@ const deployment = union([
59167
59381
  excludeWstdDomainFromSearch: boolean$2().optional()
59168
59382
  })
59169
59383
  ]);
59384
+ const isPublishedDeployment = (deployment2) => deployment2?.destination === publishedDeploymentDestination;
59170
59385
  const webstudioFragment = object({
59171
59386
  children: array(instanceChild),
59172
59387
  instances: array(instance$1),
@@ -61837,85 +62052,298 @@ const createScope = (occupiedIdentifiers = [], normalizeName2 = normalizeJsName,
61837
62052
  getName
61838
62053
  };
61839
62054
  };
62055
+ const getExpressionDataSourceIds = (expressions) => {
62056
+ const dataSourceIds = /* @__PURE__ */ new Set();
62057
+ for (const expression2 of expressions) {
62058
+ if (expression2 === void 0) {
62059
+ continue;
62060
+ }
62061
+ for (const identifier2 of getExpressionIdentifiers(expression2)) {
62062
+ const dataSourceId2 = decodeDataVariableId(identifier2);
62063
+ if (dataSourceId2 !== void 0) {
62064
+ dataSourceIds.add(dataSourceId2);
62065
+ }
62066
+ }
62067
+ }
62068
+ return dataSourceIds;
62069
+ };
62070
+ const getResourceDataSourceIds = (resource2) => {
62071
+ return getExpressionDataSourceIds([
62072
+ resource2.url,
62073
+ ...(resource2.searchParams ?? []).map(({ value: value2 }) => value2),
62074
+ ...resource2.headers.map(({ value: value2 }) => value2),
62075
+ resource2.body
62076
+ ]);
62077
+ };
62078
+ const getResourceDependencyIds = ({
62079
+ resource: resource2,
62080
+ dataSources
62081
+ }) => {
62082
+ const dependencyIds = /* @__PURE__ */ new Set();
62083
+ for (const dataSourceId2 of getResourceDataSourceIds(resource2)) {
62084
+ const dataSource2 = dataSources.get(dataSourceId2);
62085
+ if (dataSource2?.type === "resource") {
62086
+ dependencyIds.add(dataSource2.resourceId);
62087
+ }
62088
+ }
62089
+ return dependencyIds;
62090
+ };
62091
+ const getPageResourceRootIds = ({
62092
+ page: page2,
62093
+ instances,
62094
+ props: props2,
62095
+ dataSources
62096
+ }) => {
62097
+ const instanceIds = findTreeInstanceIds(instances, page2.rootInstanceId);
62098
+ const expressions = [
62099
+ page2.title,
62100
+ page2.meta?.description,
62101
+ page2.meta?.excludePageFromSearch,
62102
+ page2.meta?.language,
62103
+ page2.meta?.socialImageUrl,
62104
+ page2.meta?.status,
62105
+ page2.meta?.redirect,
62106
+ page2.meta?.content,
62107
+ ...(page2.meta?.custom ?? []).filter(({ property: property2 }) => property2.trim().length > 0).map(({ content: content2 }) => content2)
62108
+ ];
62109
+ for (const prop2 of props2.values()) {
62110
+ if (instances.size > 0 && instanceIds.has(prop2.instanceId) === false) {
62111
+ continue;
62112
+ }
62113
+ if (prop2.type === "expression") {
62114
+ expressions.push(prop2.value);
62115
+ }
62116
+ if (prop2.type === "action") {
62117
+ for (const action2 of prop2.value) {
62118
+ expressions.push(action2.code);
62119
+ }
62120
+ }
62121
+ }
62122
+ for (const instanceId2 of instanceIds) {
62123
+ const instance2 = instances.get(instanceId2);
62124
+ if (instance2 === void 0) {
62125
+ continue;
62126
+ }
62127
+ for (const child of instance2.children) {
62128
+ if (child.type === "expression") {
62129
+ expressions.push(child.value);
62130
+ }
62131
+ }
62132
+ }
62133
+ const resourceIds = /* @__PURE__ */ new Set();
62134
+ for (const dataSourceId2 of getExpressionDataSourceIds(expressions)) {
62135
+ const dataSource2 = dataSources.get(dataSourceId2);
62136
+ if (dataSource2?.type === "resource") {
62137
+ resourceIds.add(dataSource2.resourceId);
62138
+ }
62139
+ }
62140
+ return resourceIds;
62141
+ };
62142
+ const generateResourceRequestFields = ({
62143
+ resource: resource2,
62144
+ indent: indent2,
62145
+ dataSources,
62146
+ usedDataSources,
62147
+ scope: scope2
62148
+ }) => {
62149
+ let generated2 = "";
62150
+ generated2 += `${indent2}name: ${JSON.stringify(resource2.name)},
62151
+ `;
62152
+ if (resource2.control !== void 0) {
62153
+ generated2 += `${indent2}control: "${resource2.control}",
62154
+ `;
62155
+ }
62156
+ const url2 = generateExpression({
62157
+ expression: resource2.url,
62158
+ dataSources,
62159
+ usedDataSources,
62160
+ scope: scope2
62161
+ });
62162
+ generated2 += `${indent2}url: ${url2},
62163
+ `;
62164
+ generated2 += `${indent2}searchParams: [
62165
+ `;
62166
+ for (const searchParam of resource2.searchParams ?? []) {
62167
+ const value2 = generateExpression({
62168
+ expression: searchParam.value,
62169
+ dataSources,
62170
+ usedDataSources,
62171
+ scope: scope2
62172
+ });
62173
+ generated2 += `${indent2} { name: "${searchParam.name}", value: ${value2} },
62174
+ `;
62175
+ }
62176
+ generated2 += `${indent2}],
62177
+ `;
62178
+ generated2 += `${indent2}method: "${resource2.method}",
62179
+ `;
62180
+ generated2 += `${indent2}headers: [
62181
+ `;
62182
+ for (const header2 of resource2.headers) {
62183
+ const value2 = generateExpression({
62184
+ expression: header2.value,
62185
+ dataSources,
62186
+ usedDataSources,
62187
+ scope: scope2
62188
+ });
62189
+ generated2 += `${indent2} { name: "${header2.name}", value: ${value2} },
62190
+ `;
62191
+ }
62192
+ generated2 += `${indent2}],
62193
+ `;
62194
+ if (resource2.body !== void 0 && resource2.body.length > 0) {
62195
+ const body2 = generateExpression({
62196
+ expression: resource2.body,
62197
+ dataSources,
62198
+ usedDataSources,
62199
+ scope: scope2
62200
+ });
62201
+ generated2 += `${indent2}body: ${body2},
62202
+ `;
62203
+ }
62204
+ return generated2;
62205
+ };
61840
62206
  const generateResources = ({
61841
62207
  scope: scope2,
61842
62208
  page: page2,
61843
62209
  dataSources,
61844
62210
  props: props2,
61845
62211
  resources,
62212
+ instances = /* @__PURE__ */ new Map(),
61846
62213
  contentBlockResourceSelections = []
61847
62214
  }) => {
61848
62215
  const usedDataSources = /* @__PURE__ */ new Map();
61849
- const contentSelectionDataSourceIds = /* @__PURE__ */ new Set();
61850
- const generatedResourceIds = new Set(resources.keys());
62216
+ const contentInputDataSourceIds = /* @__PURE__ */ new Set();
61851
62217
  const selectedResourceIds = new Set(
61852
62218
  contentBlockResourceSelections.flatMap(
61853
62219
  ({ candidates }) => candidates.flatMap(({ resourceIds }) => resourceIds)
61854
62220
  )
61855
62221
  );
62222
+ const pageInstanceIds = findTreeInstanceIds(instances, page2.rootInstanceId);
62223
+ const actionResourceProps = Array.from(props2.values()).filter(
62224
+ (prop2) => (instances.size === 0 || pageInstanceIds.has(prop2.instanceId)) && prop2.type === "resource" && resources.has(prop2.value)
62225
+ );
62226
+ const actionResourceIds = new Set(
62227
+ actionResourceProps.map((prop2) => prop2.value)
62228
+ );
62229
+ const resourceDataSourceByResourceId = new Map(
62230
+ Array.from(dataSources.values()).filter(
62231
+ (dataSource2) => dataSource2.type === "resource" && resources.has(dataSource2.resourceId)
62232
+ ).map((dataSource2) => [dataSource2.resourceId, dataSource2])
62233
+ );
62234
+ const rootResourceIds = getPageResourceRootIds({
62235
+ page: page2,
62236
+ instances,
62237
+ props: props2,
62238
+ dataSources
62239
+ });
62240
+ for (const { sourceExpression } of contentBlockResourceSelections) {
62241
+ for (const dataSourceId2 of getExpressionDataSourceIds([sourceExpression])) {
62242
+ const dataSource2 = dataSources.get(dataSourceId2);
62243
+ if (dataSource2?.type === "resource") {
62244
+ rootResourceIds.add(dataSource2.resourceId);
62245
+ contentInputDataSourceIds.add(dataSource2.id);
62246
+ }
62247
+ }
62248
+ }
62249
+ for (const resourceId2 of selectedResourceIds) {
62250
+ const resource2 = resources.get(resourceId2);
62251
+ if (resource2 === void 0) {
62252
+ continue;
62253
+ }
62254
+ for (const dataSourceId2 of getResourceDataSourceIds(resource2)) {
62255
+ const dataSource2 = dataSources.get(dataSourceId2);
62256
+ if (dataSource2?.type !== "resource") {
62257
+ continue;
62258
+ }
62259
+ if (selectedResourceIds.has(dataSource2.resourceId)) {
62260
+ throw new Error(
62261
+ "Dynamic Content Block Resources cannot depend on another selected Resource"
62262
+ );
62263
+ }
62264
+ rootResourceIds.add(dataSource2.resourceId);
62265
+ contentInputDataSourceIds.add(dataSource2.id);
62266
+ }
62267
+ }
62268
+ const graphResourceIds = /* @__PURE__ */ new Set();
62269
+ const resourceDependencies = /* @__PURE__ */ new Map();
62270
+ const addResourceAndDependencies = (resourceId2) => {
62271
+ if (graphResourceIds.has(resourceId2)) {
62272
+ return;
62273
+ }
62274
+ const resource2 = resources.get(resourceId2);
62275
+ if (resource2 === void 0) {
62276
+ return;
62277
+ }
62278
+ graphResourceIds.add(resourceId2);
62279
+ const dependencies2 = Array.from(
62280
+ getResourceDependencyIds({
62281
+ resource: resource2,
62282
+ dataSources
62283
+ })
62284
+ );
62285
+ resourceDependencies.set(resourceId2, dependencies2);
62286
+ for (const dependencyId of dependencies2) {
62287
+ addResourceAndDependencies(dependencyId);
62288
+ }
62289
+ };
62290
+ for (const dataSource2 of resourceDataSourceByResourceId.values()) {
62291
+ if (selectedResourceIds.has(dataSource2.resourceId) === false && actionResourceIds.has(dataSource2.resourceId) === false) {
62292
+ addResourceAndDependencies(dataSource2.resourceId);
62293
+ }
62294
+ }
62295
+ for (const resourceId2 of rootResourceIds) {
62296
+ addResourceAndDependencies(resourceId2);
62297
+ }
62298
+ for (const resourceId2 of actionResourceIds) {
62299
+ addResourceAndDependencies(resourceId2);
62300
+ }
61856
62301
  let generatedRequests = "";
61857
62302
  for (const resource2 of resources.values()) {
61858
- let generatedRequest = "";
61859
62303
  const resourceName = scope2.getName(resource2.id, resource2.name);
61860
- generatedRequest += ` const ${resourceName}: ResourceRequest = {
61861
- `;
61862
- generatedRequest += ` name: ${JSON.stringify(resource2.name)},
61863
- `;
61864
- if (resource2.control !== void 0) {
61865
- generatedRequest += ` control: "${resource2.control}",
61866
- `;
61867
- }
61868
- const url2 = generateExpression({
61869
- expression: resource2.url,
61870
- dataSources,
61871
- usedDataSources,
61872
- scope: scope2
61873
- });
61874
- generatedRequest += ` url: ${url2},
61875
- `;
61876
- generatedRequest += ` searchParams: [
61877
- `;
61878
- for (const searchParam of resource2.searchParams ?? []) {
61879
- const value2 = generateExpression({
61880
- expression: searchParam.value,
62304
+ if (graphResourceIds.has(resource2.id)) {
62305
+ const requestDataSources = /* @__PURE__ */ new Map();
62306
+ const fields = generateResourceRequestFields({
62307
+ resource: resource2,
62308
+ indent: " ",
61881
62309
  dataSources,
61882
- usedDataSources,
62310
+ usedDataSources: requestDataSources,
61883
62311
  scope: scope2
61884
62312
  });
61885
- generatedRequest += ` { name: "${searchParam.name}", value: ${value2} },
62313
+ let generatedRequest = ` const ${resourceName} = (documents: ReadonlyMap<string, unknown>): ResourceRequest => {
61886
62314
  `;
61887
- }
61888
- generatedRequest += ` ],
62315
+ for (const dataSource2 of requestDataSources.values()) {
62316
+ usedDataSources.set(dataSource2.id, dataSource2);
62317
+ if (dataSource2.type !== "resource") {
62318
+ continue;
62319
+ }
62320
+ const name2 = scope2.getName(dataSource2.id, dataSource2.name);
62321
+ generatedRequest += ` const ${name2} = documents.get(${JSON.stringify(
62322
+ dataSource2.resourceId
62323
+ )})
61889
62324
  `;
61890
- generatedRequest += ` method: "${resource2.method}",
62325
+ }
62326
+ generatedRequest += ` return {
61891
62327
  `;
61892
- generatedRequest += ` headers: [
62328
+ generatedRequest += fields;
62329
+ generatedRequest += ` }
61893
62330
  `;
61894
- for (const header2 of resource2.headers) {
61895
- const value2 = generateExpression({
61896
- expression: header2.value,
61897
- dataSources,
61898
- usedDataSources,
61899
- scope: scope2
61900
- });
61901
- generatedRequest += ` { name: "${header2.name}", value: ${value2} },
62331
+ generatedRequest += ` }
61902
62332
  `;
62333
+ generatedRequests += generatedRequest;
62334
+ continue;
61903
62335
  }
61904
- generatedRequest += ` ],
62336
+ generatedRequests += ` const ${resourceName}: ResourceRequest = {
61905
62337
  `;
61906
- if (resource2.body !== void 0 && resource2.body.length > 0) {
61907
- const body2 = generateExpression({
61908
- expression: resource2.body,
61909
- dataSources,
61910
- usedDataSources,
61911
- scope: scope2
61912
- });
61913
- generatedRequest += ` body: ${body2},
61914
- `;
61915
- }
61916
- generatedRequest += ` }
62338
+ generatedRequests += generateResourceRequestFields({
62339
+ resource: resource2,
62340
+ indent: " ",
62341
+ dataSources,
62342
+ usedDataSources,
62343
+ scope: scope2
62344
+ });
62345
+ generatedRequests += ` }
61917
62346
  `;
61918
- generatedRequests += generatedRequest;
61919
62347
  }
61920
62348
  const generatedContentSelections = contentBlockResourceSelections.map(
61921
62349
  ({ sourceExpression, candidates }) => {
@@ -61936,7 +62364,7 @@ const generateResources = ({
61936
62364
  }
61937
62365
  }
61938
62366
  for (const dataSource2 of selectionDataSources.values()) {
61939
- contentSelectionDataSourceIds.add(dataSource2.id);
62367
+ contentInputDataSourceIds.add(dataSource2.id);
61940
62368
  usedDataSources.set(dataSource2.id, dataSource2);
61941
62369
  }
61942
62370
  return { source, candidates };
@@ -61957,68 +62385,108 @@ const generateResources = ({
61957
62385
  `;
61958
62386
  }
61959
62387
  }
61960
- if (dataSource2.type === "resource" && contentSelectionDataSourceIds.has(dataSource2.id)) {
62388
+ if (dataSource2.type === "resource" && contentInputDataSourceIds.has(dataSource2.id)) {
61961
62389
  const name2 = scope2.getName(dataSource2.id, dataSource2.name);
61962
62390
  const resourceName = scope2.getName(
61963
62391
  dataSource2.resourceId,
61964
62392
  dataSource2.name
61965
62393
  );
61966
- generatedVariables += ` const ${name2} = _props.resources?.[${JSON.stringify(resourceName)}]
62394
+ generatedVariables += ` const ${name2} = _props.resources?.[${JSON.stringify(
62395
+ resourceName
62396
+ )}]
61967
62397
  `;
61968
62398
  }
61969
62399
  }
61970
62400
  let generated2 = "";
61971
62401
  generated2 += `import type { System, ResourceRequest } from "@webstudio-is/sdk";
62402
+ `;
62403
+ generated2 += `import type { ResourceRequestGraph } from "@webstudio-is/sdk/runtime";
61972
62404
  `;
61973
62405
  generated2 += `export const getResources = (_props: { system: System; resources?: Record<string, any> }) => {
61974
62406
  `;
61975
62407
  generated2 += generatedVariables;
61976
62408
  generated2 += generatedRequests;
61977
- const actionResourceIds = /* @__PURE__ */ new Set();
61978
- for (const prop2 of props2.values()) {
61979
- if (prop2.type === "resource" && generatedResourceIds.has(prop2.value)) {
61980
- actionResourceIds.add(prop2.value);
62409
+ generated2 += ` const _data: ResourceRequestGraph = {
62410
+ `;
62411
+ generated2 += ` resources: [
62412
+ `;
62413
+ for (const resourceId2 of graphResourceIds) {
62414
+ const resource2 = resources.get(resourceId2);
62415
+ if (resource2 === void 0) {
62416
+ continue;
61981
62417
  }
62418
+ const name2 = scope2.getName(resourceId2, resource2.name);
62419
+ const dependencies2 = resourceDependencies.get(resourceId2) ?? [];
62420
+ generated2 += ` { id: ${JSON.stringify(
62421
+ resourceId2
62422
+ )}, outputName: ${JSON.stringify(name2)}, dependencies: ${JSON.stringify(
62423
+ dependencies2
62424
+ )}, createRequest: ${name2} },
62425
+ `;
61982
62426
  }
61983
- generated2 += ` const _data = new Map<string, ResourceRequest>([
62427
+ generated2 += ` ],
61984
62428
  `;
61985
- for (const dataSource2 of dataSources.values()) {
61986
- if (dataSource2.type === "resource" && generatedResourceIds.has(dataSource2.resourceId) && selectedResourceIds.has(dataSource2.resourceId) === false && actionResourceIds.has(dataSource2.resourceId) === false) {
61987
- const name2 = scope2.getName(dataSource2.resourceId, dataSource2.name);
61988
- generated2 += ` ["${name2}", ${name2}],
62429
+ generated2 += ` rootIds: [
62430
+ `;
62431
+ for (const resourceId2 of rootResourceIds) {
62432
+ if (graphResourceIds.has(resourceId2) && selectedResourceIds.has(resourceId2) === false && actionResourceIds.has(resourceId2) === false) {
62433
+ generated2 += ` ${JSON.stringify(resourceId2)},
61989
62434
  `;
61990
62435
  }
61991
62436
  }
61992
- generated2 += ` ])
62437
+ generated2 += ` ],
61993
62438
  `;
61994
- generated2 += ` const _contentData = new Map<string, ResourceRequest>()
62439
+ generated2 += ` }
61995
62440
  `;
61996
- if (contentBlockResourceSelections.length > 0) {
61997
- for (const { source, candidates } of generatedContentSelections) {
61998
- for (const { assetId: assetId2, resourceIds } of candidates) {
61999
- generated2 += ` if (${source} === ${JSON.stringify(assetId2)}) {
62441
+ if ([...selectedResourceIds].some(
62442
+ (resourceId2) => graphResourceIds.has(resourceId2)
62443
+ )) {
62444
+ generated2 += ` const _contentDocuments = new Map<string, unknown>([
62000
62445
  `;
62001
- for (const dataSource2 of dataSources.values()) {
62002
- if (dataSource2.type !== "resource" || resourceIds.includes(dataSource2.resourceId) === false || generatedResourceIds.has(dataSource2.resourceId) === false || actionResourceIds.has(dataSource2.resourceId)) {
62003
- continue;
62004
- }
62005
- const name2 = scope2.getName(dataSource2.resourceId, dataSource2.name);
62006
- generated2 += ` _contentData.set(${JSON.stringify(name2)}, ${name2})
62446
+ for (const dataSource2 of usedDataSources.values()) {
62447
+ if (dataSource2.type !== "resource" || contentInputDataSourceIds.has(dataSource2.id) === false) {
62448
+ continue;
62449
+ }
62450
+ const name2 = scope2.getName(dataSource2.id, dataSource2.name);
62451
+ generated2 += ` [${JSON.stringify(dataSource2.resourceId)}, ${name2}],
62452
+ `;
62453
+ }
62454
+ generated2 += ` ])
62455
+ `;
62456
+ }
62457
+ generated2 += ` const _contentData = new Map<string, ResourceRequest>()
62458
+ `;
62459
+ for (const { source, candidates } of generatedContentSelections) {
62460
+ for (const { assetId: assetId2, resourceIds } of candidates) {
62461
+ generated2 += ` if (${source} === ${JSON.stringify(assetId2)}) {
62007
62462
  `;
62463
+ for (const resourceId2 of resourceIds) {
62464
+ const dataSource2 = resourceDataSourceByResourceId.get(resourceId2);
62465
+ if (dataSource2 === void 0 || actionResourceIds.has(resourceId2)) {
62466
+ continue;
62008
62467
  }
62009
- generated2 += ` }
62468
+ const name2 = scope2.getName(resourceId2, dataSource2.name);
62469
+ const request = graphResourceIds.has(resourceId2) ? `${scope2.getName(resourceId2, resources.get(resourceId2)?.name ?? dataSource2.name)}(_contentDocuments)` : name2;
62470
+ generated2 += ` _contentData.set(${JSON.stringify(name2)}, ${request})
62010
62471
  `;
62011
62472
  }
62473
+ generated2 += ` }
62474
+ `;
62012
62475
  }
62013
62476
  }
62014
- generated2 += ` const _action = new Map<string, ResourceRequest>([
62015
- `;
62016
- for (const prop2 of props2.values()) {
62017
- if (prop2.type === "resource" && generatedResourceIds.has(prop2.value)) {
62018
- const name2 = scope2.getName(prop2.value, prop2.name);
62019
- generated2 += ` ["${name2}", ${name2}],
62477
+ generated2 += ` const _action = new Map<string, { id: string; outputName: string }>([
62020
62478
  `;
62479
+ for (const prop2 of actionResourceProps) {
62480
+ const resource2 = resources.get(prop2.value);
62481
+ if (resource2 === void 0 || graphResourceIds.has(prop2.value) === false) {
62482
+ continue;
62021
62483
  }
62484
+ const name2 = scope2.getName(prop2.value, prop2.name);
62485
+ const outputName = scope2.getName(prop2.value, resource2.name);
62486
+ generated2 += ` ["${name2}", { id: ${JSON.stringify(
62487
+ prop2.value
62488
+ )}, outputName: ${JSON.stringify(outputName)} }],
62489
+ `;
62022
62490
  }
62023
62491
  generated2 += ` ])
62024
62492
  `;
@@ -187039,7 +187507,7 @@ const replaceDataSourcesInExpression = (expression2, replacements) => {
187039
187507
  return expression2;
187040
187508
  }
187041
187509
  };
187042
- const computeExpression = (expression2, variables) => {
187510
+ const evaluateExpression = (expression2, variables) => {
187043
187511
  try {
187044
187512
  const proxiedVariables = /* @__PURE__ */ new Map();
187045
187513
  const getVariable = (key2) => {
@@ -187059,8 +187527,43 @@ const computeExpression = (expression2, variables) => {
187059
187527
  return void 0;
187060
187528
  }
187061
187529
  };
187062
- const computeStringExpression = (expression2, variables) => {
187063
- const value2 = computeExpression(expression2, variables);
187530
+ const resolveExpressionVariables = async ({
187531
+ expression: expression2,
187532
+ variables,
187533
+ resolveDataSource
187534
+ }) => {
187535
+ const dataSourceIds = /* @__PURE__ */ new Set();
187536
+ for (const identifier2 of getExpressionIdentifiers(expression2)) {
187537
+ const dataSourceId2 = decodeDataVariableId(identifier2);
187538
+ if (dataSourceId2 !== void 0) {
187539
+ dataSourceIds.add(dataSourceId2);
187540
+ }
187541
+ }
187542
+ const resolved = new Map(variables);
187543
+ await Promise.all(
187544
+ [...dataSourceIds].map(async (dataSourceId2) => {
187545
+ resolved.set(
187546
+ dataSourceId2,
187547
+ await resolveDataSource(dataSourceId2, variables.get(dataSourceId2))
187548
+ );
187549
+ })
187550
+ );
187551
+ return resolved;
187552
+ };
187553
+ const computeExpression = async (expression2, variables, resolveDataSource = (_dataSourceId, value2) => value2) => evaluateExpression(
187554
+ expression2,
187555
+ await resolveExpressionVariables({
187556
+ expression: expression2,
187557
+ variables,
187558
+ resolveDataSource
187559
+ })
187560
+ );
187561
+ const computeStringExpression = async (expression2, variables, resolveDataSource) => {
187562
+ const value2 = await computeExpression(
187563
+ expression2,
187564
+ variables,
187565
+ resolveDataSource
187566
+ );
187064
187567
  return typeof value2 === "string" && value2 !== "" ? value2 : void 0;
187065
187568
  };
187066
187569
  const getParentInstanceById = (instances) => {
@@ -195783,10 +196286,10 @@ const getFragmentContentModelWarnings = ({
195783
196286
  metas
195784
196287
  });
195785
196288
  };
195786
- const resolveContentBlockSourceAssetId = ({
196289
+ const resolveContentBlockSourceAssetId = async ({
195787
196290
  source,
195788
196291
  values
195789
- }) => source.type === "asset" ? source.assetId : values === void 0 ? void 0 : computeStringExpression(source.value, values);
196292
+ }) => source.type === "asset" ? source.assetId : values === void 0 ? void 0 : await computeStringExpression(source.value, values);
195790
196293
  const findBlockTemplateNameCollision = ({
195791
196294
  instance: instance2,
195792
196295
  nextInstance,
@@ -281094,18 +281597,6 @@ Any elements that were not used above are used below.
281094
281597
  > [!NOTE]
281095
281598
  > Add helpful context without interrupting the main content.
281096
281599
 
281097
- > [!TIP]
281098
- > Share a useful suggestion.
281099
-
281100
- > [!IMPORTANT]
281101
- > Highlight essential information.
281102
-
281103
- > [!WARNING]
281104
- > Point out something readers should be careful about.
281105
-
281106
- > [!CAUTION]
281107
- > Explain a potential negative consequence.
281108
-
281109
281600
  Using \`console.log("Hello World");\` will log to the console.
281110
281601
 
281111
281602
  | Header 1 | Header 2 | Header 3 |
@@ -281139,29 +281630,6 @@ const meta$i = {
281139
281630
  "ws:style": markdownAlertStyle
281140
281631
  }
281141
281632
  ),
281142
- /* @__PURE__ */ jsxRuntimeExports.jsx(ws.descendant, { "ws:label": "Note alert", selector: ' [data-state="note"]' }),
281143
- /* @__PURE__ */ jsxRuntimeExports.jsx(ws.descendant, { "ws:label": "Tip alert", selector: ' [data-state="tip"]' }),
281144
- /* @__PURE__ */ jsxRuntimeExports.jsx(
281145
- ws.descendant,
281146
- {
281147
- "ws:label": "Important alert",
281148
- selector: ' [data-state="important"]'
281149
- }
281150
- ),
281151
- /* @__PURE__ */ jsxRuntimeExports.jsx(
281152
- ws.descendant,
281153
- {
281154
- "ws:label": "Warning alert",
281155
- selector: ' [data-state="warning"]'
281156
- }
281157
- ),
281158
- /* @__PURE__ */ jsxRuntimeExports.jsx(
281159
- ws.descendant,
281160
- {
281161
- "ws:label": "Caution alert",
281162
- selector: ' [data-state="caution"]'
281163
- }
281164
- ),
281165
281633
  /* @__PURE__ */ jsxRuntimeExports.jsx(ws.descendant, { "ws:label": "Code Text", selector: " code" }),
281166
281634
  /* @__PURE__ */ jsxRuntimeExports.jsx(ws.descendant, { "ws:label": "List", selector: " :where(ul, ol)" }),
281167
281635
  /* @__PURE__ */ jsxRuntimeExports.jsx(ws.descendant, { "ws:label": "List Item", selector: " li" }),
@@ -297922,8 +298390,7 @@ const getStaticString = (expression2) => {
297922
298390
  if (isLiteralExpression(expression2) === false) {
297923
298391
  return;
297924
298392
  }
297925
- const value2 = computeExpression(expression2, /* @__PURE__ */ new Map());
297926
- return typeof value2 === "string" ? value2 : void 0;
298393
+ return parseStringLiteralExpression(expression2);
297927
298394
  };
297928
298395
  const analyzeProject = (state, input2) => {
297929
298396
  if (state.instances === void 0 || state.props === void 0 || state.styles === void 0 || state.styleSources === void 0 || state.styleSourceSelections === void 0 || state.resources === void 0 || state.dataSources === void 0 || state.assets === void 0 || state.breakpoints === void 0) {
@@ -328066,6 +328533,30 @@ const serverOnlyRouterOperationMetadata = {
328066
328533
  additionalProperties: true
328067
328534
  }
328068
328535
  },
328536
+ "publish.validate": {
328537
+ id: "publish.validate",
328538
+ command: "check-publish-readiness",
328539
+ method: "query",
328540
+ path: "api.publish.validate",
328541
+ client: "checkPublishReadiness",
328542
+ permit: "edit",
328543
+ inputSchema: {
328544
+ type: "object",
328545
+ properties: {
328546
+ target: {
328547
+ type: "string",
328548
+ enum: ["staging", "production"]
328549
+ },
328550
+ domains: {
328551
+ type: "array",
328552
+ items: {
328553
+ type: "string"
328554
+ }
328555
+ }
328556
+ },
328557
+ required: ["target"]
328558
+ }
328559
+ },
328069
328560
  "publish.list": {
328070
328561
  id: "publish.list",
328071
328562
  command: "list-publishes",
@@ -329018,6 +329509,15 @@ const curatedPublicApiOperationDocumentation = [
329018
329509
  requiredOptions: ["resource", "json"],
329019
329510
  examples: ["webstudio delete-resource --resource resource-id --json"]
329020
329511
  },
329512
+ {
329513
+ command: "check-publish-readiness",
329514
+ description: "Check publish access, selected domains, and content diagnostics without starting a publish. Use audit for project-wide quality checks.",
329515
+ requiredOptions: ["target", "json"],
329516
+ examples: [
329517
+ "webstudio check-publish-readiness --target production --json",
329518
+ 'MCP tool: check-publish-readiness {"target":"production"}'
329519
+ ]
329520
+ },
329021
329521
  {
329022
329522
  command: "publish",
329023
329523
  description: "Publish the configured project to staging or production. Uses the project domain by default and, for production, active verified custom domains. If local development cannot contact the deployment backend, the JSON response includes warning while still returning the local publish job id.",
@@ -330863,6 +331363,7 @@ const createResource = projectMutationInput("create-resource");
330863
331363
  const updateResource = projectMutationInput("update-resource");
330864
331364
  const deleteResource = projectMutationInput("delete-resource");
330865
331365
  const listPublishes = projectQueryInput("list-publishes");
331366
+ const checkPublishReadiness = projectQueryInput("check-publish-readiness");
330866
331367
  const publish = projectMutationInput("publish");
330867
331368
  const getPublishJob = projectQueryInput("get-publish-job");
330868
331369
  const unpublish = projectConfirmedMutationInput("unpublish");
@@ -331027,6 +331528,7 @@ const httpClient = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePr
331027
331528
  bindProps,
331028
331529
  bundleVersion,
331029
331530
  checkProjectBuildPermission,
331531
+ checkPublishReadiness,
331030
331532
  clearStyleSourceStyles,
331031
331533
  cloneInstance,
331032
331534
  connectContentBlockSource,
@@ -331219,7 +331721,7 @@ class HandledCliError extends Error {
331219
331721
  }
331220
331722
  const isHandledCliError = (error) => error instanceof HandledCliError;
331221
331723
  const name = "webstudio";
331222
- const version$1 = "0.299.0";
331724
+ const version$1 = "0.300.0";
331223
331725
  const description = "Webstudio CLI";
331224
331726
  const author = "Webstudio <github@webstudio.is>";
331225
331727
  const homepage = "https://webstudio.is";
@@ -338207,7 +338709,7 @@ const bindContentBlockSource = (state, blockInstanceId, source) => source.type =
338207
338709
  ...source,
338208
338710
  value: bindExpressionInput(state, blockInstanceId, source.value)
338209
338711
  } : source;
338210
- const getMdxAssetSourceBlockInstanceIds = ({
338712
+ const getMdxAssetSourceBlockInstanceIds = async ({
338211
338713
  assetId: assetId2,
338212
338714
  state
338213
338715
  }) => {
@@ -338218,13 +338720,21 @@ const getMdxAssetSourceBlockInstanceIds = ({
338218
338720
  values.set(dataSource2.id, dataSource2.value.value);
338219
338721
  }
338220
338722
  }
338221
- return Array.from(
338222
- getContentBlockSources({
338223
- instances: state.instances?.values() ?? [],
338224
- props: state.props?.values() ?? []
338225
- })
338226
- ).flatMap(
338227
- ([blockInstanceId, contentSource]) => resolveContentBlockSourceAssetId({ source: contentSource, values }) === assetId2 ? [blockInstanceId] : []
338723
+ const blockInstanceIds = await Promise.all(
338724
+ Array.from(
338725
+ getContentBlockSources({
338726
+ instances: state.instances?.values() ?? [],
338727
+ props: state.props?.values() ?? []
338728
+ })
338729
+ ).map(
338730
+ async ([blockInstanceId, contentSource]) => await resolveContentBlockSourceAssetId({
338731
+ source: contentSource,
338732
+ values
338733
+ }) === assetId2 ? blockInstanceId : void 0
338734
+ )
338735
+ );
338736
+ return blockInstanceIds.filter(
338737
+ (blockInstanceId) => blockInstanceId !== void 0
338228
338738
  );
338229
338739
  };
338230
338740
  const mdxAssetInspectionNamespaces = componentInsertReadNamespaces;
@@ -338276,7 +338786,7 @@ const inspectMdxAssetSource = async ({
338276
338786
  }
338277
338787
  const data2 = getData(state);
338278
338788
  const blockInstanceIds = /* @__PURE__ */ new Set([
338279
- ...getMdxAssetSourceBlockInstanceIds({ assetId: assetId2, state }),
338789
+ ...await getMdxAssetSourceBlockInstanceIds({ assetId: assetId2, state }),
338280
338790
  ...sourceBlockInstanceIds
338281
338791
  ]);
338282
338792
  for (const blockInstanceId of blockInstanceIds) {
@@ -338319,13 +338829,13 @@ const createContentBlockApplication = ({
338319
338829
  metas,
338320
338830
  resolveSourceAssetId
338321
338831
  }) => {
338322
- const resolveSource = ({
338832
+ const resolveSource = async ({
338323
338833
  source,
338324
338834
  state,
338325
338835
  blockInstanceId,
338326
338836
  variables
338327
338837
  }) => {
338328
- const resolved = resolveSourceAssetId?.({ source, state, variables });
338838
+ const resolved = await resolveSourceAssetId?.({ source, state, variables });
338329
338839
  if (resolveSourceAssetId !== void 0) {
338330
338840
  if (resolved === void 0 || resolved === "") {
338331
338841
  throw new Error("Content source does not resolve to an MDX Asset");
@@ -338347,11 +338857,11 @@ const createContentBlockApplication = ({
338347
338857
  values.set(dataSource2.id, dataSource2.value.value);
338348
338858
  }
338349
338859
  }
338350
- const assetId2 = resolveContentBlockSourceAssetId({ source, values });
338860
+ const assetId2 = await resolveContentBlockSourceAssetId({ source, values });
338351
338861
  if (assetId2 !== void 0) {
338352
338862
  return assetId2;
338353
338863
  }
338354
- const evaluated = source.type === "expression" ? computeExpression(source.value, values) : void 0;
338864
+ const evaluated = source.type === "expression" ? await computeExpression(source.value, values) : void 0;
338355
338865
  const suppliedVariableShapes = Object.entries(variables ?? {}).map(
338356
338866
  ([name2, value2]) => `${JSON.stringify(name2)} (${describeValueShape(value2)})`
338357
338867
  ).join(", ") || "none";
@@ -338382,7 +338892,7 @@ const createContentBlockApplication = ({
338382
338892
  renderScope,
338383
338893
  variables
338384
338894
  }) => {
338385
- const assetId2 = resolveSource({
338895
+ const assetId2 = await resolveSource({
338386
338896
  source,
338387
338897
  state,
338388
338898
  blockInstanceId,
@@ -344719,6 +345229,41 @@ const appRoot = "app";
344719
345229
  const generatedDir = join$2(appRoot, "__generated__");
344720
345230
  const routesDir = join$2(appRoot, "routes");
344721
345231
  const generatedOutputDirectories = [generatedDir, routesDir];
345232
+ const hydrateLocalMarkdownContents = async ({
345233
+ artifact,
345234
+ assets,
345235
+ assetsDirectory,
345236
+ includeMarkdown
345237
+ }) => {
345238
+ const assetsById = new Map(assets.map((asset2) => [asset2.id, asset2]));
345239
+ const missingContents = await Promise.all(
345240
+ artifact.documents.filter(
345241
+ (document2) => (document2.extension === "mdx" || includeMarkdown && document2.extension === "md") && document2.contentRef !== void 0 && artifact.contents?.[document2.contentRef] === void 0
345242
+ ).map(async (document2) => {
345243
+ const asset2 = assetsById.get(document2._id);
345244
+ if (asset2 === void 0) {
345245
+ return;
345246
+ }
345247
+ const content2 = await readFile(
345248
+ getLocalAssetPath(asset2.name, assetsDirectory),
345249
+ "utf8"
345250
+ ).catch(() => void 0);
345251
+ return content2 === void 0 ? void 0 : [document2.contentRef, content2];
345252
+ })
345253
+ );
345254
+ const contents = Object.fromEntries(
345255
+ missingContents.filter(
345256
+ (entry2) => entry2 !== void 0
345257
+ )
345258
+ );
345259
+ return Object.keys(contents).length === 0 ? artifact : {
345260
+ ...artifact,
345261
+ contents: {
345262
+ ...artifact.contents,
345263
+ ...contents
345264
+ }
345265
+ };
345266
+ };
344722
345267
  const getBoundSystemRouteParameter = (expression2) => {
344723
345268
  const path2 = parseStaticMemberPath(expression2);
344724
345269
  const variable2 = path2?.[0];
@@ -344892,7 +345437,9 @@ const getAssetResourcePrerenderPaths = ({
344892
345437
  );
344893
345438
  if (completeRouteConfigurations.length > 0 && enumerableConfigurations.length === 0) {
344894
345439
  throw new Error(
344895
- `Dynamic SSG route parameter ${JSON.stringify(firstUnenumerableParameter)} cannot be completely enumerated from every Assets query branch`
345440
+ `Dynamic SSG route parameter ${JSON.stringify(
345441
+ firstUnenumerableParameter
345442
+ )} cannot be completely enumerated from every Assets query branch`
344896
345443
  );
344897
345444
  }
344898
345445
  }
@@ -344939,7 +345486,9 @@ const getAssetResourcePrerenderPaths = ({
344939
345486
  for (const match of [...pathParameters].reverse()) {
344940
345487
  const name2 = match.groups?.name;
344941
345488
  const value2 = values.get(name2);
344942
- path2 = `${path2.slice(0, match.index)}${encodeURIComponent(value2)}${path2.slice((match.index ?? 0) + match[0].length)}`;
345489
+ path2 = `${path2.slice(0, match.index)}${encodeURIComponent(
345490
+ value2
345491
+ )}${path2.slice((match.index ?? 0) + match[0].length)}`;
344943
345492
  }
344944
345493
  paths.add(path2);
344945
345494
  if (paths.size > assetResourceLimits.candidateDocuments) {
@@ -345026,18 +345575,19 @@ const createRuntimeFetch = createGeneratedAssetResourceRuntime({
345026
345575
  runtimeAssets,
345027
345576
  });
345028
345577
 
345029
- export const createGeneratedAssetResourceFetch = ({ request, fallback }: ${inputType}) =>
345030
- createRuntimeFetch({ request, fallback });
345578
+ export const createGeneratedAssetResourceFetch = ({ request, context, fallback }: ${inputType}) =>
345579
+ createRuntimeFetch({ request, context, fallback });
345031
345580
  `;
345032
345581
  };
345033
345582
  const materializeVerifiedAssetIndex = async ({
345034
345583
  index: index2,
345035
345584
  runtimeAssets,
345036
345585
  includeDocumentRuntimeAssets,
345586
+ includeContents,
345037
345587
  generatedDirectory,
345038
345588
  deploymentId
345039
345589
  }) => {
345040
- const runtimeIndex = index2 === void 0 ? void 0 : createContentRuntimeArtifact(index2);
345590
+ const runtimeIndex = index2 === void 0 ? void 0 : createContentRuntimeArtifact(index2, { includeContents });
345041
345591
  const serializedIndex = runtimeIndex === void 0 ? void 0 : serializeContentRuntimeArtifact(runtimeIndex);
345042
345592
  const runtimeAssetIds = runtimeIndex === void 0 ? [] : getContentRuntimeArtifactRuntimeAssetIds({
345043
345593
  artifact: runtimeIndex,
@@ -345260,8 +345810,9 @@ Please check webstudio --help for more details`
345260
345810
  preserveTemplates: preserveRouteTemplates,
345261
345811
  templatesDirectory: join$2(buildRoot, routeTemplatesDirectory)
345262
345812
  };
345813
+ const isStaticBuild = options.template.includes("ssg");
345263
345814
  let framework;
345264
- if (options.template.includes("ssg")) {
345815
+ if (isStaticBuild) {
345265
345816
  framework = await createFramework(frameworkOptions);
345266
345817
  } else if (options.template.includes("react-router")) {
345267
345818
  framework = await createFramework$1(frameworkOptions);
@@ -345294,7 +345845,17 @@ Please check webstudio --help for more details`
345294
345845
  const siteData = parsedSiteData.data;
345295
345846
  const pages2 = migratePages(siteData.build.pages);
345296
345847
  const publicationBuild = { ...siteData.build, pages: pages2 };
345297
- const verifiedAssetIndex = siteData.assetIndex === void 0 ? void 0 : await verifyContentArtifact(siteData.assetIndex);
345848
+ let verifiedAssetIndex = siteData.assetIndex === void 0 ? void 0 : await verifyContentArtifact(siteData.assetIndex);
345849
+ if (verifiedAssetIndex !== void 0 && (options.previewIdentity === true || options.assets === true)) {
345850
+ verifiedAssetIndex = await hydrateLocalMarkdownContents({
345851
+ artifact: verifiedAssetIndex,
345852
+ assets: siteData.assets,
345853
+ assetsDirectory: options.sourceAssetsDirectory ?? join$2(buildRoot, LOCAL_ASSETS_DIR),
345854
+ // SSR only needs local MDX sources during component compilation. Its
345855
+ // runtime reads article contents over HTTP, just like hosted sites.
345856
+ includeMarkdown: isStaticBuild
345857
+ });
345858
+ }
345298
345859
  let dynamicMdxCandidates;
345299
345860
  if (hasDynamicPublishedMdxSources(publicationBuild)) {
345300
345861
  dynamicMdxCandidates = verifiedAssetIndex === void 0 ? /* @__PURE__ */ new Map() : resolvePublishedMdxAssetCandidates({
@@ -345414,7 +345975,7 @@ Please check webstudio --help for more details`
345414
345975
  asset2,
345415
345976
  "https://placeholder.local"
345416
345977
  );
345417
- return siteData.build.deployment?.destination === "saas" && options.assets === false ? runtimeAsset.url : `${assetBaseUrl}${asset2.name}`;
345978
+ return isPublishedDeployment(siteData.build.deployment) && options.assets === false ? runtimeAsset.url : `${assetBaseUrl}${asset2.name}`;
345418
345979
  };
345419
345980
  const runtimeAssetsById = Object.fromEntries(
345420
345981
  siteData.assets.map((asset2) => {
@@ -345427,8 +345988,9 @@ Please check webstudio --help for more details`
345427
345988
  {
345428
345989
  ...runtimeAsset,
345429
345990
  contentRef: asset2.name,
345430
- // SaaS serves project assets through its storage-backed proxy.
345431
- // Generated projects with downloaded assets serve them locally.
345991
+ // Hosted deployments serve project assets through storage-backed
345992
+ // proxies. Generated projects with downloaded assets serve them
345993
+ // locally.
345432
345994
  url: getPublishedAssetUrl(asset2)
345433
345995
  }
345434
345996
  ];
@@ -345800,7 +346362,9 @@ Please check webstudio --help for more details`
345800
346362
  for (const contribution of componentBuildContributions.values()) {
345801
346363
  for (const buildImport of contribution.imports) {
345802
346364
  if (buildImport.imported === void 0) {
345803
- importsString += `import ${buildImport.local} from ${JSON.stringify(buildImport.source)};
346365
+ importsString += `import ${buildImport.local} from ${JSON.stringify(
346366
+ buildImport.source
346367
+ )};
345804
346368
  `;
345805
346369
  } else {
345806
346370
  importsString += `import { ${buildImport.imported} as ${buildImport.local} } from ${JSON.stringify(buildImport.source)};
@@ -345930,6 +346494,7 @@ Please check webstudio --help for more details`
345930
346494
  dataSources,
345931
346495
  props: props2,
345932
346496
  resources,
346497
+ instances,
345933
346498
  contentBlockResourceSelections: Array.from(
345934
346499
  pageData.publishedContentBlocks?.values() ?? []
345935
346500
  ).flatMap(
@@ -346019,13 +346584,20 @@ Please check webstudio --help for more details`
346019
346584
  await writeGeneratedFile(
346020
346585
  join$2(generatedDir, "$resources.sitemap.xml.ts"),
346021
346586
  `
346022
- export const sitemap: Array<{ path: string; lastModified: string }> = ${JSON.stringify(sitemap, null, 2)};
346587
+ export const sitemap: Array<{ path: string; lastModified: string }> = ${JSON.stringify(
346588
+ sitemap,
346589
+ null,
346590
+ 2
346591
+ )};
346023
346592
  `
346024
346593
  );
346025
346594
  await materializeVerifiedAssetIndex({
346026
346595
  index: verifiedAssetIndex,
346027
346596
  runtimeAssets: runtimeAssetsById,
346028
346597
  includeDocumentRuntimeAssets: assetCompilationPlan !== void 0 && requiresRuntimeDocumentData(assetCompilationPlan),
346598
+ // Only static prerendering consumes embedded source files. Both local
346599
+ // and hosted SSR use the same HTTP content loader and serve assets.
346600
+ includeContents: isStaticBuild,
346029
346601
  generatedDirectory: generatedDir,
346030
346602
  deploymentId: siteData.build.id
346031
346603
  });
@@ -348475,6 +349047,7 @@ const publishCommandOptions = (yargs) => publishDomainsOption(publishTargetOptio
348475
349047
  type: "string",
348476
349048
  describe: "Optional idempotency key for retrying the same publish"
348477
349049
  });
349050
+ const checkPublishReadinessCommandOptions = (yargs) => publishDomainsOption(publishTargetOption(apiCommandOptions(yargs)));
348478
349051
  const publishJobCommandOptions = (yargs) => apiCommandOptions(yargs).option("job", {
348479
349052
  type: "string",
348480
349053
  describe: "Required publish job id returned by publish or unpublish",
@@ -349884,6 +350457,18 @@ const apiCommandHandlers = {
349884
350457
  };
349885
350458
  return runProjectSessionCommand("publish", input2, connection, dependencies2);
349886
350459
  },
350460
+ "check-publish-readiness": async (options, connection, dependencies2) => {
350461
+ const input2 = {
350462
+ target: publishTargetValue(options.target),
350463
+ domains: listStringOption(options.domain)
350464
+ };
350465
+ return runProjectSessionCommand(
350466
+ "check-publish-readiness",
350467
+ input2,
350468
+ connection,
350469
+ dependencies2
350470
+ );
350471
+ },
349887
350472
  "list-publishes": async (options, connection, dependencies2) => runProjectSessionCommand(
349888
350473
  "list-publishes",
349889
350474
  {
@@ -350332,6 +350917,7 @@ const apiCommandOptionsByCommand = {
350332
350917
  "delete-resource": deleteResourceCommandOptions,
350333
350918
  "list-domains": paginatedListCommandOptions,
350334
350919
  publish: publishCommandOptions,
350920
+ "check-publish-readiness": checkPublishReadinessCommandOptions,
350335
350921
  "get-publish-job": publishJobCommandOptions,
350336
350922
  unpublish: unpublishCommandOptions,
350337
350923
  "create-domain": createDomainCommandOptions,
@@ -350363,6 +350949,10 @@ const apiCommandMetadata = publicApiOperations.map((operation) => ({
350363
350949
  }));
350364
350950
  const highLevelCliCommands = [
350365
350951
  { command: "audit", operation: "audit" },
350952
+ {
350953
+ command: "check-publish-readiness",
350954
+ operation: "check-publish-readiness"
350955
+ },
350366
350956
  { command: "permissions", operation: "permissions" },
350367
350957
  { command: "get-assets-resource", operation: "get-assets-resource" },
350368
350958
  { command: "create-assets-resource", operation: "create-assets-resource" },
@@ -350915,7 +351505,7 @@ const apiCommandsByArea = {
350915
351505
  projectQuality: cliCommandMetadata.filter(({ cliCommand }) => cliCommand === "audit").map(({ cliCommand }) => cliCommand),
350916
351506
  assetsAndIndexes: cliCommandMetadata.filter(({ cliCommand }) => cliCommand.includes("asset")).map(({ cliCommand }) => cliCommand),
350917
351507
  publishAndDomains: cliCommandMetadata.filter(
350918
- ({ cliCommand }) => cliCommand.startsWith("publish ") || cliCommand.startsWith("domains ")
351508
+ ({ cliCommand }) => cliCommand === "check-publish-readiness" || cliCommand.startsWith("publish ") || cliCommand.startsWith("domains ")
350919
351509
  ).map(({ cliCommand }) => cliCommand),
350920
351510
  pagesAndSettings: cliCommandMetadata.filter(
350921
351511
  ({ cliCommand }) => [