@growth-labs/cms 0.6.3 → 0.6.5
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/README.md +31 -0
- package/dist/engine/publisher.d.ts +7 -0
- package/dist/engine/publisher.d.ts.map +1 -1
- package/dist/engine/publisher.js +29 -15
- package/dist/engine/publisher.js.map +1 -1
- package/dist/providers/types.d.ts +27 -0
- package/dist/providers/types.d.ts.map +1 -1
- package/dist/providers/types.js +10 -0
- package/dist/providers/types.js.map +1 -1
- package/dist/routes/content.d.ts +8 -0
- package/dist/routes/content.d.ts.map +1 -1
- package/dist/routes/content.js +196 -0
- package/dist/routes/content.js.map +1 -1
- package/dist/routes/index.d.ts +1 -1
- package/dist/routes/index.d.ts.map +1 -1
- package/dist/routes/index.js.map +1 -1
- package/dist/ui/editor/ContentForm.d.ts.map +1 -1
- package/dist/ui/editor/ContentForm.js +26 -5
- package/dist/ui/editor/ContentForm.js.map +1 -1
- package/dist/ui/editor/content-payload.d.ts +13 -0
- package/dist/ui/editor/content-payload.d.ts.map +1 -1
- package/dist/ui/editor/content-payload.js +40 -7
- package/dist/ui/editor/content-payload.js.map +1 -1
- package/package.json +54 -13
- package/src/engine/publisher.ts +60 -35
- package/src/providers/types.ts +38 -0
- package/src/routes/content.ts +261 -0
- package/src/routes/index.ts +1 -0
- package/src/ui/editor/ContentForm.tsx +32 -5
- package/src/ui/editor/content-payload.ts +53 -9
|
@@ -24,6 +24,45 @@ export interface ContentDraftFields {
|
|
|
24
24
|
metadata?: ContentMetadata
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
export interface MediaSourceReadinessPayload {
|
|
28
|
+
requestedUrl: string
|
|
29
|
+
resolvedUrl: string
|
|
30
|
+
sourceKind: string
|
|
31
|
+
durationSeconds: number | null
|
|
32
|
+
ready: boolean
|
|
33
|
+
blockers: string[]
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Apply an async host measurement only while its exact input is still current.
|
|
38
|
+
* Returning the original object signals that a newer editor change won.
|
|
39
|
+
*/
|
|
40
|
+
export function applyMediaSourceReadiness<T extends ContentDraftFields>(
|
|
41
|
+
contentType: ContentType,
|
|
42
|
+
draft: T,
|
|
43
|
+
readiness: MediaSourceReadinessPayload,
|
|
44
|
+
): T {
|
|
45
|
+
if (contentType === 'video') {
|
|
46
|
+
if (draft.videoUrl.trim() !== readiness.requestedUrl) return draft
|
|
47
|
+
return {
|
|
48
|
+
...draft,
|
|
49
|
+
videoUrl: readiness.resolvedUrl,
|
|
50
|
+
videoSourceKind: readiness.sourceKind,
|
|
51
|
+
durationSeconds: normalizeMediaDurationSeconds(readiness.durationSeconds),
|
|
52
|
+
} as T
|
|
53
|
+
}
|
|
54
|
+
if (contentType === 'podcast') {
|
|
55
|
+
if ((draft.podcastSourceUrl ?? '').trim() !== readiness.requestedUrl) return draft
|
|
56
|
+
return {
|
|
57
|
+
...draft,
|
|
58
|
+
podcastSourceUrl: readiness.resolvedUrl,
|
|
59
|
+
podcastSourceKind: readiness.sourceKind,
|
|
60
|
+
durationSeconds: normalizeMediaDurationSeconds(readiness.durationSeconds),
|
|
61
|
+
} as T
|
|
62
|
+
}
|
|
63
|
+
return draft
|
|
64
|
+
}
|
|
65
|
+
|
|
27
66
|
type MetadataSelectFieldContract = Pick<
|
|
28
67
|
ContentMetadataSelectField,
|
|
29
68
|
'key' | 'defaultValue' | 'inferenceMarkerKey'
|
|
@@ -83,10 +122,7 @@ export function canCreateContentDraft(
|
|
|
83
122
|
return draft.body.trim().length > 0
|
|
84
123
|
}
|
|
85
124
|
if (contentType === 'video') {
|
|
86
|
-
return (
|
|
87
|
-
draft.videoUrl.trim().length > 0 &&
|
|
88
|
-
normalizeMediaDurationSeconds(draft.durationSeconds) !== null
|
|
89
|
-
)
|
|
125
|
+
return draft.videoUrl.trim().length > 0
|
|
90
126
|
}
|
|
91
127
|
if (contentType === 'podcast') {
|
|
92
128
|
const hasAudio = draft.audioUrl.trim().length > 0
|
|
@@ -168,27 +204,35 @@ export function buildContentUpdatePayload(
|
|
|
168
204
|
payload.content = {
|
|
169
205
|
script: '',
|
|
170
206
|
videoId,
|
|
171
|
-
durationSeconds: normalizeMediaDurationSeconds(draft.durationSeconds),
|
|
207
|
+
durationSeconds: sourceUrl ? normalizeMediaDurationSeconds(draft.durationSeconds) : null,
|
|
172
208
|
...(thumbnailImageId ? { thumbnailImageId } : {}),
|
|
173
209
|
...(sourceUrl
|
|
174
210
|
? {
|
|
175
211
|
processingSourceUrl: sourceUrl,
|
|
176
212
|
processingSourceKind: draft.videoSourceKind || inferVideoSourceKind(sourceUrl),
|
|
177
213
|
}
|
|
178
|
-
: {
|
|
214
|
+
: {
|
|
215
|
+
processingSourceUrl: null,
|
|
216
|
+
processingSourceKind: null,
|
|
217
|
+
}),
|
|
179
218
|
}
|
|
180
219
|
} else if (contentType === 'podcast') {
|
|
181
220
|
const sourceUrl = draft.podcastSourceUrl?.trim()
|
|
221
|
+
const audioR2Key = draft.audioUrl.trim()
|
|
182
222
|
payload.content = {
|
|
183
223
|
transcript: '',
|
|
184
|
-
audioR2Key
|
|
185
|
-
durationSeconds:
|
|
224
|
+
audioR2Key,
|
|
225
|
+
durationSeconds:
|
|
226
|
+
sourceUrl || audioR2Key ? normalizeMediaDurationSeconds(draft.durationSeconds) : null,
|
|
186
227
|
...(sourceUrl
|
|
187
228
|
? {
|
|
188
229
|
processingSourceUrl: sourceUrl,
|
|
189
230
|
processingSourceKind: draft.podcastSourceKind || 'https',
|
|
190
231
|
}
|
|
191
|
-
: {
|
|
232
|
+
: {
|
|
233
|
+
processingSourceUrl: null,
|
|
234
|
+
processingSourceKind: null,
|
|
235
|
+
}),
|
|
192
236
|
}
|
|
193
237
|
}
|
|
194
238
|
|