@cueframe/kernel 0.2.22 → 0.2.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_members/composition/scene/clipRules.d.ts +10 -0
- package/dist/_members/mcp/core.d.ts +16 -1
- package/dist/_members/mcp/generated/operations.d.ts +2 -0
- package/dist/animate/preparation-facts.js +2 -2
- package/dist/animate.js +3 -3
- package/dist/authoring/scene.js +2 -2
- package/dist/authoring.js +2 -2
- package/dist/{chunk-DJWCD3RF.js → chunk-3OOMVQ6I.js} +4 -4
- package/dist/{chunk-VDSO2KZY.js → chunk-5BAWOULP.js} +1 -1
- package/dist/{chunk-CDZBSLVA.js → chunk-H5CPILOK.js} +2 -2
- package/dist/{chunk-DEDZKZ6G.js → chunk-JBWSK2YD.js} +2 -2
- package/dist/{chunk-E54DK225.js → chunk-JCQTSVZQ.js} +1 -1
- package/dist/{chunk-PQDALM2G.js → chunk-JNQKX4OI.js} +1 -1
- package/dist/{chunk-YV5AYMNK.js → chunk-JRJQECCF.js} +1 -1
- package/dist/{chunk-NG7DP46H.js → chunk-MMZMS3S4.js} +1 -1
- package/dist/{chunk-BAVEHXVC.js → chunk-NXEJASGI.js} +9 -7
- package/dist/{chunk-TZ7DKL2G.js → chunk-OBA6NW4S.js} +1 -1
- package/dist/{chunk-URQQTAHZ.js → chunk-PNJ7DACK.js} +122 -111
- package/dist/{chunk-PRSRV7AT.js → chunk-TE3PNQG6.js} +2 -2
- package/dist/{chunk-WLU5XPDG.js → chunk-TXI53LIT.js} +2 -2
- package/dist/{chunk-LD4XQQRL.js → chunk-WAUVKF2F.js} +1 -1
- package/dist/{chunk-7YL7NJJF.js → chunk-XACXNDFL.js} +6 -1
- package/dist/component-runtime/browserOptions.js +2 -2
- package/dist/component-runtime/render.js +3 -3
- package/dist/component-runtime.js +4 -4
- package/dist/compose.js +6 -6
- package/dist/composition/scene.js +3 -1
- package/dist/composition-ops.js +89 -32
- package/dist/core/render.js +2 -2
- package/dist/core.js +2 -2
- package/dist/mcp/adapter.js +3 -3
- package/dist/mcp/core.js +3 -1
- package/dist/mcp/curation.js +1 -1
- package/dist/mcp/server.js +4 -4
- package/dist/mcp.js +4 -4
- package/dist/primitives/effects.js +4 -4
- package/dist/primitives/layouts.js +4 -4
- package/dist/primitives/scenes.js +4 -4
- package/dist/primitives.js +6 -6
- package/dist/render-harness.js +6 -6
- package/package.json +11 -11
|
@@ -14,6 +14,16 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import type { Composition, Gap, TimelineClip, Track } from '../validators/composition.js';
|
|
16
16
|
import { type SceneShotSpecV2 } from './schema.js';
|
|
17
|
+
/**
|
|
18
|
+
* What a scene slot admits, stated once. The refusal below names these formats;
|
|
19
|
+
* so does the `scene.add` / `scene.update` contract, which reads them from here.
|
|
20
|
+
* They were only ever in the refusal, so the only way to learn them was to bind
|
|
21
|
+
* the wrong media and read the error.
|
|
22
|
+
*/
|
|
23
|
+
export declare const SCENE_SLOT_MEDIA_FORMATS: {
|
|
24
|
+
readonly image: "PNG, JPEG or WebP";
|
|
25
|
+
readonly video: "MP4 or WebM";
|
|
26
|
+
};
|
|
17
27
|
export type SceneClipIssueCode = 'validation_error' | 'invalid_composition';
|
|
18
28
|
/** One rejection: a path into the clip (or request) and an actionable detail. */
|
|
19
29
|
export interface SceneClipRuleIssue {
|
|
@@ -38,6 +38,19 @@ export type ToolResult = {
|
|
|
38
38
|
structuredContent?: Record<string, unknown>;
|
|
39
39
|
};
|
|
40
40
|
export declare function text(s: string): ToolResult;
|
|
41
|
+
/**
|
|
42
|
+
* A JSON response, carried BOTH ways: the rendered prose a human reads, and the
|
|
43
|
+
* parsed object a program can consume.
|
|
44
|
+
*
|
|
45
|
+
* Curated tools used to return prose only, so `create_render` promised
|
|
46
|
+
* `{id,status,warnings?}` and delivered "Render queued.\n\nrenderId: …". A
|
|
47
|
+
* generic MCP consumer had to scrape it (CUE-15 P0). `structuredContent` is the
|
|
48
|
+
* protocol's channel for exactly this; the text block stays as display.
|
|
49
|
+
*
|
|
50
|
+
* Attached only for a non-null, non-array OBJECT, which is what the protocol
|
|
51
|
+
* allows — a bare array or scalar would be rejected by a validating client.
|
|
52
|
+
*/
|
|
53
|
+
export declare function textWithData(s: string, data: unknown): ToolResult;
|
|
41
54
|
export declare function errText(s: string): ToolResult;
|
|
42
55
|
export declare function firstText(r: ToolResult): string;
|
|
43
56
|
export declare function sniffImageMediaType(base64: string): string | undefined;
|
|
@@ -45,7 +58,9 @@ export declare function sniffAudioMediaType(base64: string): string | undefined;
|
|
|
45
58
|
export declare function withMedia(payload: string, media: {
|
|
46
59
|
data: string;
|
|
47
60
|
kind: 'image' | 'audio';
|
|
48
|
-
}[]
|
|
61
|
+
}[],
|
|
62
|
+
/** The parsed response, carried alongside the media for programmatic callers. */
|
|
63
|
+
data?: unknown): ToolResult;
|
|
49
64
|
export declare function fetchAsBase64(url: string, opts?: {
|
|
50
65
|
timeoutMs?: number;
|
|
51
66
|
maxBytes?: number;
|
|
@@ -27,6 +27,8 @@ export interface GeneratedOperation {
|
|
|
27
27
|
bodyKey: string | null;
|
|
28
28
|
description: string;
|
|
29
29
|
annotations: GeneratedAnnotations;
|
|
30
|
+
/** The 2xx JSON body as a self-contained JSON Schema, when it is an object. */
|
|
31
|
+
outputSchema?: Record<string, unknown>;
|
|
30
32
|
}
|
|
31
33
|
export interface GeneratedQueryParameter {
|
|
32
34
|
name: string;
|
|
@@ -4,11 +4,11 @@ import {
|
|
|
4
4
|
sceneGrainPreparationCpuAllocationV1,
|
|
5
5
|
scenePresetBuilderDescriptorV1,
|
|
6
6
|
sceneSlabPreparationFactsV1
|
|
7
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-OBA6NW4S.js";
|
|
8
8
|
import {
|
|
9
9
|
photographicStudioPreparationFactsV1,
|
|
10
10
|
sceneFocusPreparationAllocationsV1
|
|
11
|
-
} from "../chunk-
|
|
11
|
+
} from "../chunk-XACXNDFL.js";
|
|
12
12
|
import "../chunk-2L7PYYJK.js";
|
|
13
13
|
import "../chunk-2ESYSVXG.js";
|
|
14
14
|
export {
|
package/dist/animate.js
CHANGED
|
@@ -102,7 +102,7 @@ import {
|
|
|
102
102
|
useStage,
|
|
103
103
|
weightsAt,
|
|
104
104
|
worldTransform
|
|
105
|
-
} from "./chunk-
|
|
105
|
+
} from "./chunk-JBWSK2YD.js";
|
|
106
106
|
import {
|
|
107
107
|
DEFAULT_LIGHTING_PROFILE,
|
|
108
108
|
DEVICE_GLASS_OPACITY_ENCODED,
|
|
@@ -161,7 +161,7 @@ import {
|
|
|
161
161
|
studioShadowFrustum,
|
|
162
162
|
verifyPhotographicStudioHdr,
|
|
163
163
|
withNormalisedFaceUv
|
|
164
|
-
} from "./chunk-
|
|
164
|
+
} from "./chunk-OBA6NW4S.js";
|
|
165
165
|
import {
|
|
166
166
|
ALLOWED_BAKE_SCALES,
|
|
167
167
|
DEFAULT_BAKE_SCALE,
|
|
@@ -183,7 +183,7 @@ import {
|
|
|
183
183
|
projectedSlotEdges,
|
|
184
184
|
sceneFocusPreparationAllocationsV1,
|
|
185
185
|
selectSceneBakeScale
|
|
186
|
-
} from "./chunk-
|
|
186
|
+
} from "./chunk-XACXNDFL.js";
|
|
187
187
|
import "./chunk-2L7PYYJK.js";
|
|
188
188
|
import "./chunk-AVTEPAWI.js";
|
|
189
189
|
import "./chunk-2ESYSVXG.js";
|
package/dist/authoring/scene.js
CHANGED
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
sceneTrackIdFor,
|
|
14
14
|
validateSceneAdd,
|
|
15
15
|
validateSceneUpdate
|
|
16
|
-
} from "../chunk-
|
|
16
|
+
} from "../chunk-JCQTSVZQ.js";
|
|
17
17
|
import {
|
|
18
18
|
SCENE_TRANSITION_KINDS,
|
|
19
19
|
collectSceneClipIssues,
|
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
offFrameLattice,
|
|
23
23
|
readSceneSourceRef,
|
|
24
24
|
sceneClipShapeIssues
|
|
25
|
-
} from "../chunk-
|
|
25
|
+
} from "../chunk-XACXNDFL.js";
|
|
26
26
|
import "../chunk-2L7PYYJK.js";
|
|
27
27
|
import "../chunk-2ESYSVXG.js";
|
|
28
28
|
export {
|
package/dist/authoring.js
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
hasSceneOp,
|
|
5
5
|
isSceneOp,
|
|
6
6
|
materializeSceneOpsCore
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-JCQTSVZQ.js";
|
|
8
8
|
import {
|
|
9
9
|
ZERO_USAGE,
|
|
10
10
|
buildDirectorTools,
|
|
@@ -67,7 +67,7 @@ import "./chunk-7PA7FGLD.js";
|
|
|
67
67
|
import {
|
|
68
68
|
collectSceneClipIssues,
|
|
69
69
|
isSceneShotClip
|
|
70
|
-
} from "./chunk-
|
|
70
|
+
} from "./chunk-XACXNDFL.js";
|
|
71
71
|
import "./chunk-2L7PYYJK.js";
|
|
72
72
|
import "./chunk-AVTEPAWI.js";
|
|
73
73
|
import "./chunk-2ESYSVXG.js";
|
|
@@ -312,7 +312,7 @@ Call wait_job(kind="compose", id="${j.composeJobId}", projectId="${a.projectId}"
|
|
|
312
312
|
name: "apply_composition",
|
|
313
313
|
operationId: "applyComposition",
|
|
314
314
|
pathArgs: { projectId: "id" },
|
|
315
|
-
description: 'Atomically apply an array of CompositionOps to a project composition. All ops succeed or none do (transactional). Pass `if_match` for optimistic-concurrency control (409 stale_etag on mismatch) and `dry_run: true` to validate the batch without persisting. Use this to seed a composition (add media clips) or make targeted edits (set a crop intent, reorder clips, set the format). CAPTIONS: attach content with {type:"captions.fromTranscript", mediaId, window?} \u2014 the server slices the cached word-timed transcript, rebases times, and sentence-splits into segments (no pasting words; 422 media_no_transcript if the media has no speech); style it with {type:"setCaptionStyle", style}; or set explicit words with {type:"setCaptions", segments, style?} (e.g. translations or your own VO timings). Brand is NOT set here \u2014 it lives on the project (create_project / PATCH /projects/:id
|
|
315
|
+
description: 'Atomically apply an array of CompositionOps to a project composition. All ops succeed or none do (transactional). Pass `if_match` for optimistic-concurrency control (409 stale_etag on mismatch) and `dry_run: true` to validate the batch without persisting. Use this to seed a composition (add media clips) or make targeted edits (set a crop intent, reorder clips, set the format). CAPTIONS: attach content with {type:"captions.fromTranscript", mediaId, window?} \u2014 the server slices the cached word-timed transcript, rebases times, and sentence-splits into segments (no pasting words; 422 media_no_transcript if the media has no speech); style it with {type:"setCaptionStyle", style}; or set explicit words with {type:"setCaptions", segments, style?} (e.g. translations or your own VO timings). Brand is NOT set here \u2014 it lives on the project (create_project / update_project with brandKitId \u2014 or PATCH /projects/:id over REST). CARDS: a {kind:"card", html, tokens} clip projects each `tokens` KEY `x` to the CSS custom property `--cf-x`, so the html must read it as `var(--cf-x)` \u2014 write `tokens:{"plate":"#0af"}` + `background:var(--cf-plate)`. Do NOT put dashes in the key: `"--plate"` becomes `--cf---plate` and your `var(--plate)` then resolves to NOTHING, which CSS silently degrades to a transparent background and black text. Responses carry `warnings[]` when a card reads a var nothing defines. SCENE SHOTS: for a 3D product shot \u2014 a tilted page screenshot, a lit laptop/phone showing a real screenshot, two-colour type, a colour-field backdrop, focus/grain/vignette and a camera move \u2014 use {type:"scene.add", clipId, newTrack|trackId, startTime, duration, scene, assets} and revise it with {type:"scene.update", clipId, scene?, assets?, startTime?, duration?}. You author a scene SPEC, never wrapper TSX; the server registers the component for you. There is NO built-in scene primitive in list_catalog \u2014 READ cueframe://scene-shot first for the JSON schema, the canonical V2 world-objects recipe with nested groups, slabs, pages, phones, laptops, world/screen text, admitted surfaces, camera motion, lighting, and the current resource limits.',
|
|
316
316
|
okFormat: (j, a) => {
|
|
317
317
|
const warns = formatWarnings(j);
|
|
318
318
|
if (j && typeof j.valid === "boolean") {
|
|
@@ -348,7 +348,7 @@ ${JSON.stringify(r.errors ?? [], null, 2)}${warns}`;
|
|
|
348
348
|
name: "create_render",
|
|
349
349
|
operationId: "createRender",
|
|
350
350
|
pathArgs: { projectId: "id" },
|
|
351
|
-
description: "Queue an MP4 render of a project's composition. Returns { id (renderId), status, warnings? } \u2014 `warnings[]` carries non-fatal advisories (omitted when none). The render themes from the project's brand kit (bind one via create_project / PATCH /projects/:id
|
|
351
|
+
description: "Queue an MP4 render of a project's composition. Returns { id (renderId), status, warnings? } \u2014 `warnings[]` carries non-fatal advisories (omitted when none). The render themes from the project's brand kit (bind one via create_project / update_project with brandKitId \u2014 or PATCH /projects/:id over REST; without one the output is unbranded). Then call wait_job(kind=\"render\", id=renderId, projectId=...) to block until the file is ready and get the download URL, or register a webhook (create_webhook on render.completed \u2014 status rides the payload).",
|
|
352
352
|
okFormat: (j, a) => `Render queued.
|
|
353
353
|
|
|
354
354
|
renderId: ${j.id}
|
|
@@ -552,7 +552,7 @@ Poll get_media_facts(mediaItemId="${a.mediaItemId}", kind="${a.body?.kind}", sta
|
|
|
552
552
|
{
|
|
553
553
|
name: "create_project",
|
|
554
554
|
operationId: "createProject",
|
|
555
|
-
description: "Create a new project \u2014 the unit you compose and render into. compose / apply_composition / create_render / the preview family all require a projectId; this mints one. Pass name (required) plus optionally a format (aspectRatio/fps/resolution) and brandKitId. brandKitId binds a brand kit to the PROJECT (pass the kitId from create_brand_kit): colors/fonts/motion theme every render of this project automatically (omit it and the output is unbranded). Bind or change it later via PATCH /projects/:id. Returns the ProjectResponse (id + metadata)."
|
|
555
|
+
description: "Create a new project \u2014 the unit you compose and render into. compose / apply_composition / create_render / the preview family all require a projectId; this mints one. Pass name (required) plus optionally a format (aspectRatio/fps/resolution) and brandKitId. brandKitId binds a brand kit to the PROJECT (pass the kitId from create_brand_kit): colors/fonts/motion theme every render of this project automatically (omit it and the output is unbranded). Bind or change it later via update_project (PATCH /projects/:id over REST). Returns the ProjectResponse (id + metadata)."
|
|
556
556
|
},
|
|
557
557
|
{
|
|
558
558
|
name: "new_composition",
|
|
@@ -806,7 +806,7 @@ Render it with create_render(projectId="${a.projectId}", body={ compositionId: "
|
|
|
806
806
|
{
|
|
807
807
|
name: "create_brand_kit",
|
|
808
808
|
operationId: "createBrandKit",
|
|
809
|
-
description: "Create or UPSERT a brand kit (re-POSTing the same kitId updates it in place \u2014 this is also the brand-kit UPDATE path). Sets fonts/colors/logo. This is brand step 0 of the workflow: author the kit, then bind it to a PROJECT so colors/fonts/motion theme the output AUTOMATICALLY \u2014 pass its kitId as brandKitId to create_project, or attach it to an existing project via PATCH /projects/:id. Without a bound kit, create_render produces UNBRANDED output. Tenant-scoped (no project arg)."
|
|
809
|
+
description: "Create or UPSERT a brand kit (re-POSTing the same kitId updates it in place \u2014 this is also the brand-kit UPDATE path). Sets fonts/colors/logo. This is brand step 0 of the workflow: author the kit, then bind it to a PROJECT so colors/fonts/motion theme the output AUTOMATICALLY \u2014 pass its kitId as brandKitId to create_project, or attach it to an existing project via update_project (PATCH /projects/:id over REST). Without a bound kit, create_render produces UNBRANDED output. Tenant-scoped (no project arg)."
|
|
810
810
|
},
|
|
811
811
|
{
|
|
812
812
|
name: "extract_brand_kit",
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
componentBrowserBackend,
|
|
16
16
|
componentBrowserOptions,
|
|
17
17
|
readGpuAttestation
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-5BAWOULP.js";
|
|
19
19
|
import {
|
|
20
20
|
ComponentCapturePageRasterAttestationV1,
|
|
21
21
|
ComponentGraphicsApiV2,
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
} from "./chunk-ZVG446DJ.js";
|
|
29
29
|
import {
|
|
30
30
|
parseSceneShotSpecV2
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-XACXNDFL.js";
|
|
32
32
|
import {
|
|
33
33
|
BUNDLED_FONT_FACES
|
|
34
34
|
} from "./chunk-AVTEPAWI.js";
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
slabTriangleCount,
|
|
20
20
|
takeSceneEnvironment,
|
|
21
21
|
useSceneActualResourceRegistrarV1
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-OBA6NW4S.js";
|
|
23
23
|
import {
|
|
24
24
|
PHOTOGRAPHIC_STUDIO_RIG_ID,
|
|
25
25
|
SCENE_SLAB_CONTENT_OFFSET,
|
|
@@ -31,7 +31,7 @@ import {
|
|
|
31
31
|
sceneTextureBytes,
|
|
32
32
|
sceneVideoMidpointAddressV1,
|
|
33
33
|
selectSceneBakeScale
|
|
34
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-XACXNDFL.js";
|
|
35
35
|
import {
|
|
36
36
|
resolveCaptionFaces
|
|
37
37
|
} from "./chunk-AVTEPAWI.js";
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
} from "./chunk-W2245F6G.js";
|
|
25
25
|
import {
|
|
26
26
|
FlexLayout
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-JBWSK2YD.js";
|
|
28
28
|
|
|
29
29
|
// ../execution/primitives/src/layouts/chat-to-preview-layout/index.tsx
|
|
30
30
|
import { Easing, interpolate, useCurrentFrame, useVideoConfig } from "remotion";
|
|
@@ -2,10 +2,10 @@ import {
|
|
|
2
2
|
querySchemaShape,
|
|
3
3
|
serializeQuery,
|
|
4
4
|
waitForJob
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-MMZMS3S4.js";
|
|
6
6
|
import {
|
|
7
7
|
CURATED_TOOLS
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-3OOMVQ6I.js";
|
|
9
9
|
import {
|
|
10
10
|
GENERATED_OPERATIONS,
|
|
11
11
|
apiErrorFrom,
|
|
@@ -21,8 +21,9 @@ import {
|
|
|
21
21
|
safeParse,
|
|
22
22
|
sniffImageMediaType,
|
|
23
23
|
text,
|
|
24
|
+
textWithData,
|
|
24
25
|
withMedia
|
|
25
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-PNJ7DACK.js";
|
|
26
27
|
|
|
27
28
|
// ../mcp/src/prompts.ts
|
|
28
29
|
var skillListCache = null;
|
|
@@ -3616,7 +3617,7 @@ function registerResources(server, ex) {
|
|
|
3616
3617
|
}),
|
|
3617
3618
|
{
|
|
3618
3619
|
title: "Component catalog",
|
|
3619
|
-
description: "The component catalog: the FULL built-in primitive catalog (
|
|
3620
|
+
description: "The component catalog: the FULL built-in primitive catalog (lower-third, cinematic-title, color-grade, the `scenes`-category templates \u2026) PLUS your org-installed custom components. This is 'discover what to build with'. resources/list enumerates EVERY entry with its discovery facets (source/category/kind/tier/useCase) and a placement hint; read one for its full prop schema. NOT only your authored components. NOTE the word 'scene' means two different things: the `scenes` CATEGORY here is composed built-in templates you place by primitiveId, whereas a SCENE SHOT (the scene.add op, cueframe://scene-shot) is a 3D spec you author and has no catalog entry at all. URI: cueframe://component/{componentId}.",
|
|
3620
3621
|
mimeType: "application/json"
|
|
3621
3622
|
},
|
|
3622
3623
|
async (uri, { componentId }) => jsonResource(uri, await read(ex, "getComponent", () => String(componentId)))
|
|
@@ -3747,7 +3748,8 @@ function registerCuratedTools(server, ex, opts) {
|
|
|
3747
3748
|
const bodySchema = bodySchemaFor(op);
|
|
3748
3749
|
if (bodySchema) inputSchema.body = bodySchema;
|
|
3749
3750
|
const annotations = { ...op.annotations, ...spec.annotations };
|
|
3750
|
-
|
|
3751
|
+
const outputSchema = op.outputSchema && !spec.okText ? z.fromJSONSchema(op.outputSchema) : void 0;
|
|
3752
|
+
server.registerTool(spec.name, { title: spec.title ?? titleCase(spec.name), description: spec.description, inputSchema: z.object(inputSchema), ...outputSchema ? { outputSchema } : {}, annotations }, async (args, extra) => timed(opts?.onEvent, spec.name, async (report) => {
|
|
3751
3753
|
const a = { ...spec.defaults ?? {}, ...args };
|
|
3752
3754
|
try {
|
|
3753
3755
|
const query = serializeQuery(op.queryParams, a);
|
|
@@ -3760,9 +3762,9 @@ function registerCuratedTools(server, ex, opts) {
|
|
|
3760
3762
|
const urls = spec.preview.urls(json).filter(Boolean);
|
|
3761
3763
|
const data = await fetchPreviews(urls, spec.preview.cap ?? 12);
|
|
3762
3764
|
report({ preview: { urls: urls.length, fetched: data.length } });
|
|
3763
|
-
if (data.length) return withMedia(payload, data.map((d) => ({ data: d, kind })));
|
|
3765
|
+
if (data.length) return withMedia(payload, data.map((d) => ({ data: d, kind })), json);
|
|
3764
3766
|
}
|
|
3765
|
-
return
|
|
3767
|
+
return textWithData(payload, json);
|
|
3766
3768
|
}, query);
|
|
3767
3769
|
} catch (err) {
|
|
3768
3770
|
return errText(`${spec.name} failed: ${fmtErr(err)}`);
|