@koda-sl/baker-cli 0.121.0-dev.36aef87f5 → 0.121.0-dev.3b02f951b
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 +35 -24
- package/dist/{chunk-MWFJ5NOP.js → chunk-7WLX7E7H.js} +303 -61
- package/dist/chunk-7WLX7E7H.js.map +1 -0
- package/dist/cli.js +1225 -1113
- package/dist/cli.js.map +1 -1
- package/dist/engine/index.d.ts +30 -0
- package/dist/engine/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-MWFJ5NOP.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -1,19 +1,25 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
+
BackendClient,
|
|
3
4
|
ELEVENLABS_MAX_MUSIC_LENGTH_MS,
|
|
4
5
|
IMAGE_GENERATE_MODELS,
|
|
5
6
|
LayerExecutionError,
|
|
6
7
|
MODEL_REGISTRY,
|
|
7
8
|
SEEDANCE_DURATIONS,
|
|
8
9
|
ValidationError,
|
|
10
|
+
collectAssetRefLikes,
|
|
9
11
|
createEngineFromEnv,
|
|
10
12
|
defaultRegistry,
|
|
11
13
|
describeFailureReason,
|
|
12
14
|
elementMentionKeywords,
|
|
13
15
|
generateCatalog,
|
|
16
|
+
isPersistedAssetRef,
|
|
17
|
+
requireCredentialsFromEnv,
|
|
14
18
|
resolveConcurrency,
|
|
19
|
+
sha256Hex,
|
|
20
|
+
ulid,
|
|
15
21
|
validateCanvasDeep
|
|
16
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-7WLX7E7H.js";
|
|
17
23
|
import {
|
|
18
24
|
csvOrJson,
|
|
19
25
|
daysAgoIso,
|
|
@@ -49,7 +55,7 @@ import {
|
|
|
49
55
|
import "./chunk-5WRI5ZAA.js";
|
|
50
56
|
|
|
51
57
|
// src/cli.ts
|
|
52
|
-
import { defineCommand as
|
|
58
|
+
import { defineCommand as defineCommand160, runMain } from "citty";
|
|
53
59
|
|
|
54
60
|
// src/commands/actions/index.ts
|
|
55
61
|
import { defineCommand as defineCommand18 } from "citty";
|
|
@@ -848,6 +854,7 @@ var LINKEDIN_LIMITS = {
|
|
|
848
854
|
choiceOptionsMax: 30,
|
|
849
855
|
choiceOptionTextMax: 100,
|
|
850
856
|
thankYouMessageMax: 300,
|
|
857
|
+
privacyPolicyTextMax: 2e3,
|
|
851
858
|
legalDisclaimerMax: 2e3,
|
|
852
859
|
consentsMax: 5,
|
|
853
860
|
// Campaign Manager caps disclosure checkboxes at 5
|
|
@@ -1442,6 +1449,7 @@ var leadFormFields = {
|
|
|
1442
1449
|
/** Form language, e.g. { country: "US", language: "en" }. Defaults to the account locale on LinkedIn. */
|
|
1443
1450
|
locale: z2.object({ country: z2.string().length(2), language: z2.string().length(2) }).optional(),
|
|
1444
1451
|
privacyPolicyUrl: httpsUrlSchema,
|
|
1452
|
+
privacyPolicyText: z2.string().max(LEAD.privacyPolicyTextMax).optional(),
|
|
1445
1453
|
questions: z2.array(leadFormQuestionSchema).min(1).max(LEAD.questionsMax),
|
|
1446
1454
|
consents: z2.array(leadFormConsentSchema).max(LEAD.consentsMax).optional(),
|
|
1447
1455
|
hiddenFields: z2.array(leadFormHiddenFieldSchema).max(LEAD.hiddenFieldsMax).optional(),
|
|
@@ -1916,241 +1924,142 @@ var imagesIngestResponseSchema = z4.object({
|
|
|
1916
1924
|
contentHash: z4.string()
|
|
1917
1925
|
});
|
|
1918
1926
|
|
|
1919
|
-
// ../api/src/tags.ts
|
|
1920
|
-
import { z as z5 } from "zod";
|
|
1921
|
-
var TAG_TYPES = [
|
|
1922
|
-
"meta",
|
|
1923
|
-
"amplitude",
|
|
1924
|
-
"googleAds",
|
|
1925
|
-
"tiktok",
|
|
1926
|
-
"vwo",
|
|
1927
|
-
"hotjar",
|
|
1928
|
-
"clarity",
|
|
1929
|
-
"pinterest",
|
|
1930
|
-
"code",
|
|
1931
|
-
"googleAnalytics",
|
|
1932
|
-
"googleTagManager",
|
|
1933
|
-
"hubspot",
|
|
1934
|
-
"linkedinInsightTag",
|
|
1935
|
-
"onetrust",
|
|
1936
|
-
"posthog",
|
|
1937
|
-
"datafast",
|
|
1938
|
-
"recaptcha",
|
|
1939
|
-
"twitterAds"
|
|
1940
|
-
];
|
|
1941
|
-
var tagTypeSchema = z5.enum(TAG_TYPES);
|
|
1942
|
-
var tagDraftOpKindSchema = z5.enum(["create", "update", "delete"]);
|
|
1943
|
-
var tagDraftOpViewSchema = z5.object({
|
|
1944
|
-
/** `tag_temp_*` for staged creates; the real tag id for update/delete ops. */
|
|
1945
|
-
ref: z5.string(),
|
|
1946
|
-
kind: tagDraftOpKindSchema,
|
|
1947
|
-
type: tagTypeSchema,
|
|
1948
|
-
/** Present on update/delete ops — the real tag this op targets. */
|
|
1949
|
-
tagId: z5.string().optional(),
|
|
1950
|
-
/** Non-secret config (create: full; update: the staged patch). Secrets are structurally absent. */
|
|
1951
|
-
config: z5.record(z5.string(), z5.string()),
|
|
1952
|
-
/** Update only — fields the op explicitly clears. */
|
|
1953
|
-
clearFields: z5.array(z5.string()).optional(),
|
|
1954
|
-
/** Names of secret fields already provided via the dashboard secure form. Never values. */
|
|
1955
|
-
secretsSet: z5.array(z5.string()),
|
|
1956
|
-
/** Names of secret fields still awaiting user input. */
|
|
1957
|
-
secretsPending: z5.array(z5.string()),
|
|
1958
|
-
summary: z5.string(),
|
|
1959
|
-
stagedAt: z5.number()
|
|
1960
|
-
});
|
|
1961
|
-
var tagsEffectiveEntrySchema = z5.object({
|
|
1962
|
-
/** Real tag id, or `tag_temp_*` for staged creates. Use as flow side-effect `tagIds` value. */
|
|
1963
|
-
ref: z5.string(),
|
|
1964
|
-
tagId: z5.string().optional(),
|
|
1965
|
-
type: tagTypeSchema,
|
|
1966
|
-
/** Value of the type's identifying field, when set. */
|
|
1967
|
-
identifier: z5.string().optional(),
|
|
1968
|
-
/** Redacted config; for staged updates, production config with the patch merged. */
|
|
1969
|
-
config: z5.record(z5.string(), z5.string()),
|
|
1970
|
-
/** Absent = live production tag with no staged changes in this chat. */
|
|
1971
|
-
staged: tagDraftOpKindSchema.optional(),
|
|
1972
|
-
secretsSet: z5.array(z5.string()),
|
|
1973
|
-
secretsPending: z5.array(z5.string())
|
|
1974
|
-
});
|
|
1975
|
-
var tagsListRequestSchema = z5.object({ chatId: z5.string() });
|
|
1976
|
-
var tagsListResponseSchema = z5.object({ tags: z5.array(tagsEffectiveEntrySchema) });
|
|
1977
|
-
var tagsDraftListRequestSchema = z5.object({ chatId: z5.string() });
|
|
1978
|
-
var tagsDraftListResponseSchema = z5.object({
|
|
1979
|
-
status: z5.enum(["active", "publishing", "applied", "discarded", "none"]),
|
|
1980
|
-
ops: z5.array(tagDraftOpViewSchema)
|
|
1981
|
-
});
|
|
1982
|
-
var tagInputRequestSchema = z5.object({
|
|
1983
|
-
// Every tag change is a tab in the approval form: create/edit show the full
|
|
1984
|
-
// body; delete shows a confirm. No tag change bypasses this approval.
|
|
1985
|
-
mode: z5.enum(["create", "edit", "delete"]),
|
|
1986
|
-
tagType: tagTypeSchema,
|
|
1987
|
-
/** Edit/delete mode — the real tag id or `tag_temp_*` ref being changed. */
|
|
1988
|
-
ref: z5.string().optional(),
|
|
1989
|
-
/** Non-secret values the agent proposes to prefill. Secret keys are stripped at every boundary. */
|
|
1990
|
-
prefilledConfig: z5.record(z5.string(), z5.string()).optional(),
|
|
1991
|
-
/** Secret field names the agent asks the user to provide. */
|
|
1992
|
-
requestedSecretFields: z5.array(z5.string()).optional(),
|
|
1993
|
-
/** Short message shown above the form explaining why the input is needed. */
|
|
1994
|
-
message: z5.string().optional()
|
|
1995
|
-
});
|
|
1996
|
-
var tagChangeToolInputSchema = z5.object({
|
|
1997
|
-
changes: z5.array(tagInputRequestSchema).min(1).max(8)
|
|
1998
|
-
});
|
|
1999
|
-
var tagInputResultSchema = z5.discriminatedUnion("status", [
|
|
2000
|
-
z5.object({
|
|
2001
|
-
status: z5.literal("submitted"),
|
|
2002
|
-
ref: z5.string(),
|
|
2003
|
-
type: tagTypeSchema,
|
|
2004
|
-
/** Identifying field name → value (non-secret), when the type has one. */
|
|
2005
|
-
identifier: z5.record(z5.string(), z5.string()).optional(),
|
|
2006
|
-
secretFieldsSet: z5.array(z5.string()),
|
|
2007
|
-
note: z5.string().optional()
|
|
2008
|
-
}),
|
|
2009
|
-
z5.object({
|
|
2010
|
-
status: z5.literal("declined"),
|
|
2011
|
-
reason: z5.string().optional()
|
|
2012
|
-
})
|
|
2013
|
-
]);
|
|
2014
|
-
var tagChangeToolResultSchema = z5.object({
|
|
2015
|
-
results: z5.array(tagInputResultSchema)
|
|
2016
|
-
});
|
|
2017
|
-
|
|
2018
1927
|
// ../api/src/testimonials.ts
|
|
2019
|
-
import { z as
|
|
2020
|
-
var testimonialSourceTypeSchema =
|
|
2021
|
-
var testimonialStatusSchema =
|
|
2022
|
-
var testimonialSentimentSchema =
|
|
2023
|
-
var testimonialDocSchema =
|
|
2024
|
-
_id:
|
|
2025
|
-
_creationTime:
|
|
2026
|
-
companyId:
|
|
2027
|
-
sourceId:
|
|
1928
|
+
import { z as z5 } from "zod";
|
|
1929
|
+
var testimonialSourceTypeSchema = z5.enum(["google", "trustpilot"]);
|
|
1930
|
+
var testimonialStatusSchema = z5.enum(["pending", "processing", "ready", "error"]);
|
|
1931
|
+
var testimonialSentimentSchema = z5.enum(["positive", "neutral", "negative"]);
|
|
1932
|
+
var testimonialDocSchema = z5.object({
|
|
1933
|
+
_id: z5.string(),
|
|
1934
|
+
_creationTime: z5.number(),
|
|
1935
|
+
companyId: z5.string(),
|
|
1936
|
+
sourceId: z5.string(),
|
|
2028
1937
|
sourceType: testimonialSourceTypeSchema,
|
|
2029
|
-
reviewText:
|
|
2030
|
-
reviewTitle:
|
|
2031
|
-
searchText:
|
|
2032
|
-
reviewerName:
|
|
2033
|
-
reviewerImageUrl:
|
|
2034
|
-
reviewerImageId:
|
|
2035
|
-
reviewerLocation:
|
|
2036
|
-
rating:
|
|
2037
|
-
reviewDate:
|
|
2038
|
-
ownerAnswer:
|
|
2039
|
-
mediaUrls:
|
|
2040
|
-
imageIds:
|
|
2041
|
-
videoIds:
|
|
2042
|
-
sourceUrl:
|
|
2043
|
-
rawData:
|
|
2044
|
-
tags:
|
|
2045
|
-
highlight:
|
|
2046
|
-
language:
|
|
2047
|
-
summary:
|
|
1938
|
+
reviewText: z5.string(),
|
|
1939
|
+
reviewTitle: z5.string().optional(),
|
|
1940
|
+
searchText: z5.string().optional(),
|
|
1941
|
+
reviewerName: z5.string().optional(),
|
|
1942
|
+
reviewerImageUrl: z5.string().optional(),
|
|
1943
|
+
reviewerImageId: z5.string().optional(),
|
|
1944
|
+
reviewerLocation: z5.string().optional(),
|
|
1945
|
+
rating: z5.number().optional(),
|
|
1946
|
+
reviewDate: z5.number().optional(),
|
|
1947
|
+
ownerAnswer: z5.string().optional(),
|
|
1948
|
+
mediaUrls: z5.array(z5.string()).optional(),
|
|
1949
|
+
imageIds: z5.array(z5.string()).optional(),
|
|
1950
|
+
videoIds: z5.array(z5.string()).optional(),
|
|
1951
|
+
sourceUrl: z5.string().optional(),
|
|
1952
|
+
rawData: z5.unknown().optional(),
|
|
1953
|
+
tags: z5.array(z5.string()),
|
|
1954
|
+
highlight: z5.string().optional(),
|
|
1955
|
+
language: z5.string().optional(),
|
|
1956
|
+
summary: z5.string().optional(),
|
|
2048
1957
|
sentiment: testimonialSentimentSchema.optional(),
|
|
2049
|
-
textEmbedding:
|
|
2050
|
-
externalId:
|
|
2051
|
-
contentHash:
|
|
1958
|
+
textEmbedding: z5.array(z5.number()).optional(),
|
|
1959
|
+
externalId: z5.string().optional(),
|
|
1960
|
+
contentHash: z5.string().optional(),
|
|
2052
1961
|
status: testimonialStatusSchema,
|
|
2053
|
-
errorMessage:
|
|
2054
|
-
createdAt:
|
|
2055
|
-
updatedAt:
|
|
1962
|
+
errorMessage: z5.string().optional(),
|
|
1963
|
+
createdAt: z5.number(),
|
|
1964
|
+
updatedAt: z5.number()
|
|
2056
1965
|
});
|
|
2057
|
-
var testimonialsListRequestSchema =
|
|
1966
|
+
var testimonialsListRequestSchema = z5.object({
|
|
2058
1967
|
source: testimonialSourceTypeSchema.optional(),
|
|
2059
|
-
rating_min:
|
|
2060
|
-
rating_max:
|
|
2061
|
-
tags:
|
|
1968
|
+
rating_min: z5.coerce.number().int().min(1).max(5).optional(),
|
|
1969
|
+
rating_max: z5.coerce.number().int().min(1).max(5).optional(),
|
|
1970
|
+
tags: z5.string().transform((s) => s.split(",").filter(Boolean)).optional(),
|
|
2062
1971
|
status: testimonialStatusSchema.optional(),
|
|
2063
1972
|
sentiment: testimonialSentimentSchema.optional(),
|
|
2064
|
-
language:
|
|
2065
|
-
limit:
|
|
2066
|
-
});
|
|
2067
|
-
var testimonialsListResponseSchema =
|
|
2068
|
-
var testimonialsGetRequestSchema =
|
|
2069
|
-
var testimonialsSearchRequestSchema =
|
|
2070
|
-
query:
|
|
2071
|
-
limit:
|
|
1973
|
+
language: z5.string().min(2).max(5).optional(),
|
|
1974
|
+
limit: z5.coerce.number().int().positive().max(200).optional()
|
|
1975
|
+
});
|
|
1976
|
+
var testimonialsListResponseSchema = z5.array(testimonialDocSchema);
|
|
1977
|
+
var testimonialsGetRequestSchema = z5.object({ id: z5.string().min(1, "Missing id parameter") });
|
|
1978
|
+
var testimonialsSearchRequestSchema = z5.object({
|
|
1979
|
+
query: z5.string().min(1),
|
|
1980
|
+
limit: z5.coerce.number().int().positive().max(100).optional(),
|
|
2072
1981
|
source: testimonialSourceTypeSchema.optional(),
|
|
2073
|
-
rating_min:
|
|
2074
|
-
rating_max:
|
|
2075
|
-
tags:
|
|
1982
|
+
rating_min: z5.coerce.number().int().min(1).max(5).optional(),
|
|
1983
|
+
rating_max: z5.coerce.number().int().min(1).max(5).optional(),
|
|
1984
|
+
tags: z5.array(z5.string()).optional(),
|
|
2076
1985
|
status: testimonialStatusSchema.optional(),
|
|
2077
1986
|
sentiment: testimonialSentimentSchema.optional(),
|
|
2078
|
-
language:
|
|
1987
|
+
language: z5.string().min(2).max(5).optional()
|
|
2079
1988
|
}).refine(
|
|
2080
1989
|
(data) => data.rating_min === void 0 || data.rating_max === void 0 || data.rating_min <= data.rating_max,
|
|
2081
1990
|
{ message: "rating_min must be less than or equal to rating_max" }
|
|
2082
1991
|
);
|
|
2083
|
-
var testimonialsSearchResponseSchema =
|
|
2084
|
-
var testimonialsOutscraperWebhookResponseSchema =
|
|
2085
|
-
ok:
|
|
2086
|
-
note:
|
|
1992
|
+
var testimonialsSearchResponseSchema = z5.array(testimonialDocSchema);
|
|
1993
|
+
var testimonialsOutscraperWebhookResponseSchema = z5.object({
|
|
1994
|
+
ok: z5.literal(true),
|
|
1995
|
+
note: z5.string().optional()
|
|
2087
1996
|
});
|
|
2088
1997
|
|
|
2089
1998
|
// ../api/src/videos.ts
|
|
2090
|
-
import { z as
|
|
2091
|
-
var videoStatusSchema =
|
|
2092
|
-
var videoTranscriptSegmentSchema =
|
|
2093
|
-
text:
|
|
2094
|
-
startSecond:
|
|
2095
|
-
endSecond:
|
|
2096
|
-
});
|
|
2097
|
-
var videoSceneSchema =
|
|
2098
|
-
title:
|
|
2099
|
-
description:
|
|
2100
|
-
startSecond:
|
|
2101
|
-
endSecond:
|
|
2102
|
-
thumbnailTime:
|
|
2103
|
-
});
|
|
2104
|
-
var videoDocSchema =
|
|
2105
|
-
_id:
|
|
2106
|
-
_creationTime:
|
|
2107
|
-
companyId:
|
|
2108
|
-
muxAssetId:
|
|
2109
|
-
muxPlaybackId:
|
|
2110
|
-
muxUploadId:
|
|
2111
|
-
name:
|
|
2112
|
-
description:
|
|
2113
|
-
tags:
|
|
2114
|
-
source:
|
|
2115
|
-
externalId:
|
|
2116
|
-
sourceId:
|
|
2117
|
-
width:
|
|
2118
|
-
height:
|
|
2119
|
-
aspectRatio:
|
|
2120
|
-
duration:
|
|
2121
|
-
transcript:
|
|
2122
|
-
transcriptSegments:
|
|
2123
|
-
scenes:
|
|
2124
|
-
descriptionEmbedding:
|
|
2125
|
-
searchText:
|
|
1999
|
+
import { z as z6 } from "zod";
|
|
2000
|
+
var videoStatusSchema = z6.enum(["uploading", "uploaded", "processing", "ready", "error"]);
|
|
2001
|
+
var videoTranscriptSegmentSchema = z6.object({
|
|
2002
|
+
text: z6.string(),
|
|
2003
|
+
startSecond: z6.number(),
|
|
2004
|
+
endSecond: z6.number()
|
|
2005
|
+
});
|
|
2006
|
+
var videoSceneSchema = z6.object({
|
|
2007
|
+
title: z6.string(),
|
|
2008
|
+
description: z6.string(),
|
|
2009
|
+
startSecond: z6.number(),
|
|
2010
|
+
endSecond: z6.number(),
|
|
2011
|
+
thumbnailTime: z6.number()
|
|
2012
|
+
});
|
|
2013
|
+
var videoDocSchema = z6.object({
|
|
2014
|
+
_id: z6.string(),
|
|
2015
|
+
_creationTime: z6.number(),
|
|
2016
|
+
companyId: z6.string(),
|
|
2017
|
+
muxAssetId: z6.string(),
|
|
2018
|
+
muxPlaybackId: z6.string(),
|
|
2019
|
+
muxUploadId: z6.string(),
|
|
2020
|
+
name: z6.string(),
|
|
2021
|
+
description: z6.string(),
|
|
2022
|
+
tags: z6.array(z6.string()),
|
|
2023
|
+
source: z6.string(),
|
|
2024
|
+
externalId: z6.string().optional(),
|
|
2025
|
+
sourceId: z6.string().optional(),
|
|
2026
|
+
width: z6.number().optional(),
|
|
2027
|
+
height: z6.number().optional(),
|
|
2028
|
+
aspectRatio: z6.number().optional(),
|
|
2029
|
+
duration: z6.number().optional(),
|
|
2030
|
+
transcript: z6.string().optional(),
|
|
2031
|
+
transcriptSegments: z6.array(videoTranscriptSegmentSchema).optional(),
|
|
2032
|
+
scenes: z6.array(videoSceneSchema).optional(),
|
|
2033
|
+
descriptionEmbedding: z6.array(z6.number()).optional(),
|
|
2034
|
+
searchText: z6.string().optional(),
|
|
2126
2035
|
status: videoStatusSchema,
|
|
2127
|
-
errorMessage:
|
|
2128
|
-
createdAt:
|
|
2129
|
-
updatedAt:
|
|
2130
|
-
thumbnailUrl:
|
|
2131
|
-
});
|
|
2132
|
-
var videosWebhookResponseSchema =
|
|
2133
|
-
var videosGetRequestSchema =
|
|
2134
|
-
var videosSearchRequestSchema =
|
|
2135
|
-
query:
|
|
2136
|
-
limit:
|
|
2137
|
-
tags:
|
|
2138
|
-
});
|
|
2139
|
-
var videoSearchResultSchema =
|
|
2140
|
-
_id:
|
|
2141
|
-
thumbnailUrl:
|
|
2142
|
-
name:
|
|
2143
|
-
description:
|
|
2144
|
-
tags:
|
|
2145
|
-
status:
|
|
2146
|
-
duration:
|
|
2147
|
-
muxPlaybackId:
|
|
2148
|
-
createdAt:
|
|
2149
|
-
});
|
|
2150
|
-
var videosSearchResponseSchema =
|
|
2151
|
-
var videosUploadResponseSchema =
|
|
2152
|
-
var videosDeleteRequestSchema =
|
|
2153
|
-
var videosDeleteResponseSchema =
|
|
2036
|
+
errorMessage: z6.string().optional(),
|
|
2037
|
+
createdAt: z6.number(),
|
|
2038
|
+
updatedAt: z6.number(),
|
|
2039
|
+
thumbnailUrl: z6.string()
|
|
2040
|
+
});
|
|
2041
|
+
var videosWebhookResponseSchema = z6.object({ ok: z6.literal(true) });
|
|
2042
|
+
var videosGetRequestSchema = z6.object({ id: z6.string().min(1, "Missing id parameter") });
|
|
2043
|
+
var videosSearchRequestSchema = z6.object({
|
|
2044
|
+
query: z6.string().min(1),
|
|
2045
|
+
limit: z6.coerce.number().int().positive().max(100).optional(),
|
|
2046
|
+
tags: z6.array(z6.string()).optional()
|
|
2047
|
+
});
|
|
2048
|
+
var videoSearchResultSchema = z6.object({
|
|
2049
|
+
_id: z6.string(),
|
|
2050
|
+
thumbnailUrl: z6.string(),
|
|
2051
|
+
name: z6.string(),
|
|
2052
|
+
description: z6.string(),
|
|
2053
|
+
tags: z6.array(z6.string()),
|
|
2054
|
+
status: z6.string(),
|
|
2055
|
+
duration: z6.number().optional(),
|
|
2056
|
+
muxPlaybackId: z6.string(),
|
|
2057
|
+
createdAt: z6.number()
|
|
2058
|
+
});
|
|
2059
|
+
var videosSearchResponseSchema = z6.array(videoSearchResultSchema);
|
|
2060
|
+
var videosUploadResponseSchema = z6.object({ uploadUrl: z6.string(), videoId: z6.string() });
|
|
2061
|
+
var videosDeleteRequestSchema = z6.object({ id: z6.string().min(1, "Missing video ID") });
|
|
2062
|
+
var videosDeleteResponseSchema = z6.object({ ok: z6.literal(true) });
|
|
2154
2063
|
|
|
2155
2064
|
// src/commands/actions/complete.ts
|
|
2156
2065
|
import { defineCommand as defineCommand2 } from "citty";
|
|
@@ -3963,37 +3872,37 @@ var GEO_TARGET_CONSTANT_REGEX = /^geoTargetConstants\/\d+$/;
|
|
|
3963
3872
|
var LANGUAGE_CONSTANT_REGEX = /^languageConstants\/\d+$/;
|
|
3964
3873
|
|
|
3965
3874
|
// ../api/src/ads-google/ops.ts
|
|
3966
|
-
import { z as
|
|
3967
|
-
var tempRefSchema2 =
|
|
3968
|
-
var refSchema =
|
|
3969
|
-
|
|
3970
|
-
|
|
3875
|
+
import { z as z7 } from "zod";
|
|
3876
|
+
var tempRefSchema2 = z7.string().regex(TEMP_REF_REGEX2, "expected a g_temp_* reference");
|
|
3877
|
+
var refSchema = z7.union([
|
|
3878
|
+
z7.string().regex(RESOURCE_NAME_REGEX, "expected a customers/\u2026/\u2026/\u2026 resource name"),
|
|
3879
|
+
z7.string().regex(NUMERIC_ID_REGEX2, "expected a numeric id"),
|
|
3971
3880
|
tempRefSchema2
|
|
3972
3881
|
]);
|
|
3973
3882
|
var targetRefSchema = refSchema;
|
|
3974
|
-
var microsSchema =
|
|
3975
|
-
var httpsUrlSchema2 =
|
|
3976
|
-
var customerIdSchema =
|
|
3977
|
-
var stageableStatusSchema2 =
|
|
3978
|
-
var matchTypeSchema =
|
|
3979
|
-
var keywordTextSchema =
|
|
3980
|
-
var budgetCreateSchema =
|
|
3981
|
-
name:
|
|
3883
|
+
var microsSchema = z7.number().int().positive("expected a positive micros amount");
|
|
3884
|
+
var httpsUrlSchema2 = z7.string().url().refine((u) => u.startsWith("https://"), "final URLs must be https");
|
|
3885
|
+
var customerIdSchema = z7.string().regex(NUMERIC_ID_REGEX2, "customerId must be the bare numeric customer id");
|
|
3886
|
+
var stageableStatusSchema2 = z7.enum(STAGEABLE_CREATE_STATUSES2);
|
|
3887
|
+
var matchTypeSchema = z7.enum(KEYWORD_MATCH_TYPES);
|
|
3888
|
+
var keywordTextSchema = z7.string().min(1).max(GOOGLE_ADS_LIMITS.keyword.textMax).refine((t) => t.trim().split(/\s+/).length <= GOOGLE_ADS_LIMITS.keyword.wordsMax, "keyword exceeds 10 words");
|
|
3889
|
+
var budgetCreateSchema = z7.object({
|
|
3890
|
+
name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.budget.nameMax),
|
|
3982
3891
|
amountMicros: microsSchema,
|
|
3983
|
-
deliveryMethod:
|
|
3984
|
-
explicitlyShared:
|
|
3892
|
+
deliveryMethod: z7.enum(BUDGET_DELIVERY_METHODS).default("STANDARD"),
|
|
3893
|
+
explicitlyShared: z7.boolean().default(false)
|
|
3985
3894
|
});
|
|
3986
|
-
var budgetUpdateSchema =
|
|
3987
|
-
name:
|
|
3895
|
+
var budgetUpdateSchema = z7.object({
|
|
3896
|
+
name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.budget.nameMax).optional(),
|
|
3988
3897
|
amountMicros: microsSchema.optional(),
|
|
3989
|
-
deliveryMethod:
|
|
3898
|
+
deliveryMethod: z7.enum(BUDGET_DELIVERY_METHODS).optional()
|
|
3990
3899
|
}).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
|
|
3991
|
-
var biddingConfigSchema =
|
|
3992
|
-
type:
|
|
3900
|
+
var biddingConfigSchema = z7.object({
|
|
3901
|
+
type: z7.enum(BIDDING_STRATEGY_TYPES),
|
|
3993
3902
|
targetCpaMicros: microsSchema.optional(),
|
|
3994
|
-
targetRoas:
|
|
3903
|
+
targetRoas: z7.number().positive().optional(),
|
|
3995
3904
|
cpcBidCeilingMicros: microsSchema.optional(),
|
|
3996
|
-
enhancedCpcEnabled:
|
|
3905
|
+
enhancedCpcEnabled: z7.boolean().optional()
|
|
3997
3906
|
}).superRefine((p, ctx) => {
|
|
3998
3907
|
if (p.type === "TARGET_CPA" && p.targetCpaMicros === void 0) {
|
|
3999
3908
|
ctx.addIssue({ code: "custom", path: ["targetCpaMicros"], message: "TARGET_CPA needs targetCpaMicros" });
|
|
@@ -4002,17 +3911,17 @@ var biddingConfigSchema = z8.object({
|
|
|
4002
3911
|
ctx.addIssue({ code: "custom", path: ["targetRoas"], message: "TARGET_ROAS needs targetRoas" });
|
|
4003
3912
|
}
|
|
4004
3913
|
});
|
|
4005
|
-
var networkSettingsSchema =
|
|
4006
|
-
targetGoogleSearch:
|
|
4007
|
-
targetSearchNetwork:
|
|
4008
|
-
targetContentNetwork:
|
|
4009
|
-
targetPartnerSearchNetwork:
|
|
3914
|
+
var networkSettingsSchema = z7.object({
|
|
3915
|
+
targetGoogleSearch: z7.boolean().optional(),
|
|
3916
|
+
targetSearchNetwork: z7.boolean().optional(),
|
|
3917
|
+
targetContentNetwork: z7.boolean().optional(),
|
|
3918
|
+
targetPartnerSearchNetwork: z7.boolean().optional()
|
|
4010
3919
|
});
|
|
4011
|
-
var dateSchema =
|
|
4012
|
-
var campaignCreateSchema2 =
|
|
4013
|
-
name:
|
|
4014
|
-
channelType:
|
|
4015
|
-
channelSubType:
|
|
3920
|
+
var dateSchema = z7.string().regex(/^\d{4}-\d{2}-\d{2}$/, "expected a YYYY-MM-DD date");
|
|
3921
|
+
var campaignCreateSchema2 = z7.object({
|
|
3922
|
+
name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.campaign.nameMax),
|
|
3923
|
+
channelType: z7.enum(ADVERTISING_CHANNEL_TYPES),
|
|
3924
|
+
channelSubType: z7.enum(ADVERTISING_CHANNEL_SUB_TYPES).optional(),
|
|
4016
3925
|
budget: refSchema,
|
|
4017
3926
|
/** Inline standard bidding, or a portfolio strategy ref via biddingStrategy. */
|
|
4018
3927
|
bidding: biddingConfigSchema.optional(),
|
|
@@ -4021,7 +3930,7 @@ var campaignCreateSchema2 = z8.object({
|
|
|
4021
3930
|
startDate: dateSchema.optional(),
|
|
4022
3931
|
endDate: dateSchema.optional(),
|
|
4023
3932
|
/** Advisory Google Ads UI objective — drives warnings, not sent to the API. */
|
|
4024
|
-
objective:
|
|
3933
|
+
objective: z7.enum(CAMPAIGN_OBJECTIVES).optional(),
|
|
4025
3934
|
status: stageableStatusSchema2.default("PAUSED")
|
|
4026
3935
|
}).superRefine((p, ctx) => {
|
|
4027
3936
|
if (!p.bidding && !p.biddingStrategy) {
|
|
@@ -4045,129 +3954,129 @@ var campaignCreateSchema2 = z8.object({
|
|
|
4045
3954
|
ctx.addIssue({ code: "custom", path: ["endDate"], message: "endDate must be after startDate" });
|
|
4046
3955
|
}
|
|
4047
3956
|
});
|
|
4048
|
-
var campaignUpdateSchema2 =
|
|
4049
|
-
name:
|
|
3957
|
+
var campaignUpdateSchema2 = z7.object({
|
|
3958
|
+
name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.campaign.nameMax).optional(),
|
|
4050
3959
|
budget: refSchema.optional(),
|
|
4051
3960
|
bidding: biddingConfigSchema.optional(),
|
|
4052
3961
|
networkSettings: networkSettingsSchema.optional(),
|
|
4053
3962
|
startDate: dateSchema.optional(),
|
|
4054
3963
|
endDate: dateSchema.optional(),
|
|
4055
|
-
status:
|
|
3964
|
+
status: z7.enum(["ENABLED", "PAUSED", "REMOVED"]).optional()
|
|
4056
3965
|
}).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
|
|
4057
|
-
var adGroupCreateSchema =
|
|
4058
|
-
name:
|
|
3966
|
+
var adGroupCreateSchema = z7.object({
|
|
3967
|
+
name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.adGroup.nameMax),
|
|
4059
3968
|
campaign: refSchema,
|
|
4060
|
-
type:
|
|
3969
|
+
type: z7.enum(AD_GROUP_TYPES).default("SEARCH_STANDARD"),
|
|
4061
3970
|
cpcBidMicros: microsSchema.optional(),
|
|
4062
3971
|
status: stageableStatusSchema2.default("PAUSED")
|
|
4063
3972
|
});
|
|
4064
|
-
var adGroupUpdateSchema =
|
|
4065
|
-
name:
|
|
3973
|
+
var adGroupUpdateSchema = z7.object({
|
|
3974
|
+
name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.adGroup.nameMax).optional(),
|
|
4066
3975
|
cpcBidMicros: microsSchema.optional(),
|
|
4067
|
-
status:
|
|
3976
|
+
status: z7.enum(["ENABLED", "PAUSED", "REMOVED"]).optional()
|
|
4068
3977
|
}).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
|
|
4069
|
-
var keywordAddSchema =
|
|
3978
|
+
var keywordAddSchema = z7.object({
|
|
4070
3979
|
adGroup: refSchema,
|
|
4071
3980
|
text: keywordTextSchema,
|
|
4072
3981
|
matchType: matchTypeSchema,
|
|
4073
3982
|
cpcBidMicros: microsSchema.optional(),
|
|
4074
|
-
finalUrls:
|
|
3983
|
+
finalUrls: z7.array(httpsUrlSchema2).optional(),
|
|
4075
3984
|
status: stageableStatusSchema2.default("ENABLED")
|
|
4076
3985
|
});
|
|
4077
|
-
var keywordUpdateSchema =
|
|
3986
|
+
var keywordUpdateSchema = z7.object({
|
|
4078
3987
|
cpcBidMicros: microsSchema.optional(),
|
|
4079
|
-
finalUrls:
|
|
4080
|
-
status:
|
|
3988
|
+
finalUrls: z7.array(httpsUrlSchema2).optional(),
|
|
3989
|
+
status: z7.enum(["ENABLED", "PAUSED", "REMOVED"]).optional()
|
|
4081
3990
|
}).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
|
|
4082
|
-
var negativeKeywordAddSchema =
|
|
4083
|
-
level:
|
|
3991
|
+
var negativeKeywordAddSchema = z7.object({
|
|
3992
|
+
level: z7.enum(["adGroup", "campaign"]),
|
|
4084
3993
|
parent: refSchema,
|
|
4085
3994
|
text: keywordTextSchema,
|
|
4086
3995
|
matchType: matchTypeSchema
|
|
4087
3996
|
});
|
|
4088
|
-
var sharedSetCreateSchema =
|
|
4089
|
-
name:
|
|
4090
|
-
type:
|
|
3997
|
+
var sharedSetCreateSchema = z7.object({
|
|
3998
|
+
name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.sharedSet.nameMax),
|
|
3999
|
+
type: z7.enum(SHARED_SET_TYPES).default("NEGATIVE_KEYWORDS")
|
|
4091
4000
|
});
|
|
4092
|
-
var sharedSetMemberAddSchema =
|
|
4001
|
+
var sharedSetMemberAddSchema = z7.object({
|
|
4093
4002
|
sharedSet: refSchema,
|
|
4094
4003
|
text: keywordTextSchema,
|
|
4095
4004
|
matchType: matchTypeSchema
|
|
4096
4005
|
});
|
|
4097
|
-
var campaignSharedSetAttachSchema =
|
|
4006
|
+
var campaignSharedSetAttachSchema = z7.object({
|
|
4098
4007
|
campaign: refSchema,
|
|
4099
4008
|
sharedSet: refSchema
|
|
4100
4009
|
});
|
|
4101
|
-
var adTextAssetSchema =
|
|
4102
|
-
text:
|
|
4103
|
-
pinnedField:
|
|
4010
|
+
var adTextAssetSchema = z7.object({
|
|
4011
|
+
text: z7.string().min(1),
|
|
4012
|
+
pinnedField: z7.enum(PINNED_FIELDS).optional()
|
|
4104
4013
|
});
|
|
4105
|
-
var responsiveSearchAdSchema =
|
|
4106
|
-
format:
|
|
4107
|
-
headlines:
|
|
4014
|
+
var responsiveSearchAdSchema = z7.object({
|
|
4015
|
+
format: z7.literal("responsiveSearch"),
|
|
4016
|
+
headlines: z7.array(
|
|
4108
4017
|
adTextAssetSchema.refine(
|
|
4109
4018
|
(a) => a.text.length <= GOOGLE_ADS_LIMITS.responsiveSearchAd.headlineTextMax,
|
|
4110
4019
|
"headline exceeds 30 chars"
|
|
4111
4020
|
)
|
|
4112
4021
|
).min(GOOGLE_ADS_LIMITS.responsiveSearchAd.headlinesMin).max(GOOGLE_ADS_LIMITS.responsiveSearchAd.headlinesMax),
|
|
4113
|
-
descriptions:
|
|
4022
|
+
descriptions: z7.array(
|
|
4114
4023
|
adTextAssetSchema.refine(
|
|
4115
4024
|
(a) => a.text.length <= GOOGLE_ADS_LIMITS.responsiveSearchAd.descriptionTextMax,
|
|
4116
4025
|
"description exceeds 90 chars"
|
|
4117
4026
|
)
|
|
4118
4027
|
).min(GOOGLE_ADS_LIMITS.responsiveSearchAd.descriptionsMin).max(GOOGLE_ADS_LIMITS.responsiveSearchAd.descriptionsMax),
|
|
4119
|
-
path1:
|
|
4120
|
-
path2:
|
|
4121
|
-
finalUrls:
|
|
4122
|
-
});
|
|
4123
|
-
var responsiveDisplayAdSchema =
|
|
4124
|
-
format:
|
|
4125
|
-
headlines:
|
|
4126
|
-
longHeadline:
|
|
4127
|
-
descriptions:
|
|
4128
|
-
businessName:
|
|
4028
|
+
path1: z7.string().max(GOOGLE_ADS_LIMITS.responsiveSearchAd.pathMax).optional(),
|
|
4029
|
+
path2: z7.string().max(GOOGLE_ADS_LIMITS.responsiveSearchAd.pathMax).optional(),
|
|
4030
|
+
finalUrls: z7.array(httpsUrlSchema2).min(1)
|
|
4031
|
+
});
|
|
4032
|
+
var responsiveDisplayAdSchema = z7.object({
|
|
4033
|
+
format: z7.literal("responsiveDisplay"),
|
|
4034
|
+
headlines: z7.array(z7.object({ text: z7.string().min(1).max(GOOGLE_ADS_LIMITS.responsiveDisplayAd.headlineTextMax) })).min(1).max(5),
|
|
4035
|
+
longHeadline: z7.object({ text: z7.string().min(1).max(GOOGLE_ADS_LIMITS.responsiveDisplayAd.longHeadlineTextMax) }),
|
|
4036
|
+
descriptions: z7.array(z7.object({ text: z7.string().min(1).max(GOOGLE_ADS_LIMITS.responsiveDisplayAd.descriptionTextMax) })).min(1).max(5),
|
|
4037
|
+
businessName: z7.string().min(1).max(GOOGLE_ADS_LIMITS.responsiveDisplayAd.businessNameMax),
|
|
4129
4038
|
// A Responsive Display Ad's images are fields on the ad's own content (never campaign-level
|
|
4130
4039
|
// asset links). Google requires ≥1 landscape marketing image (1.91:1) AND ≥1 square marketing
|
|
4131
4040
|
// image (1:1) to serve; the logo images are optional.
|
|
4132
|
-
marketingImageAssets:
|
|
4133
|
-
squareMarketingImageAssets:
|
|
4134
|
-
logoImageAssets:
|
|
4135
|
-
finalUrls:
|
|
4136
|
-
});
|
|
4137
|
-
var callAdSchema =
|
|
4138
|
-
format:
|
|
4139
|
-
countryCode:
|
|
4140
|
-
phoneNumber:
|
|
4141
|
-
headline1:
|
|
4142
|
-
headline2:
|
|
4143
|
-
description1:
|
|
4144
|
-
description2:
|
|
4145
|
-
businessName:
|
|
4146
|
-
finalUrls:
|
|
4147
|
-
});
|
|
4148
|
-
var appAdSchema =
|
|
4149
|
-
format:
|
|
4150
|
-
headlines:
|
|
4151
|
-
descriptions:
|
|
4152
|
-
});
|
|
4153
|
-
var videoAdSchema =
|
|
4154
|
-
format:
|
|
4041
|
+
marketingImageAssets: z7.array(refSchema).optional(),
|
|
4042
|
+
squareMarketingImageAssets: z7.array(refSchema).optional(),
|
|
4043
|
+
logoImageAssets: z7.array(refSchema).optional(),
|
|
4044
|
+
finalUrls: z7.array(httpsUrlSchema2).min(1)
|
|
4045
|
+
});
|
|
4046
|
+
var callAdSchema = z7.object({
|
|
4047
|
+
format: z7.literal("call"),
|
|
4048
|
+
countryCode: z7.string().length(2),
|
|
4049
|
+
phoneNumber: z7.string().min(3),
|
|
4050
|
+
headline1: z7.string().min(1).max(30),
|
|
4051
|
+
headline2: z7.string().min(1).max(30),
|
|
4052
|
+
description1: z7.string().min(1).max(90),
|
|
4053
|
+
description2: z7.string().min(1).max(90),
|
|
4054
|
+
businessName: z7.string().min(1).max(25),
|
|
4055
|
+
finalUrls: z7.array(httpsUrlSchema2).min(1)
|
|
4056
|
+
});
|
|
4057
|
+
var appAdSchema = z7.object({
|
|
4058
|
+
format: z7.literal("app"),
|
|
4059
|
+
headlines: z7.array(z7.object({ text: z7.string().min(1).max(30) })).min(1),
|
|
4060
|
+
descriptions: z7.array(z7.object({ text: z7.string().min(1).max(90) })).min(1)
|
|
4061
|
+
});
|
|
4062
|
+
var videoAdSchema = z7.object({
|
|
4063
|
+
format: z7.literal("video"),
|
|
4155
4064
|
// A raw YouTube id is not a publishable Google Ads reference — the video must be staged as
|
|
4156
4065
|
// its own `google.asset.create` (type: youtubeVideo) first, then referenced here by asset ref.
|
|
4157
|
-
videoAssets:
|
|
4158
|
-
finalUrls:
|
|
4159
|
-
});
|
|
4160
|
-
var demandGenAdSchema =
|
|
4161
|
-
format:
|
|
4162
|
-
headlines:
|
|
4163
|
-
descriptions:
|
|
4164
|
-
businessName:
|
|
4165
|
-
finalUrls:
|
|
4166
|
-
imageAssets:
|
|
4167
|
-
squareImageAssets:
|
|
4168
|
-
logoImageAssets:
|
|
4169
|
-
});
|
|
4170
|
-
var adContentSchema =
|
|
4066
|
+
videoAssets: z7.array(refSchema).min(1),
|
|
4067
|
+
finalUrls: z7.array(httpsUrlSchema2).min(1)
|
|
4068
|
+
});
|
|
4069
|
+
var demandGenAdSchema = z7.object({
|
|
4070
|
+
format: z7.literal("demandGen"),
|
|
4071
|
+
headlines: z7.array(z7.object({ text: z7.string().min(1).max(40) })).min(1).max(5),
|
|
4072
|
+
descriptions: z7.array(z7.object({ text: z7.string().min(1).max(90) })).min(1).max(5),
|
|
4073
|
+
businessName: z7.string().min(1).max(25),
|
|
4074
|
+
finalUrls: z7.array(httpsUrlSchema2).min(1),
|
|
4075
|
+
imageAssets: z7.array(refSchema).optional(),
|
|
4076
|
+
squareImageAssets: z7.array(refSchema).optional(),
|
|
4077
|
+
logoImageAssets: z7.array(refSchema).optional()
|
|
4078
|
+
});
|
|
4079
|
+
var adContentSchema = z7.discriminatedUnion("format", [
|
|
4171
4080
|
responsiveSearchAdSchema,
|
|
4172
4081
|
responsiveDisplayAdSchema,
|
|
4173
4082
|
callAdSchema,
|
|
@@ -4175,45 +4084,45 @@ var adContentSchema = z8.discriminatedUnion("format", [
|
|
|
4175
4084
|
videoAdSchema,
|
|
4176
4085
|
demandGenAdSchema
|
|
4177
4086
|
]);
|
|
4178
|
-
var adCreateSchema =
|
|
4087
|
+
var adCreateSchema = z7.object({
|
|
4179
4088
|
adGroup: refSchema,
|
|
4180
4089
|
status: stageableStatusSchema2.default("PAUSED"),
|
|
4181
4090
|
content: adContentSchema
|
|
4182
4091
|
});
|
|
4183
|
-
var adUpdateSchema =
|
|
4184
|
-
status:
|
|
4092
|
+
var adUpdateSchema = z7.object({
|
|
4093
|
+
status: z7.enum(["ENABLED", "PAUSED", "REMOVED"]).optional(),
|
|
4185
4094
|
/** Whole-content replacement for RSA-like formats; re-validated against adContentSchema. */
|
|
4186
|
-
content:
|
|
4095
|
+
content: z7.record(z7.string(), z7.unknown()).optional()
|
|
4187
4096
|
}).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
|
|
4188
|
-
var textAssetSchema =
|
|
4189
|
-
var imageAssetSchema =
|
|
4190
|
-
type:
|
|
4191
|
-
imageId:
|
|
4192
|
-
name:
|
|
4193
|
-
});
|
|
4194
|
-
var youtubeVideoAssetSchema =
|
|
4195
|
-
type:
|
|
4196
|
-
youtubeVideoId:
|
|
4197
|
-
name:
|
|
4198
|
-
});
|
|
4199
|
-
var sitelinkAssetSchema =
|
|
4200
|
-
type:
|
|
4201
|
-
linkText:
|
|
4202
|
-
description1:
|
|
4203
|
-
description2:
|
|
4204
|
-
finalUrls:
|
|
4205
|
-
});
|
|
4206
|
-
var calloutAssetSchema =
|
|
4207
|
-
type:
|
|
4208
|
-
calloutText:
|
|
4209
|
-
});
|
|
4210
|
-
var structuredSnippetAssetSchema =
|
|
4211
|
-
type:
|
|
4212
|
-
header:
|
|
4213
|
-
values:
|
|
4214
|
-
});
|
|
4215
|
-
var callToActionAssetSchema =
|
|
4216
|
-
var assetCreateSchema =
|
|
4097
|
+
var textAssetSchema = z7.object({ type: z7.literal("text"), text: z7.string().min(1) });
|
|
4098
|
+
var imageAssetSchema = z7.object({
|
|
4099
|
+
type: z7.literal("image"),
|
|
4100
|
+
imageId: z7.string().min(1),
|
|
4101
|
+
name: z7.string().optional()
|
|
4102
|
+
});
|
|
4103
|
+
var youtubeVideoAssetSchema = z7.object({
|
|
4104
|
+
type: z7.literal("youtubeVideo"),
|
|
4105
|
+
youtubeVideoId: z7.string().min(1),
|
|
4106
|
+
name: z7.string().optional()
|
|
4107
|
+
});
|
|
4108
|
+
var sitelinkAssetSchema = z7.object({
|
|
4109
|
+
type: z7.literal("sitelink"),
|
|
4110
|
+
linkText: z7.string().min(1).max(GOOGLE_ADS_LIMITS.asset.sitelinkLinkTextMax),
|
|
4111
|
+
description1: z7.string().max(GOOGLE_ADS_LIMITS.asset.sitelinkDescriptionMax).optional(),
|
|
4112
|
+
description2: z7.string().max(GOOGLE_ADS_LIMITS.asset.sitelinkDescriptionMax).optional(),
|
|
4113
|
+
finalUrls: z7.array(httpsUrlSchema2).min(1)
|
|
4114
|
+
});
|
|
4115
|
+
var calloutAssetSchema = z7.object({
|
|
4116
|
+
type: z7.literal("callout"),
|
|
4117
|
+
calloutText: z7.string().min(1).max(GOOGLE_ADS_LIMITS.asset.calloutTextMax)
|
|
4118
|
+
});
|
|
4119
|
+
var structuredSnippetAssetSchema = z7.object({
|
|
4120
|
+
type: z7.literal("structuredSnippet"),
|
|
4121
|
+
header: z7.string().min(1).max(GOOGLE_ADS_LIMITS.asset.structuredSnippetHeaderMax),
|
|
4122
|
+
values: z7.array(z7.string().min(1)).min(GOOGLE_ADS_LIMITS.asset.structuredSnippetValuesMin).max(GOOGLE_ADS_LIMITS.asset.structuredSnippetValuesMax)
|
|
4123
|
+
});
|
|
4124
|
+
var callToActionAssetSchema = z7.object({ type: z7.literal("callToAction"), callToAction: z7.string().min(1) });
|
|
4125
|
+
var assetCreateSchema = z7.discriminatedUnion("type", [
|
|
4217
4126
|
textAssetSchema,
|
|
4218
4127
|
imageAssetSchema,
|
|
4219
4128
|
youtubeVideoAssetSchema,
|
|
@@ -4222,136 +4131,136 @@ var assetCreateSchema = z8.discriminatedUnion("type", [
|
|
|
4222
4131
|
structuredSnippetAssetSchema,
|
|
4223
4132
|
callToActionAssetSchema
|
|
4224
4133
|
]);
|
|
4225
|
-
var assetUpdateSchema =
|
|
4226
|
-
name:
|
|
4227
|
-
linkText:
|
|
4228
|
-
description1:
|
|
4229
|
-
description2:
|
|
4230
|
-
finalUrls:
|
|
4231
|
-
calloutText:
|
|
4232
|
-
header:
|
|
4233
|
-
values:
|
|
4234
|
-
callToAction:
|
|
4235
|
-
text:
|
|
4134
|
+
var assetUpdateSchema = z7.object({
|
|
4135
|
+
name: z7.string().min(1).optional(),
|
|
4136
|
+
linkText: z7.string().min(1).max(GOOGLE_ADS_LIMITS.asset.sitelinkLinkTextMax).optional(),
|
|
4137
|
+
description1: z7.string().max(GOOGLE_ADS_LIMITS.asset.sitelinkDescriptionMax).optional(),
|
|
4138
|
+
description2: z7.string().max(GOOGLE_ADS_LIMITS.asset.sitelinkDescriptionMax).optional(),
|
|
4139
|
+
finalUrls: z7.array(httpsUrlSchema2).min(1).optional(),
|
|
4140
|
+
calloutText: z7.string().min(1).max(GOOGLE_ADS_LIMITS.asset.calloutTextMax).optional(),
|
|
4141
|
+
header: z7.string().min(1).max(GOOGLE_ADS_LIMITS.asset.structuredSnippetHeaderMax).optional(),
|
|
4142
|
+
values: z7.array(z7.string().min(1)).min(GOOGLE_ADS_LIMITS.asset.structuredSnippetValuesMin).max(GOOGLE_ADS_LIMITS.asset.structuredSnippetValuesMax).optional(),
|
|
4143
|
+
callToAction: z7.string().min(1).optional(),
|
|
4144
|
+
text: z7.string().min(1).optional()
|
|
4236
4145
|
}).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
|
|
4237
|
-
var assetLinkAttachSchema =
|
|
4238
|
-
level:
|
|
4146
|
+
var assetLinkAttachSchema = z7.object({
|
|
4147
|
+
level: z7.enum(["campaign", "adGroup", "customer"]),
|
|
4239
4148
|
parent: refSchema.optional(),
|
|
4240
4149
|
asset: refSchema,
|
|
4241
|
-
fieldType:
|
|
4150
|
+
fieldType: z7.enum(ASSET_FIELD_TYPES)
|
|
4242
4151
|
}).superRefine((value, ctx) => {
|
|
4243
4152
|
if (value.level !== "customer" && !value.parent) {
|
|
4244
4153
|
ctx.addIssue({
|
|
4245
|
-
code:
|
|
4154
|
+
code: z7.ZodIssueCode.custom,
|
|
4246
4155
|
path: ["parent"],
|
|
4247
4156
|
message: `parent is required for a ${value.level}-level asset link (--parent-ref)`
|
|
4248
4157
|
});
|
|
4249
4158
|
}
|
|
4250
4159
|
});
|
|
4251
|
-
var assetGroupCreateSchema =
|
|
4160
|
+
var assetGroupCreateSchema = z7.object({
|
|
4252
4161
|
campaign: refSchema,
|
|
4253
|
-
name:
|
|
4254
|
-
finalUrls:
|
|
4255
|
-
headlines:
|
|
4256
|
-
longHeadlines:
|
|
4257
|
-
descriptions:
|
|
4258
|
-
businessName:
|
|
4259
|
-
imageAssets:
|
|
4260
|
-
squareImageAssets:
|
|
4261
|
-
logoAssets:
|
|
4262
|
-
status:
|
|
4263
|
-
});
|
|
4264
|
-
var assetGroupUpdateSchema =
|
|
4265
|
-
name:
|
|
4266
|
-
finalUrls:
|
|
4267
|
-
status:
|
|
4162
|
+
name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.assetGroup.nameMax),
|
|
4163
|
+
finalUrls: z7.array(httpsUrlSchema2).min(1),
|
|
4164
|
+
headlines: z7.array(z7.object({ text: z7.string().min(1).max(GOOGLE_ADS_LIMITS.assetGroup.headlineTextMax) })).min(GOOGLE_ADS_LIMITS.assetGroup.headlinesMin).max(GOOGLE_ADS_LIMITS.assetGroup.headlinesMax),
|
|
4165
|
+
longHeadlines: z7.array(z7.object({ text: z7.string().min(1).max(GOOGLE_ADS_LIMITS.assetGroup.longHeadlineTextMax) })).min(GOOGLE_ADS_LIMITS.assetGroup.longHeadlinesMin).max(GOOGLE_ADS_LIMITS.assetGroup.longHeadlinesMax),
|
|
4166
|
+
descriptions: z7.array(z7.object({ text: z7.string().min(1).max(GOOGLE_ADS_LIMITS.assetGroup.descriptionTextMax) })).min(GOOGLE_ADS_LIMITS.assetGroup.descriptionsMin).max(GOOGLE_ADS_LIMITS.assetGroup.descriptionsMax),
|
|
4167
|
+
businessName: z7.string().min(1).max(GOOGLE_ADS_LIMITS.assetGroup.businessNameMax),
|
|
4168
|
+
imageAssets: z7.array(refSchema).optional(),
|
|
4169
|
+
squareImageAssets: z7.array(refSchema).optional(),
|
|
4170
|
+
logoAssets: z7.array(refSchema).optional(),
|
|
4171
|
+
status: z7.enum(["ENABLED", "PAUSED"]).default("PAUSED")
|
|
4172
|
+
});
|
|
4173
|
+
var assetGroupUpdateSchema = z7.object({
|
|
4174
|
+
name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.assetGroup.nameMax).optional(),
|
|
4175
|
+
finalUrls: z7.array(httpsUrlSchema2).min(1).optional(),
|
|
4176
|
+
status: z7.enum(["ENABLED", "PAUSED", "REMOVED"]).optional()
|
|
4268
4177
|
}).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
|
|
4269
|
-
var audienceCreateSchema2 =
|
|
4270
|
-
name:
|
|
4271
|
-
type:
|
|
4272
|
-
description:
|
|
4178
|
+
var audienceCreateSchema2 = z7.object({
|
|
4179
|
+
name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.audience.nameMax),
|
|
4180
|
+
type: z7.enum(USER_LIST_TYPES).default("BASIC"),
|
|
4181
|
+
description: z7.string().optional(),
|
|
4273
4182
|
/** Customer-match members (crm-based) — file-first for large lists. */
|
|
4274
|
-
members:
|
|
4275
|
-
sourceFileRef:
|
|
4183
|
+
members: z7.array(z7.record(z7.string(), z7.string())).optional(),
|
|
4184
|
+
sourceFileRef: z7.string().optional()
|
|
4276
4185
|
});
|
|
4277
|
-
var audienceCriterionAttachSchema =
|
|
4278
|
-
level:
|
|
4186
|
+
var audienceCriterionAttachSchema = z7.object({
|
|
4187
|
+
level: z7.enum(["campaign", "adGroup"]),
|
|
4279
4188
|
parent: refSchema,
|
|
4280
4189
|
userList: refSchema,
|
|
4281
|
-
negative:
|
|
4190
|
+
negative: z7.boolean().default(false)
|
|
4282
4191
|
});
|
|
4283
|
-
var conversionActionCreateSchema =
|
|
4284
|
-
name:
|
|
4285
|
-
type:
|
|
4286
|
-
category:
|
|
4287
|
-
countingType:
|
|
4192
|
+
var conversionActionCreateSchema = z7.object({
|
|
4193
|
+
name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.conversionAction.nameMax),
|
|
4194
|
+
type: z7.enum(CONVERSION_ACTION_TYPES).default("WEBPAGE"),
|
|
4195
|
+
category: z7.enum(CONVERSION_ACTION_CATEGORIES).default("DEFAULT"),
|
|
4196
|
+
countingType: z7.enum(CONVERSION_COUNTING_TYPES).default("ONE_PER_CLICK"),
|
|
4288
4197
|
defaultValueMicros: microsSchema.optional(),
|
|
4289
|
-
defaultCurrencyCode:
|
|
4290
|
-
clickThroughLookbackWindowDays:
|
|
4291
|
-
viewThroughLookbackWindowDays:
|
|
4292
|
-
status:
|
|
4293
|
-
});
|
|
4294
|
-
var conversionActionUpdateSchema =
|
|
4295
|
-
name:
|
|
4296
|
-
category:
|
|
4297
|
-
countingType:
|
|
4198
|
+
defaultCurrencyCode: z7.string().length(3).optional(),
|
|
4199
|
+
clickThroughLookbackWindowDays: z7.number().int().positive().optional(),
|
|
4200
|
+
viewThroughLookbackWindowDays: z7.number().int().positive().optional(),
|
|
4201
|
+
status: z7.enum(["ENABLED", "PAUSED"]).default("ENABLED")
|
|
4202
|
+
});
|
|
4203
|
+
var conversionActionUpdateSchema = z7.object({
|
|
4204
|
+
name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.conversionAction.nameMax).optional(),
|
|
4205
|
+
category: z7.enum(CONVERSION_ACTION_CATEGORIES).optional(),
|
|
4206
|
+
countingType: z7.enum(CONVERSION_COUNTING_TYPES).optional(),
|
|
4298
4207
|
defaultValueMicros: microsSchema.optional(),
|
|
4299
|
-
defaultCurrencyCode:
|
|
4300
|
-
clickThroughLookbackWindowDays:
|
|
4301
|
-
viewThroughLookbackWindowDays:
|
|
4302
|
-
status:
|
|
4208
|
+
defaultCurrencyCode: z7.string().length(3).optional(),
|
|
4209
|
+
clickThroughLookbackWindowDays: z7.number().int().positive().optional(),
|
|
4210
|
+
viewThroughLookbackWindowDays: z7.number().int().positive().optional(),
|
|
4211
|
+
status: z7.enum(["ENABLED", "REMOVED", "HIDDEN"]).optional()
|
|
4303
4212
|
}).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
|
|
4304
|
-
var biddingStrategyCreateSchema =
|
|
4305
|
-
name:
|
|
4213
|
+
var biddingStrategyCreateSchema = z7.object({
|
|
4214
|
+
name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.biddingStrategy.nameMax),
|
|
4306
4215
|
config: biddingConfigSchema
|
|
4307
4216
|
}).superRefine((p, ctx) => {
|
|
4308
4217
|
if (p.config.type === "MANUAL_CPC") {
|
|
4309
4218
|
ctx.addIssue({ code: "custom", path: ["config", "type"], message: "portfolio strategies cannot be Manual CPC" });
|
|
4310
4219
|
}
|
|
4311
4220
|
});
|
|
4312
|
-
var biddingStrategyUpdateSchema =
|
|
4313
|
-
name:
|
|
4221
|
+
var biddingStrategyUpdateSchema = z7.object({
|
|
4222
|
+
name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.biddingStrategy.nameMax).optional(),
|
|
4314
4223
|
config: biddingConfigSchema.optional()
|
|
4315
4224
|
}).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
|
|
4316
|
-
var labelCreateSchema =
|
|
4317
|
-
name:
|
|
4318
|
-
backgroundColor:
|
|
4319
|
-
description:
|
|
4225
|
+
var labelCreateSchema = z7.object({
|
|
4226
|
+
name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.label.nameMax),
|
|
4227
|
+
backgroundColor: z7.string().regex(/^#[0-9A-Fa-f]{6}$/).optional(),
|
|
4228
|
+
description: z7.string().optional()
|
|
4320
4229
|
});
|
|
4321
|
-
var labelAttachSchema =
|
|
4322
|
-
level:
|
|
4230
|
+
var labelAttachSchema = z7.object({
|
|
4231
|
+
level: z7.enum(["campaign", "adGroup", "ad"]),
|
|
4323
4232
|
parent: refSchema,
|
|
4324
4233
|
label: refSchema
|
|
4325
4234
|
});
|
|
4326
|
-
var locationCriterionSchema =
|
|
4327
|
-
criterionType:
|
|
4328
|
-
geoTargetConstant:
|
|
4329
|
-
});
|
|
4330
|
-
var languageCriterionSchema =
|
|
4331
|
-
criterionType:
|
|
4332
|
-
languageConstant:
|
|
4333
|
-
});
|
|
4334
|
-
var adScheduleCriterionSchema =
|
|
4335
|
-
criterionType:
|
|
4336
|
-
dayOfWeek:
|
|
4337
|
-
startHour:
|
|
4338
|
-
startMinute:
|
|
4339
|
-
endHour:
|
|
4340
|
-
endMinute:
|
|
4341
|
-
});
|
|
4342
|
-
var deviceCriterionSchema =
|
|
4343
|
-
criterionType:
|
|
4344
|
-
device:
|
|
4235
|
+
var locationCriterionSchema = z7.object({
|
|
4236
|
+
criterionType: z7.literal("location"),
|
|
4237
|
+
geoTargetConstant: z7.union([z7.string().regex(GEO_TARGET_CONSTANT_REGEX), z7.string().regex(NUMERIC_ID_REGEX2)])
|
|
4238
|
+
});
|
|
4239
|
+
var languageCriterionSchema = z7.object({
|
|
4240
|
+
criterionType: z7.literal("language"),
|
|
4241
|
+
languageConstant: z7.union([z7.string().regex(LANGUAGE_CONSTANT_REGEX), z7.string().regex(NUMERIC_ID_REGEX2)])
|
|
4242
|
+
});
|
|
4243
|
+
var adScheduleCriterionSchema = z7.object({
|
|
4244
|
+
criterionType: z7.literal("adSchedule"),
|
|
4245
|
+
dayOfWeek: z7.enum(DAYS_OF_WEEK),
|
|
4246
|
+
startHour: z7.number().int().min(0).max(23),
|
|
4247
|
+
startMinute: z7.enum(["ZERO", "FIFTEEN", "THIRTY", "FORTY_FIVE"]).default("ZERO"),
|
|
4248
|
+
endHour: z7.number().int().min(0).max(24),
|
|
4249
|
+
endMinute: z7.enum(["ZERO", "FIFTEEN", "THIRTY", "FORTY_FIVE"]).default("ZERO")
|
|
4250
|
+
});
|
|
4251
|
+
var deviceCriterionSchema = z7.object({
|
|
4252
|
+
criterionType: z7.literal("device"),
|
|
4253
|
+
device: z7.enum(DEVICE_TYPES),
|
|
4345
4254
|
// Google's `CampaignCriterion.bid_modifier`: "The modifier must be in the range 0.1 - 10.0. Use 0
|
|
4346
4255
|
// to opt out of a Device type." So 0 (exclude the device) and 0.1–10.0 are valid; the (0, 0.1) gap is not.
|
|
4347
|
-
bidModifier:
|
|
4256
|
+
bidModifier: z7.number().min(0).max(10).optional().refine((v) => v === void 0 || v === 0 || v >= 0.1, {
|
|
4348
4257
|
message: "bid modifier must be 0 (exclude the device) or between 0.1 and 10.0"
|
|
4349
4258
|
})
|
|
4350
4259
|
});
|
|
4351
|
-
var campaignCriterionAddSchema =
|
|
4260
|
+
var campaignCriterionAddSchema = z7.object({
|
|
4352
4261
|
campaign: refSchema,
|
|
4353
|
-
negative:
|
|
4354
|
-
criterion:
|
|
4262
|
+
negative: z7.boolean().default(false),
|
|
4263
|
+
criterion: z7.discriminatedUnion("criterionType", [
|
|
4355
4264
|
locationCriterionSchema,
|
|
4356
4265
|
languageCriterionSchema,
|
|
4357
4266
|
adScheduleCriterionSchema,
|
|
@@ -4361,7 +4270,7 @@ var campaignCriterionAddSchema = z8.object({
|
|
|
4361
4270
|
const c = val.criterion;
|
|
4362
4271
|
if (c.criterionType === "adSchedule" && c.endHour === 24 && c.endMinute !== "ZERO") {
|
|
4363
4272
|
ctx.addIssue({
|
|
4364
|
-
code:
|
|
4273
|
+
code: z7.ZodIssueCode.custom,
|
|
4365
4274
|
message: "endHour 24 (midnight) cannot have a non-zero endMinute",
|
|
4366
4275
|
path: ["criterion", "endMinute"]
|
|
4367
4276
|
});
|
|
@@ -4413,17 +4322,17 @@ var GOOGLE_DRAFT_OP_KINDS = [
|
|
|
4413
4322
|
"google.campaignCriterion.add",
|
|
4414
4323
|
"google.campaignCriterion.remove"
|
|
4415
4324
|
];
|
|
4416
|
-
var googleDraftOpKindSchema =
|
|
4325
|
+
var googleDraftOpKindSchema = z7.enum(GOOGLE_DRAFT_OP_KINDS);
|
|
4417
4326
|
function createOp2(kind, payload) {
|
|
4418
|
-
return
|
|
4327
|
+
return z7.object({ kind: z7.literal(kind), customerId: customerIdSchema, payload });
|
|
4419
4328
|
}
|
|
4420
4329
|
function updateOp2(kind, payload) {
|
|
4421
|
-
return
|
|
4330
|
+
return z7.object({ kind: z7.literal(kind), customerId: customerIdSchema, target: targetRefSchema, payload });
|
|
4422
4331
|
}
|
|
4423
4332
|
function targetOp(kind) {
|
|
4424
|
-
return
|
|
4333
|
+
return z7.object({ kind: z7.literal(kind), customerId: customerIdSchema, target: targetRefSchema });
|
|
4425
4334
|
}
|
|
4426
|
-
var googleDraftOpInputSchema =
|
|
4335
|
+
var googleDraftOpInputSchema = z7.discriminatedUnion("kind", [
|
|
4427
4336
|
createOp2("google.budget.create", budgetCreateSchema),
|
|
4428
4337
|
updateOp2("google.budget.update", budgetUpdateSchema),
|
|
4429
4338
|
createOp2("google.campaign.create", campaignCreateSchema2),
|
|
@@ -4471,132 +4380,132 @@ var googleDraftOpInputSchema = z8.discriminatedUnion("kind", [
|
|
|
4471
4380
|
]);
|
|
4472
4381
|
|
|
4473
4382
|
// ../api/src/ads-google/wire.ts
|
|
4474
|
-
import { z as
|
|
4475
|
-
var googleWriteModeSchema =
|
|
4476
|
-
var googleDraftOpResultSchema =
|
|
4477
|
-
status:
|
|
4478
|
-
resourceName:
|
|
4479
|
-
error:
|
|
4480
|
-
skippedBecause:
|
|
4481
|
-
executedAt:
|
|
4482
|
-
});
|
|
4483
|
-
var googleDraftStageRequestSchema =
|
|
4484
|
-
chatId:
|
|
4383
|
+
import { z as z8 } from "zod";
|
|
4384
|
+
var googleWriteModeSchema = z8.enum(["live", "simulated"]);
|
|
4385
|
+
var googleDraftOpResultSchema = z8.object({
|
|
4386
|
+
status: z8.enum(["applied", "simulated", "failed", "skipped"]),
|
|
4387
|
+
resourceName: z8.string().optional(),
|
|
4388
|
+
error: z8.string().optional(),
|
|
4389
|
+
skippedBecause: z8.string().optional(),
|
|
4390
|
+
executedAt: z8.number().optional()
|
|
4391
|
+
});
|
|
4392
|
+
var googleDraftStageRequestSchema = z8.object({
|
|
4393
|
+
chatId: z8.string(),
|
|
4485
4394
|
op: googleDraftOpInputSchema
|
|
4486
4395
|
});
|
|
4487
|
-
var googleDraftStageResponseSchema =
|
|
4488
|
-
staged:
|
|
4489
|
-
ref:
|
|
4396
|
+
var googleDraftStageResponseSchema = z8.object({
|
|
4397
|
+
staged: z8.literal(true),
|
|
4398
|
+
ref: z8.string(),
|
|
4490
4399
|
kind: googleDraftOpKindSchema,
|
|
4491
4400
|
mode: googleWriteModeSchema,
|
|
4492
|
-
dependsOn:
|
|
4493
|
-
summary:
|
|
4494
|
-
warnings:
|
|
4401
|
+
dependsOn: z8.array(z8.string()),
|
|
4402
|
+
summary: z8.string(),
|
|
4403
|
+
warnings: z8.array(z8.string()),
|
|
4495
4404
|
/** True when the op amended an already-staged op in place instead of appending a new one. */
|
|
4496
|
-
amended:
|
|
4405
|
+
amended: z8.boolean().optional()
|
|
4497
4406
|
});
|
|
4498
|
-
var googleDraftAmendRequestSchema =
|
|
4499
|
-
chatId:
|
|
4500
|
-
ref:
|
|
4501
|
-
patch:
|
|
4407
|
+
var googleDraftAmendRequestSchema = z8.object({
|
|
4408
|
+
chatId: z8.string(),
|
|
4409
|
+
ref: z8.string(),
|
|
4410
|
+
patch: z8.record(z8.string(), z8.unknown())
|
|
4502
4411
|
});
|
|
4503
|
-
var googleDraftShowRequestSchema =
|
|
4504
|
-
chatId:
|
|
4505
|
-
ref:
|
|
4412
|
+
var googleDraftShowRequestSchema = z8.object({
|
|
4413
|
+
chatId: z8.string(),
|
|
4414
|
+
ref: z8.string()
|
|
4506
4415
|
});
|
|
4507
4416
|
var GOOGLE_DRAFT_BATCH_MAX = 500;
|
|
4508
|
-
var googleDraftStageBatchRequestSchema =
|
|
4509
|
-
chatId:
|
|
4510
|
-
ops:
|
|
4417
|
+
var googleDraftStageBatchRequestSchema = z8.object({
|
|
4418
|
+
chatId: z8.string(),
|
|
4419
|
+
ops: z8.array(googleDraftOpInputSchema).min(1).max(GOOGLE_DRAFT_BATCH_MAX)
|
|
4511
4420
|
});
|
|
4512
|
-
var googleDraftStageBatchResponseSchema =
|
|
4513
|
-
staged:
|
|
4421
|
+
var googleDraftStageBatchResponseSchema = z8.object({
|
|
4422
|
+
staged: z8.literal(true),
|
|
4514
4423
|
mode: googleWriteModeSchema,
|
|
4515
|
-
count:
|
|
4516
|
-
ops:
|
|
4517
|
-
|
|
4518
|
-
ref:
|
|
4424
|
+
count: z8.number(),
|
|
4425
|
+
ops: z8.array(
|
|
4426
|
+
z8.object({
|
|
4427
|
+
ref: z8.string(),
|
|
4519
4428
|
kind: googleDraftOpKindSchema,
|
|
4520
|
-
dependsOn:
|
|
4521
|
-
summary:
|
|
4522
|
-
warnings:
|
|
4429
|
+
dependsOn: z8.array(z8.string()),
|
|
4430
|
+
summary: z8.string(),
|
|
4431
|
+
warnings: z8.array(z8.string())
|
|
4523
4432
|
})
|
|
4524
4433
|
)
|
|
4525
4434
|
});
|
|
4526
|
-
var googleDraftOpViewSchema =
|
|
4527
|
-
ref:
|
|
4435
|
+
var googleDraftOpViewSchema = z8.object({
|
|
4436
|
+
ref: z8.string(),
|
|
4528
4437
|
kind: googleDraftOpKindSchema,
|
|
4529
|
-
customerId:
|
|
4530
|
-
target:
|
|
4531
|
-
dependsOn:
|
|
4532
|
-
summary:
|
|
4533
|
-
stagedAt:
|
|
4438
|
+
customerId: z8.string(),
|
|
4439
|
+
target: z8.string().optional(),
|
|
4440
|
+
dependsOn: z8.array(z8.string()),
|
|
4441
|
+
summary: z8.string(),
|
|
4442
|
+
stagedAt: z8.number(),
|
|
4534
4443
|
result: googleDraftOpResultSchema.optional()
|
|
4535
4444
|
});
|
|
4536
|
-
var googleDraftShowResponseSchema =
|
|
4445
|
+
var googleDraftShowResponseSchema = z8.object({
|
|
4537
4446
|
op: googleDraftOpViewSchema.extend({
|
|
4538
|
-
payload:
|
|
4539
|
-
warnings:
|
|
4540
|
-
annotations:
|
|
4447
|
+
payload: z8.unknown().optional(),
|
|
4448
|
+
warnings: z8.array(z8.string()).optional(),
|
|
4449
|
+
annotations: z8.unknown().optional()
|
|
4541
4450
|
})
|
|
4542
4451
|
});
|
|
4543
|
-
var googleDraftListRequestSchema =
|
|
4544
|
-
chatId:
|
|
4452
|
+
var googleDraftListRequestSchema = z8.object({
|
|
4453
|
+
chatId: z8.string()
|
|
4545
4454
|
});
|
|
4546
|
-
var googleDraftAdvisorySchema =
|
|
4547
|
-
scope:
|
|
4548
|
-
message:
|
|
4455
|
+
var googleDraftAdvisorySchema = z8.object({
|
|
4456
|
+
scope: z8.enum(["campaign", "adGroup"]),
|
|
4457
|
+
message: z8.string()
|
|
4549
4458
|
});
|
|
4550
|
-
var googleDraftStatusCollectionSchema =
|
|
4551
|
-
label:
|
|
4552
|
-
added:
|
|
4553
|
-
removed:
|
|
4554
|
-
existing:
|
|
4459
|
+
var googleDraftStatusCollectionSchema = z8.object({
|
|
4460
|
+
label: z8.string(),
|
|
4461
|
+
added: z8.number(),
|
|
4462
|
+
removed: z8.number(),
|
|
4463
|
+
existing: z8.number()
|
|
4555
4464
|
});
|
|
4556
|
-
var googleDraftChangeOperationSchema =
|
|
4557
|
-
var googleDraftStatusNodeSchema =
|
|
4558
|
-
() =>
|
|
4559
|
-
entity:
|
|
4560
|
-
name:
|
|
4465
|
+
var googleDraftChangeOperationSchema = z8.enum(["create", "update", "pause", "resume", "remove"]);
|
|
4466
|
+
var googleDraftStatusNodeSchema = z8.lazy(
|
|
4467
|
+
() => z8.object({
|
|
4468
|
+
entity: z8.string(),
|
|
4469
|
+
name: z8.string(),
|
|
4561
4470
|
operation: googleDraftChangeOperationSchema.optional(),
|
|
4562
|
-
existing:
|
|
4563
|
-
collections:
|
|
4564
|
-
children:
|
|
4565
|
-
warnings:
|
|
4471
|
+
existing: z8.boolean(),
|
|
4472
|
+
collections: z8.array(googleDraftStatusCollectionSchema),
|
|
4473
|
+
children: z8.array(googleDraftStatusNodeSchema),
|
|
4474
|
+
warnings: z8.array(z8.string()).optional()
|
|
4566
4475
|
})
|
|
4567
4476
|
);
|
|
4568
|
-
var googleDraftListResponseSchema =
|
|
4569
|
-
status:
|
|
4477
|
+
var googleDraftListResponseSchema = z8.object({
|
|
4478
|
+
status: z8.enum(["active", "publishing", "applied", "discarded", "none"]),
|
|
4570
4479
|
mode: googleWriteModeSchema,
|
|
4571
|
-
count:
|
|
4572
|
-
ops:
|
|
4480
|
+
count: z8.number(),
|
|
4481
|
+
ops: z8.array(googleDraftOpViewSchema),
|
|
4573
4482
|
/** Grouped campaign ▸ ad group ▸ ad tree for the readable CLI status view. */
|
|
4574
|
-
tree:
|
|
4483
|
+
tree: z8.array(googleDraftStatusNodeSchema).optional(),
|
|
4575
4484
|
/** Non-blocking completeness advisories for the whole draft. */
|
|
4576
|
-
advisories:
|
|
4485
|
+
advisories: z8.array(googleDraftAdvisorySchema).optional()
|
|
4577
4486
|
});
|
|
4578
|
-
var googleDraftRemoveRequestSchema =
|
|
4579
|
-
chatId:
|
|
4580
|
-
ref:
|
|
4487
|
+
var googleDraftRemoveRequestSchema = z8.object({
|
|
4488
|
+
chatId: z8.string(),
|
|
4489
|
+
ref: z8.string()
|
|
4581
4490
|
});
|
|
4582
|
-
var googleDraftRemoveResponseSchema =
|
|
4491
|
+
var googleDraftRemoveResponseSchema = z8.object({
|
|
4583
4492
|
/** The requested ref plus any dependents removed by cascade. */
|
|
4584
|
-
removed:
|
|
4493
|
+
removed: z8.array(z8.string())
|
|
4585
4494
|
});
|
|
4586
|
-
var googleDraftClearRequestSchema =
|
|
4587
|
-
chatId:
|
|
4495
|
+
var googleDraftClearRequestSchema = z8.object({
|
|
4496
|
+
chatId: z8.string()
|
|
4588
4497
|
});
|
|
4589
|
-
var googleDraftClearResponseSchema =
|
|
4590
|
-
cleared:
|
|
4498
|
+
var googleDraftClearResponseSchema = z8.object({
|
|
4499
|
+
cleared: z8.number()
|
|
4591
4500
|
});
|
|
4592
|
-
var googleFieldErrorSchema =
|
|
4593
|
-
path:
|
|
4594
|
-
message:
|
|
4501
|
+
var googleFieldErrorSchema = z8.object({
|
|
4502
|
+
path: z8.string(),
|
|
4503
|
+
message: z8.string()
|
|
4595
4504
|
});
|
|
4596
|
-
var googleDraftErrorResponseSchema =
|
|
4597
|
-
code:
|
|
4598
|
-
error:
|
|
4599
|
-
fields:
|
|
4505
|
+
var googleDraftErrorResponseSchema = z8.object({
|
|
4506
|
+
code: z8.string(),
|
|
4507
|
+
error: z8.string(),
|
|
4508
|
+
fields: z8.array(googleFieldErrorSchema).optional()
|
|
4600
4509
|
});
|
|
4601
4510
|
|
|
4602
4511
|
// src/commands/ads/google/draft-status.ts
|
|
@@ -4761,11 +4670,11 @@ function rawTextEntries(value) {
|
|
|
4761
4670
|
const values = Array.isArray(value) ? value : typeof value === "string" ? [value] : [];
|
|
4762
4671
|
return values.filter((v) => typeof v === "string").flatMap((v) => v.split(",")).map((v) => v.trim()).filter(Boolean);
|
|
4763
4672
|
}
|
|
4764
|
-
function rawFileEntries(
|
|
4765
|
-
if (typeof
|
|
4673
|
+
function rawFileEntries(path14) {
|
|
4674
|
+
if (typeof path14 !== "string" || path14.length === 0) {
|
|
4766
4675
|
return [];
|
|
4767
4676
|
}
|
|
4768
|
-
return readFileSync2(
|
|
4677
|
+
return readFileSync2(path14, "utf8").split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#"));
|
|
4769
4678
|
}
|
|
4770
4679
|
function keywordEntries(args) {
|
|
4771
4680
|
const defaultMatch = typeof args["match-type"] === "string" ? args["match-type"].toUpperCase() : void 0;
|
|
@@ -4788,19 +4697,19 @@ function keywordEntries(args) {
|
|
|
4788
4697
|
}
|
|
4789
4698
|
return entries;
|
|
4790
4699
|
}
|
|
4791
|
-
function loadJsonFileArg(
|
|
4792
|
-
if (typeof
|
|
4700
|
+
function loadJsonFileArg(path14) {
|
|
4701
|
+
if (typeof path14 !== "string" || path14.length === 0) {
|
|
4793
4702
|
return {};
|
|
4794
4703
|
}
|
|
4795
4704
|
try {
|
|
4796
|
-
const parsed = JSON.parse(readFileSync2(
|
|
4705
|
+
const parsed = JSON.parse(readFileSync2(path14, "utf8"));
|
|
4797
4706
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
4798
|
-
failWriteValidation(`${
|
|
4707
|
+
failWriteValidation(`${path14} must contain a JSON object`);
|
|
4799
4708
|
}
|
|
4800
4709
|
return parsed;
|
|
4801
4710
|
} catch (err) {
|
|
4802
4711
|
if (err instanceof SyntaxError) {
|
|
4803
|
-
failWriteValidation(`${
|
|
4712
|
+
failWriteValidation(`${path14} is not valid JSON: ${err.message}`);
|
|
4804
4713
|
}
|
|
4805
4714
|
throw err;
|
|
4806
4715
|
}
|
|
@@ -4911,10 +4820,10 @@ async function stageUpdate(kind, customerId, target, payload) {
|
|
|
4911
4820
|
async function stageTarget(kind, customerId, target) {
|
|
4912
4821
|
await stageGoogleOp({ kind, customerId, target });
|
|
4913
4822
|
}
|
|
4914
|
-
async function draftAction(
|
|
4823
|
+
async function draftAction(path14, body) {
|
|
4915
4824
|
try {
|
|
4916
4825
|
const chatId = requireChatId();
|
|
4917
|
-
const response = await apiPost(
|
|
4826
|
+
const response = await apiPost(path14, { chatId, ...body });
|
|
4918
4827
|
writeJsonEnvelope(response);
|
|
4919
4828
|
} catch (err) {
|
|
4920
4829
|
handleGoogleError(err);
|
|
@@ -8669,19 +8578,19 @@ function failWriteValidation2(message) {
|
|
|
8669
8578
|
writeJsonEnvelope({ ok: false, error: { code: "VALIDATION_ERROR", message } });
|
|
8670
8579
|
process.exit(1);
|
|
8671
8580
|
}
|
|
8672
|
-
function loadJsonFileArg2(
|
|
8673
|
-
if (typeof
|
|
8581
|
+
function loadJsonFileArg2(path14) {
|
|
8582
|
+
if (typeof path14 !== "string" || path14.length === 0) {
|
|
8674
8583
|
return {};
|
|
8675
8584
|
}
|
|
8676
8585
|
try {
|
|
8677
|
-
const parsed = JSON.parse(readFileSync6(
|
|
8586
|
+
const parsed = JSON.parse(readFileSync6(path14, "utf8"));
|
|
8678
8587
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
8679
|
-
failWriteValidation2(`${
|
|
8588
|
+
failWriteValidation2(`${path14} must contain a JSON object`);
|
|
8680
8589
|
}
|
|
8681
8590
|
return parsed;
|
|
8682
8591
|
} catch (err) {
|
|
8683
8592
|
if (err instanceof SyntaxError) {
|
|
8684
|
-
failWriteValidation2(`${
|
|
8593
|
+
failWriteValidation2(`${path14} is not valid JSON: ${err.message}`);
|
|
8685
8594
|
}
|
|
8686
8595
|
throw err;
|
|
8687
8596
|
}
|
|
@@ -8766,15 +8675,15 @@ function parseLocaleFlag(value) {
|
|
|
8766
8675
|
}
|
|
8767
8676
|
return { language: match[1], country: match[2].toUpperCase() };
|
|
8768
8677
|
}
|
|
8769
|
-
function loadTargetingFileArg(
|
|
8770
|
-
if (typeof
|
|
8678
|
+
function loadTargetingFileArg(path14) {
|
|
8679
|
+
if (typeof path14 !== "string" || path14.length === 0) {
|
|
8771
8680
|
return void 0;
|
|
8772
8681
|
}
|
|
8773
|
-
const parsed = loadJsonFileArg2(
|
|
8682
|
+
const parsed = loadJsonFileArg2(path14);
|
|
8774
8683
|
const criteria = parsed.targetingCriteria ?? parsed;
|
|
8775
8684
|
if (!criteria.include) {
|
|
8776
8685
|
failWriteValidation2(
|
|
8777
|
-
`${
|
|
8686
|
+
`${path14} must contain targeting criteria with an "include" block (see baker schema ads.linkedin.campaigns.create)`
|
|
8778
8687
|
);
|
|
8779
8688
|
}
|
|
8780
8689
|
return criteria;
|
|
@@ -8809,14 +8718,14 @@ function parseCsvLine(line) {
|
|
|
8809
8718
|
cells.push(current);
|
|
8810
8719
|
return cells.map((cell) => cell.trim());
|
|
8811
8720
|
}
|
|
8812
|
-
function parseListFileArg(
|
|
8813
|
-
if (typeof
|
|
8721
|
+
function parseListFileArg(path14, maxRows) {
|
|
8722
|
+
if (typeof path14 !== "string" || path14.length === 0) {
|
|
8814
8723
|
return void 0;
|
|
8815
8724
|
}
|
|
8816
|
-
const raw = readFileSync6(
|
|
8725
|
+
const raw = readFileSync6(path14, "utf8");
|
|
8817
8726
|
const lines = raw.split(/\r?\n/).filter((line) => line.trim().length > 0);
|
|
8818
8727
|
if (lines.length < 2) {
|
|
8819
|
-
failWriteValidation2(`${
|
|
8728
|
+
failWriteValidation2(`${path14} needs a header row and at least one data row`);
|
|
8820
8729
|
}
|
|
8821
8730
|
const columns = parseCsvLine(lines[0]).map((column) => column.trim());
|
|
8822
8731
|
const rows = [];
|
|
@@ -8835,7 +8744,7 @@ function parseListFileArg(path12, maxRows) {
|
|
|
8835
8744
|
}
|
|
8836
8745
|
}
|
|
8837
8746
|
if (rows.length > maxRows) {
|
|
8838
|
-
failWriteValidation2(`${
|
|
8747
|
+
failWriteValidation2(`${path14} has ${rows.length} rows \u2014 the inline limit is ${maxRows}. Split the list.`);
|
|
8839
8748
|
}
|
|
8840
8749
|
return { columns, rows };
|
|
8841
8750
|
}
|
|
@@ -9480,7 +9389,7 @@ var leadFormsCreateCommand = defineCommand38({
|
|
|
9480
9389
|
Required: name, headline (\u226460), privacyPolicyUrl, questions[] (\u226412; playbook: \u22644 for completion).
|
|
9481
9390
|
Each question is a predefined profile field ({ name, predefinedField: "EMAIL" }) or a custom question ({ name, questionType: "MULTIPLE_CHOICE", options: [...] }; \u22643 custom).
|
|
9482
9391
|
Best-practice fields the preview will nudge for if missing: 1-3 qualifying questions, consents[] (disclosure checkboxes), thankYou.message + thankYou.landingUrl|appointmentUrl.
|
|
9483
|
-
Also supported: locale, formImageId|formImageUrn, hiddenFields[], legalDisclaimer, thankYou.cta. Example: baker ads linkedin lead-forms create --file form.json`
|
|
9392
|
+
Also supported: locale, formImageId|formImageUrn, privacyPolicyText, hiddenFields[], legalDisclaimer, thankYou.cta. Example: baker ads linkedin lead-forms create --file form.json`
|
|
9484
9393
|
},
|
|
9485
9394
|
args: {
|
|
9486
9395
|
...accountArgs,
|
|
@@ -10904,72 +10813,72 @@ var NUMERIC_ID_REGEX3 = /^\d+$/;
|
|
|
10904
10813
|
var IMAGE_HASH_REGEX = /^[A-Fa-f0-9]{16,}$/;
|
|
10905
10814
|
|
|
10906
10815
|
// ../api/src/ads-meta/ops.ts
|
|
10907
|
-
import { z as
|
|
10908
|
-
var tempRefSchema3 =
|
|
10909
|
-
var parentRefSchema2 =
|
|
10910
|
-
var moneySchema2 =
|
|
10911
|
-
amount:
|
|
10912
|
-
currencyCode:
|
|
10913
|
-
});
|
|
10914
|
-
var httpsUrlSchema3 =
|
|
10915
|
-
var bakerMediaIdSchema2 =
|
|
10916
|
-
var stageableStatusSchema3 =
|
|
10917
|
-
var updateStatusSchema =
|
|
10816
|
+
import { z as z9 } from "zod";
|
|
10817
|
+
var tempRefSchema3 = z9.string().regex(TEMP_REF_REGEX3, "expected a meta_temp_* reference");
|
|
10818
|
+
var parentRefSchema2 = z9.union([z9.string().regex(NUMERIC_ID_REGEX3, "expected a numeric id"), tempRefSchema3]);
|
|
10819
|
+
var moneySchema2 = z9.object({
|
|
10820
|
+
amount: z9.string().regex(/^\d+(\.\d{1,2})?$/, "expected a decimal amount like 50 or 50.00").refine((val) => Number(val) > 0, "amount must be greater than zero"),
|
|
10821
|
+
currencyCode: z9.string().length(3).optional()
|
|
10822
|
+
});
|
|
10823
|
+
var httpsUrlSchema3 = z9.string().url().refine((u) => u.startsWith("https://"), "destination URLs must be https");
|
|
10824
|
+
var bakerMediaIdSchema2 = z9.string().min(1);
|
|
10825
|
+
var stageableStatusSchema3 = z9.enum(STAGEABLE_CREATE_STATUSES3);
|
|
10826
|
+
var updateStatusSchema = z9.enum(UPDATE_STATUSES);
|
|
10918
10827
|
function currencyMinimums2(currencyCode) {
|
|
10919
10828
|
return CURRENCY_MINIMUMS2[currencyCode] ?? DEFAULT_CURRENCY_MINIMUM2;
|
|
10920
10829
|
}
|
|
10921
|
-
function validateDailyBudgetFloor(money, ctx,
|
|
10830
|
+
function validateDailyBudgetFloor(money, ctx, path14) {
|
|
10922
10831
|
if (money?.currencyCode) {
|
|
10923
10832
|
const min = currencyMinimums2(money.currencyCode).dailyBudgetMin;
|
|
10924
10833
|
if (Number(money.amount) < min) {
|
|
10925
|
-
ctx.addIssue({ code: "custom", path:
|
|
10834
|
+
ctx.addIssue({ code: "custom", path: path14, message: `below the ${min} ${money.currencyCode} daily minimum` });
|
|
10926
10835
|
}
|
|
10927
10836
|
}
|
|
10928
10837
|
}
|
|
10929
|
-
var geoLocationsSchema =
|
|
10930
|
-
countries:
|
|
10931
|
-
regions:
|
|
10932
|
-
cities:
|
|
10933
|
-
zips:
|
|
10934
|
-
location_types:
|
|
10935
|
-
}).catchall(
|
|
10936
|
-
var idNameSchema =
|
|
10937
|
-
var metaTargetingSchema =
|
|
10838
|
+
var geoLocationsSchema = z9.object({
|
|
10839
|
+
countries: z9.array(z9.string().length(2)).optional(),
|
|
10840
|
+
regions: z9.array(z9.object({ key: z9.string() })).optional(),
|
|
10841
|
+
cities: z9.array(z9.object({ key: z9.string(), radius: z9.number().optional(), distance_unit: z9.string().optional() })).optional(),
|
|
10842
|
+
zips: z9.array(z9.object({ key: z9.string() })).optional(),
|
|
10843
|
+
location_types: z9.array(z9.string()).optional()
|
|
10844
|
+
}).catchall(z9.unknown());
|
|
10845
|
+
var idNameSchema = z9.object({ id: z9.string(), name: z9.string().optional() });
|
|
10846
|
+
var metaTargetingSchema = z9.object({
|
|
10938
10847
|
geo_locations: geoLocationsSchema.optional(),
|
|
10939
10848
|
excluded_geo_locations: geoLocationsSchema.optional(),
|
|
10940
|
-
age_min:
|
|
10941
|
-
age_max:
|
|
10942
|
-
genders:
|
|
10943
|
-
locales:
|
|
10944
|
-
interests:
|
|
10945
|
-
behaviors:
|
|
10946
|
-
custom_audiences:
|
|
10947
|
-
excluded_custom_audiences:
|
|
10948
|
-
flexible_spec:
|
|
10949
|
-
exclusions:
|
|
10950
|
-
publisher_platforms:
|
|
10951
|
-
facebook_positions:
|
|
10952
|
-
instagram_positions:
|
|
10953
|
-
audience_network_positions:
|
|
10954
|
-
messenger_positions:
|
|
10955
|
-
device_platforms:
|
|
10956
|
-
targeting_automation:
|
|
10957
|
-
}).catchall(
|
|
10958
|
-
var specialAdCategoriesSchema =
|
|
10959
|
-
var campaignCreateSchema3 =
|
|
10960
|
-
name:
|
|
10961
|
-
objective:
|
|
10849
|
+
age_min: z9.number().int().min(13).max(65).optional(),
|
|
10850
|
+
age_max: z9.number().int().min(13).max(65).optional(),
|
|
10851
|
+
genders: z9.array(z9.union([z9.literal(1), z9.literal(2)])).optional(),
|
|
10852
|
+
locales: z9.array(z9.number().int()).optional(),
|
|
10853
|
+
interests: z9.array(idNameSchema).optional(),
|
|
10854
|
+
behaviors: z9.array(idNameSchema).optional(),
|
|
10855
|
+
custom_audiences: z9.array(z9.object({ id: parentRefSchema2 })).optional(),
|
|
10856
|
+
excluded_custom_audiences: z9.array(z9.object({ id: parentRefSchema2 })).optional(),
|
|
10857
|
+
flexible_spec: z9.array(z9.record(z9.string(), z9.unknown())).optional(),
|
|
10858
|
+
exclusions: z9.record(z9.string(), z9.unknown()).optional(),
|
|
10859
|
+
publisher_platforms: z9.array(z9.string()).optional(),
|
|
10860
|
+
facebook_positions: z9.array(z9.string()).optional(),
|
|
10861
|
+
instagram_positions: z9.array(z9.string()).optional(),
|
|
10862
|
+
audience_network_positions: z9.array(z9.string()).optional(),
|
|
10863
|
+
messenger_positions: z9.array(z9.string()).optional(),
|
|
10864
|
+
device_platforms: z9.array(z9.string()).optional(),
|
|
10865
|
+
targeting_automation: z9.object({ advantage_audience: z9.union([z9.literal(0), z9.literal(1)]) }).partial().optional()
|
|
10866
|
+
}).catchall(z9.unknown());
|
|
10867
|
+
var specialAdCategoriesSchema = z9.array(z9.enum(SPECIAL_AD_CATEGORIES)).default(["NONE"]);
|
|
10868
|
+
var campaignCreateSchema3 = z9.object({
|
|
10869
|
+
name: z9.string().min(1).max(META_LIMITS.campaign.nameMax),
|
|
10870
|
+
objective: z9.enum(OBJECTIVES),
|
|
10962
10871
|
status: stageableStatusSchema3.default("PAUSED"),
|
|
10963
10872
|
special_ad_categories: specialAdCategoriesSchema,
|
|
10964
|
-
special_ad_category_country:
|
|
10965
|
-
buying_type:
|
|
10966
|
-
bid_strategy:
|
|
10873
|
+
special_ad_category_country: z9.array(z9.string().length(2)).optional(),
|
|
10874
|
+
buying_type: z9.enum(BUYING_TYPES).default("AUCTION"),
|
|
10875
|
+
bid_strategy: z9.enum(BID_STRATEGIES).optional(),
|
|
10967
10876
|
/** Campaign Budget Optimization (Advantage campaign budget) — mutually exclusive with ad-set budgets. */
|
|
10968
10877
|
dailyBudget: moneySchema2.optional(),
|
|
10969
10878
|
lifetimeBudget: moneySchema2.optional(),
|
|
10970
10879
|
spendCap: moneySchema2.optional(),
|
|
10971
|
-
start_time:
|
|
10972
|
-
stop_time:
|
|
10880
|
+
start_time: z9.number().int().positive().optional(),
|
|
10881
|
+
stop_time: z9.number().int().positive().optional()
|
|
10973
10882
|
}).superRefine((p, ctx) => {
|
|
10974
10883
|
if (p.dailyBudget && p.lifetimeBudget) {
|
|
10975
10884
|
ctx.addIssue({ code: "custom", path: ["dailyBudget"], message: "set only one of dailyBudget or lifetimeBudget" });
|
|
@@ -10979,15 +10888,15 @@ var campaignCreateSchema3 = z10.object({
|
|
|
10979
10888
|
ctx.addIssue({ code: "custom", path: ["stop_time"], message: "stop_time must be after start_time" });
|
|
10980
10889
|
}
|
|
10981
10890
|
});
|
|
10982
|
-
var campaignUpdateSchema3 =
|
|
10983
|
-
name:
|
|
10891
|
+
var campaignUpdateSchema3 = z9.object({
|
|
10892
|
+
name: z9.string().min(1).max(META_LIMITS.campaign.nameMax).optional(),
|
|
10984
10893
|
status: updateStatusSchema.optional(),
|
|
10985
|
-
bid_strategy:
|
|
10894
|
+
bid_strategy: z9.enum(BID_STRATEGIES).optional(),
|
|
10986
10895
|
dailyBudget: moneySchema2.optional(),
|
|
10987
10896
|
lifetimeBudget: moneySchema2.optional(),
|
|
10988
10897
|
spendCap: moneySchema2.optional(),
|
|
10989
|
-
start_time:
|
|
10990
|
-
stop_time:
|
|
10898
|
+
start_time: z9.number().int().positive().optional(),
|
|
10899
|
+
stop_time: z9.number().int().positive().optional()
|
|
10991
10900
|
}).superRefine((p, ctx) => {
|
|
10992
10901
|
if (!Object.values(p).some((val) => val !== void 0)) {
|
|
10993
10902
|
ctx.addIssue({ code: "custom", message: "update needs at least one field" });
|
|
@@ -10997,38 +10906,38 @@ var campaignUpdateSchema3 = z10.object({
|
|
|
10997
10906
|
}
|
|
10998
10907
|
validateDailyBudgetFloor(p.dailyBudget, ctx, ["dailyBudget", "amount"]);
|
|
10999
10908
|
});
|
|
11000
|
-
var promotedObjectSchema =
|
|
10909
|
+
var promotedObjectSchema = z9.object({
|
|
11001
10910
|
page_id: parentRefSchema2.optional(),
|
|
11002
|
-
pixel_id:
|
|
11003
|
-
custom_event_type:
|
|
11004
|
-
application_id:
|
|
11005
|
-
object_store_url:
|
|
11006
|
-
product_catalog_id:
|
|
11007
|
-
product_set_id:
|
|
11008
|
-
whatsapp_phone_number:
|
|
11009
|
-
offline_conversion_data_set_id:
|
|
10911
|
+
pixel_id: z9.string().regex(NUMERIC_ID_REGEX3).optional(),
|
|
10912
|
+
custom_event_type: z9.enum(CUSTOM_EVENT_TYPES).optional(),
|
|
10913
|
+
application_id: z9.string().regex(NUMERIC_ID_REGEX3).optional(),
|
|
10914
|
+
object_store_url: z9.string().url().optional(),
|
|
10915
|
+
product_catalog_id: z9.string().regex(NUMERIC_ID_REGEX3).optional(),
|
|
10916
|
+
product_set_id: z9.string().regex(NUMERIC_ID_REGEX3).optional(),
|
|
10917
|
+
whatsapp_phone_number: z9.string().optional(),
|
|
10918
|
+
offline_conversion_data_set_id: z9.string().regex(NUMERIC_ID_REGEX3).optional()
|
|
11010
10919
|
}).partial();
|
|
11011
|
-
var attributionSpecSchema =
|
|
11012
|
-
|
|
11013
|
-
event_type:
|
|
11014
|
-
window_days:
|
|
10920
|
+
var attributionSpecSchema = z9.array(
|
|
10921
|
+
z9.object({
|
|
10922
|
+
event_type: z9.enum(ATTRIBUTION_EVENT_TYPES),
|
|
10923
|
+
window_days: z9.union([z9.literal(1), z9.literal(7), z9.literal(28)])
|
|
11015
10924
|
})
|
|
11016
10925
|
);
|
|
11017
10926
|
var adSetFields = {
|
|
11018
|
-
name:
|
|
10927
|
+
name: z9.string().min(1).max(META_LIMITS.adSet.nameMax),
|
|
11019
10928
|
campaign_id: parentRefSchema2,
|
|
11020
10929
|
status: stageableStatusSchema3.default("PAUSED"),
|
|
11021
10930
|
dailyBudget: moneySchema2.optional(),
|
|
11022
10931
|
lifetimeBudget: moneySchema2.optional(),
|
|
11023
10932
|
bidAmount: moneySchema2.optional(),
|
|
11024
|
-
bid_strategy:
|
|
11025
|
-
billing_event:
|
|
11026
|
-
optimization_goal:
|
|
11027
|
-
destination_type:
|
|
10933
|
+
bid_strategy: z9.enum(BID_STRATEGIES).optional(),
|
|
10934
|
+
billing_event: z9.enum(BILLING_EVENTS),
|
|
10935
|
+
optimization_goal: z9.enum(OPTIMIZATION_GOALS),
|
|
10936
|
+
destination_type: z9.enum(DESTINATION_TYPES).optional(),
|
|
11028
10937
|
promoted_object: promotedObjectSchema.optional(),
|
|
11029
10938
|
attribution_spec: attributionSpecSchema.optional(),
|
|
11030
|
-
start_time:
|
|
11031
|
-
end_time:
|
|
10939
|
+
start_time: z9.number().int().positive().optional(),
|
|
10940
|
+
end_time: z9.number().int().positive().optional(),
|
|
11032
10941
|
targeting: metaTargetingSchema
|
|
11033
10942
|
};
|
|
11034
10943
|
function validateAdSetBudgetAndBid(p, ctx) {
|
|
@@ -11046,22 +10955,22 @@ function validateAdSetBudgetAndBid(p, ctx) {
|
|
|
11046
10955
|
ctx.addIssue({ code: "custom", path: ["end_time"], message: "end_time must be after start_time" });
|
|
11047
10956
|
}
|
|
11048
10957
|
}
|
|
11049
|
-
var adSetCreateSchema =
|
|
10958
|
+
var adSetCreateSchema = z9.object(adSetFields).superRefine((p, ctx) => {
|
|
11050
10959
|
validateAdSetBudgetAndBid(p, ctx);
|
|
11051
10960
|
});
|
|
11052
|
-
var adSetUpdateSchema =
|
|
10961
|
+
var adSetUpdateSchema = z9.object({
|
|
11053
10962
|
name: adSetFields.name.optional(),
|
|
11054
10963
|
status: updateStatusSchema.optional(),
|
|
11055
10964
|
dailyBudget: moneySchema2.optional(),
|
|
11056
10965
|
lifetimeBudget: moneySchema2.optional(),
|
|
11057
10966
|
bidAmount: moneySchema2.optional(),
|
|
11058
|
-
bid_strategy:
|
|
11059
|
-
optimization_goal:
|
|
11060
|
-
destination_type:
|
|
10967
|
+
bid_strategy: z9.enum(BID_STRATEGIES).optional(),
|
|
10968
|
+
optimization_goal: z9.enum(OPTIMIZATION_GOALS).optional(),
|
|
10969
|
+
destination_type: z9.enum(DESTINATION_TYPES).optional(),
|
|
11061
10970
|
promoted_object: promotedObjectSchema.optional(),
|
|
11062
10971
|
attribution_spec: attributionSpecSchema.optional(),
|
|
11063
|
-
start_time:
|
|
11064
|
-
end_time:
|
|
10972
|
+
start_time: z9.number().int().positive().optional(),
|
|
10973
|
+
end_time: z9.number().int().positive().optional(),
|
|
11065
10974
|
targeting: metaTargetingSchema.optional()
|
|
11066
10975
|
}).superRefine((p, ctx) => {
|
|
11067
10976
|
if (!Object.values(p).some((val) => val !== void 0)) {
|
|
@@ -11069,38 +10978,38 @@ var adSetUpdateSchema = z10.object({
|
|
|
11069
10978
|
}
|
|
11070
10979
|
validateAdSetBudgetAndBid(p, ctx);
|
|
11071
10980
|
});
|
|
11072
|
-
var messageSchema =
|
|
11073
|
-
var headlineSchema2 =
|
|
11074
|
-
var descriptionSchema =
|
|
11075
|
-
var callToActionSchema =
|
|
11076
|
-
type:
|
|
10981
|
+
var messageSchema = z9.string().min(1).max(META_LIMITS.creative.messageHardMax);
|
|
10982
|
+
var headlineSchema2 = z9.string().min(1).max(META_LIMITS.creative.headlineMax);
|
|
10983
|
+
var descriptionSchema = z9.string().min(1).max(META_LIMITS.creative.descriptionMax);
|
|
10984
|
+
var callToActionSchema = z9.object({
|
|
10985
|
+
type: z9.enum(CTA_TYPES2),
|
|
11077
10986
|
/** Overrides the base link for the CTA button; defaults to the ad's link. */
|
|
11078
10987
|
link: httpsUrlSchema3.optional()
|
|
11079
10988
|
});
|
|
11080
|
-
var creativeEnhancementsSchema =
|
|
11081
|
-
standardEnhancements:
|
|
11082
|
-
features:
|
|
10989
|
+
var creativeEnhancementsSchema = z9.object({
|
|
10990
|
+
standardEnhancements: z9.enum(ENROLL_STATUSES).optional(),
|
|
10991
|
+
features: z9.record(z9.string(), z9.enum(ENROLL_STATUSES)).optional()
|
|
11083
10992
|
});
|
|
11084
10993
|
var creativeSharedFields = {
|
|
11085
|
-
name:
|
|
10994
|
+
name: z9.string().max(META_LIMITS.creative.nameMax).optional(),
|
|
11086
10995
|
/** Facebook Page id backing the ad's identity. */
|
|
11087
10996
|
page_id: parentRefSchema2,
|
|
11088
10997
|
/** Instagram account id for IG placements (aka instagram_actor_id on read). */
|
|
11089
|
-
instagram_user_id:
|
|
10998
|
+
instagram_user_id: z9.string().regex(NUMERIC_ID_REGEX3).optional(),
|
|
11090
10999
|
/** URL tracking parameters appended to the destination, e.g. "utm_source=fb&utm_campaign=x". */
|
|
11091
|
-
url_tags:
|
|
11000
|
+
url_tags: z9.string().max(1e3).optional(),
|
|
11092
11001
|
enhancements: creativeEnhancementsSchema.optional()
|
|
11093
11002
|
};
|
|
11094
11003
|
var imageMediaFields = {
|
|
11095
|
-
imageHash:
|
|
11004
|
+
imageHash: z9.string().regex(IMAGE_HASH_REGEX).optional(),
|
|
11096
11005
|
imageRef: tempRefSchema3.optional()
|
|
11097
11006
|
};
|
|
11098
11007
|
var videoMediaFields = {
|
|
11099
|
-
videoId:
|
|
11008
|
+
videoId: z9.string().regex(NUMERIC_ID_REGEX3).optional(),
|
|
11100
11009
|
videoRef: tempRefSchema3.optional(),
|
|
11101
11010
|
/** Thumbnail for a video creative — image hash, ref, or public url. */
|
|
11102
|
-
thumbnailHash:
|
|
11103
|
-
imageUrl:
|
|
11011
|
+
thumbnailHash: z9.string().regex(IMAGE_HASH_REGEX).optional(),
|
|
11012
|
+
imageUrl: z9.string().url().optional()
|
|
11104
11013
|
};
|
|
11105
11014
|
function countImageRefs(p) {
|
|
11106
11015
|
return [p.imageHash, p.imageRef].filter(Boolean).length;
|
|
@@ -11108,8 +11017,8 @@ function countImageRefs(p) {
|
|
|
11108
11017
|
function countVideoRefs(p) {
|
|
11109
11018
|
return [p.videoId, p.videoRef].filter(Boolean).length;
|
|
11110
11019
|
}
|
|
11111
|
-
var singleCreativeSchema =
|
|
11112
|
-
creativeType:
|
|
11020
|
+
var singleCreativeSchema = z9.object({
|
|
11021
|
+
creativeType: z9.literal("single"),
|
|
11113
11022
|
...creativeSharedFields,
|
|
11114
11023
|
/** Primary text. */
|
|
11115
11024
|
message: messageSchema,
|
|
@@ -11118,7 +11027,7 @@ var singleCreativeSchema = z10.object({
|
|
|
11118
11027
|
headline: headlineSchema2.optional(),
|
|
11119
11028
|
description: descriptionSchema.optional(),
|
|
11120
11029
|
/** Display URL / caption shown under the headline. */
|
|
11121
|
-
caption:
|
|
11030
|
+
caption: z9.string().max(255).optional(),
|
|
11122
11031
|
call_to_action: callToActionSchema.optional(),
|
|
11123
11032
|
...imageMediaFields,
|
|
11124
11033
|
...videoMediaFields
|
|
@@ -11142,10 +11051,10 @@ var singleCreativeSchema = z10.object({
|
|
|
11142
11051
|
});
|
|
11143
11052
|
}
|
|
11144
11053
|
});
|
|
11145
|
-
var carouselCardSchema =
|
|
11054
|
+
var carouselCardSchema = z9.object({
|
|
11146
11055
|
link: httpsUrlSchema3,
|
|
11147
|
-
headline:
|
|
11148
|
-
description:
|
|
11056
|
+
headline: z9.string().max(META_LIMITS.creative.headlineMax).optional(),
|
|
11057
|
+
description: z9.string().max(META_LIMITS.creative.descriptionMax).optional(),
|
|
11149
11058
|
call_to_action: callToActionSchema.optional(),
|
|
11150
11059
|
...imageMediaFields,
|
|
11151
11060
|
...videoMediaFields
|
|
@@ -11165,35 +11074,35 @@ var carouselCardSchema = z10.object({
|
|
|
11165
11074
|
ctx.addIssue({ code: "custom", path: ["videoId"], message: "each card is an image OR a video, not both" });
|
|
11166
11075
|
}
|
|
11167
11076
|
});
|
|
11168
|
-
var carouselCreativeSchema2 =
|
|
11169
|
-
creativeType:
|
|
11077
|
+
var carouselCreativeSchema2 = z9.object({
|
|
11078
|
+
creativeType: z9.literal("carousel"),
|
|
11170
11079
|
...creativeSharedFields,
|
|
11171
11080
|
message: messageSchema,
|
|
11172
11081
|
/** Optional "see more" card destination applied when a card has no own link. */
|
|
11173
11082
|
link: httpsUrlSchema3.optional(),
|
|
11174
11083
|
call_to_action: callToActionSchema.optional(),
|
|
11175
|
-
cards:
|
|
11084
|
+
cards: z9.array(carouselCardSchema).min(META_LIMITS.creative.carouselCardsMin).max(META_LIMITS.creative.carouselCardsMax)
|
|
11176
11085
|
});
|
|
11177
|
-
var dynamicImageSchema =
|
|
11178
|
-
var dynamicVideoSchema =
|
|
11086
|
+
var dynamicImageSchema = z9.object({ ...imageMediaFields }).refine((p) => countImageRefs(p) === 1, "each dynamic image needs exactly one reference");
|
|
11087
|
+
var dynamicVideoSchema = z9.object({
|
|
11179
11088
|
videoId: videoMediaFields.videoId,
|
|
11180
11089
|
videoRef: videoMediaFields.videoRef,
|
|
11181
11090
|
thumbnailHash: videoMediaFields.thumbnailHash
|
|
11182
11091
|
}).refine((p) => countVideoRefs(p) === 1, "each dynamic video needs exactly one reference");
|
|
11183
11092
|
var DYN = META_LIMITS.creative;
|
|
11184
|
-
var dynamicCreativeSchema =
|
|
11185
|
-
creativeType:
|
|
11093
|
+
var dynamicCreativeSchema = z9.object({
|
|
11094
|
+
creativeType: z9.literal("dynamic"),
|
|
11186
11095
|
...creativeSharedFields,
|
|
11187
|
-
bodies:
|
|
11188
|
-
titles:
|
|
11189
|
-
descriptions:
|
|
11190
|
-
images:
|
|
11191
|
-
videos:
|
|
11192
|
-
ad_formats:
|
|
11193
|
-
call_to_action_types:
|
|
11194
|
-
link_urls:
|
|
11096
|
+
bodies: z9.array(z9.object({ text: messageSchema })).min(DYN.dynamicTextsMin).max(DYN.dynamicTextsMax),
|
|
11097
|
+
titles: z9.array(z9.object({ text: headlineSchema2 })).min(DYN.dynamicTextsMin).max(DYN.dynamicTextsMax),
|
|
11098
|
+
descriptions: z9.array(z9.object({ text: descriptionSchema })).max(DYN.dynamicTextsMax).optional(),
|
|
11099
|
+
images: z9.array(dynamicImageSchema).optional(),
|
|
11100
|
+
videos: z9.array(dynamicVideoSchema).optional(),
|
|
11101
|
+
ad_formats: z9.array(z9.enum(AD_FORMATS2)).min(1),
|
|
11102
|
+
call_to_action_types: z9.array(z9.enum(CTA_TYPES2)).optional(),
|
|
11103
|
+
link_urls: z9.array(z9.object({ website_url: httpsUrlSchema3, display_url: z9.string().optional() })).min(1),
|
|
11195
11104
|
/** Multi-language / placement customization — structural passthrough for v1. */
|
|
11196
|
-
asset_customization_rules:
|
|
11105
|
+
asset_customization_rules: z9.array(z9.record(z9.string(), z9.unknown())).optional()
|
|
11197
11106
|
}).superRefine((p, ctx) => {
|
|
11198
11107
|
if (!(p.images?.length || p.videos?.length)) {
|
|
11199
11108
|
ctx.addIssue({
|
|
@@ -11203,57 +11112,57 @@ var dynamicCreativeSchema = z10.object({
|
|
|
11203
11112
|
});
|
|
11204
11113
|
}
|
|
11205
11114
|
});
|
|
11206
|
-
var existingPostCreativeSchema =
|
|
11207
|
-
creativeType:
|
|
11115
|
+
var existingPostCreativeSchema = z9.object({
|
|
11116
|
+
creativeType: z9.literal("existing_post"),
|
|
11208
11117
|
name: creativeSharedFields.name,
|
|
11209
11118
|
/** "<page_id>_<post_id>" object story id of the post to promote. */
|
|
11210
|
-
object_story_id:
|
|
11119
|
+
object_story_id: z9.string().regex(/^\d+_\d+$/, 'expected "<page_id>_<post_id>"'),
|
|
11211
11120
|
instagram_user_id: creativeSharedFields.instagram_user_id,
|
|
11212
11121
|
url_tags: creativeSharedFields.url_tags,
|
|
11213
11122
|
enhancements: creativeSharedFields.enhancements
|
|
11214
11123
|
});
|
|
11215
|
-
var creativeContentSchema2 =
|
|
11124
|
+
var creativeContentSchema2 = z9.discriminatedUnion("creativeType", [
|
|
11216
11125
|
singleCreativeSchema,
|
|
11217
11126
|
carouselCreativeSchema2,
|
|
11218
11127
|
dynamicCreativeSchema,
|
|
11219
11128
|
existingPostCreativeSchema
|
|
11220
11129
|
]);
|
|
11221
11130
|
var adCreativeCreateSchema = creativeContentSchema2;
|
|
11222
|
-
var adCreativeUpdateSchema =
|
|
11223
|
-
name:
|
|
11131
|
+
var adCreativeUpdateSchema = z9.object({
|
|
11132
|
+
name: z9.string().max(META_LIMITS.creative.nameMax).optional(),
|
|
11224
11133
|
status: updateStatusSchema.optional(),
|
|
11225
11134
|
/** Content patch — only honored when the target is a staged meta_temp_* creative. */
|
|
11226
|
-
content:
|
|
11135
|
+
content: z9.record(z9.string(), z9.unknown()).optional()
|
|
11227
11136
|
}).refine((p) => Object.values(p).some((val) => val !== void 0), "update needs at least one field");
|
|
11228
|
-
var adCreateSchema2 =
|
|
11229
|
-
name:
|
|
11137
|
+
var adCreateSchema2 = z9.object({
|
|
11138
|
+
name: z9.string().min(1).max(META_LIMITS.ad.nameMax),
|
|
11230
11139
|
adset_id: parentRefSchema2,
|
|
11231
11140
|
status: stageableStatusSchema3.default("PAUSED"),
|
|
11232
|
-
creative:
|
|
11141
|
+
creative: z9.object({ creative_id: parentRefSchema2 }),
|
|
11233
11142
|
/** Conversion pixel / offline event set / view tags — structural passthrough. */
|
|
11234
|
-
tracking_specs:
|
|
11143
|
+
tracking_specs: z9.array(z9.record(z9.string(), z9.unknown())).optional()
|
|
11235
11144
|
});
|
|
11236
|
-
var adUpdateSchema2 =
|
|
11237
|
-
name:
|
|
11145
|
+
var adUpdateSchema2 = z9.object({
|
|
11146
|
+
name: z9.string().min(1).max(META_LIMITS.ad.nameMax).optional(),
|
|
11238
11147
|
status: updateStatusSchema.optional(),
|
|
11239
11148
|
/** Swapping the creative is the Meta way to "edit" an ad's creative. */
|
|
11240
|
-
creative:
|
|
11241
|
-
tracking_specs:
|
|
11149
|
+
creative: z9.object({ creative_id: parentRefSchema2 }).optional(),
|
|
11150
|
+
tracking_specs: z9.array(z9.record(z9.string(), z9.unknown())).optional()
|
|
11242
11151
|
}).refine((p) => Object.values(p).some((val) => val !== void 0), "update needs at least one field");
|
|
11243
|
-
var lookalikeSpecSchema =
|
|
11244
|
-
origin:
|
|
11245
|
-
ratio:
|
|
11246
|
-
country:
|
|
11247
|
-
});
|
|
11248
|
-
var customAudienceCreateSchema =
|
|
11249
|
-
name:
|
|
11250
|
-
subtype:
|
|
11251
|
-
description:
|
|
11252
|
-
customer_file_source:
|
|
11253
|
-
retention_days:
|
|
11152
|
+
var lookalikeSpecSchema = z9.object({
|
|
11153
|
+
origin: z9.array(z9.object({ id: parentRefSchema2 })).min(1),
|
|
11154
|
+
ratio: z9.number().min(0.01).max(0.2).optional(),
|
|
11155
|
+
country: z9.string().length(2).optional()
|
|
11156
|
+
});
|
|
11157
|
+
var customAudienceCreateSchema = z9.object({
|
|
11158
|
+
name: z9.string().min(1).max(META_LIMITS.audience.nameMax),
|
|
11159
|
+
subtype: z9.enum(CUSTOM_AUDIENCE_SUBTYPES),
|
|
11160
|
+
description: z9.string().max(500).optional(),
|
|
11161
|
+
customer_file_source: z9.string().optional(),
|
|
11162
|
+
retention_days: z9.number().int().min(1).max(META_LIMITS.audience.retentionDaysMax).optional(),
|
|
11254
11163
|
lookalike_spec: lookalikeSpecSchema.optional(),
|
|
11255
11164
|
/** Website/engagement rule — structural passthrough validated by Meta. */
|
|
11256
|
-
rule:
|
|
11165
|
+
rule: z9.record(z9.string(), z9.unknown()).optional()
|
|
11257
11166
|
}).superRefine((p, ctx) => {
|
|
11258
11167
|
if (p.subtype === "LOOKALIKE" && !p.lookalike_spec) {
|
|
11259
11168
|
ctx.addIssue({ code: "custom", path: ["lookalike_spec"], message: "LOOKALIKE audiences need a lookalike_spec" });
|
|
@@ -11262,16 +11171,16 @@ var customAudienceCreateSchema = z10.object({
|
|
|
11262
11171
|
ctx.addIssue({ code: "custom", path: ["rule"], message: `${p.subtype} audiences need a rule (use --file)` });
|
|
11263
11172
|
}
|
|
11264
11173
|
});
|
|
11265
|
-
var customAudienceUpdateSchema =
|
|
11266
|
-
name:
|
|
11267
|
-
description:
|
|
11174
|
+
var customAudienceUpdateSchema = z9.object({
|
|
11175
|
+
name: z9.string().min(1).max(META_LIMITS.audience.nameMax).optional(),
|
|
11176
|
+
description: z9.string().max(500).optional()
|
|
11268
11177
|
}).refine((p) => Object.values(p).some((val) => val !== void 0), "update needs at least one field");
|
|
11269
|
-
var mediaUploadSchema =
|
|
11270
|
-
kind:
|
|
11178
|
+
var mediaUploadSchema = z9.object({
|
|
11179
|
+
kind: z9.enum(MEDIA_KINDS),
|
|
11271
11180
|
bakerImageId: bakerMediaIdSchema2.optional(),
|
|
11272
11181
|
bakerVideoId: bakerMediaIdSchema2.optional(),
|
|
11273
11182
|
/** Optional display name / filename hint. */
|
|
11274
|
-
name:
|
|
11183
|
+
name: z9.string().max(255).optional()
|
|
11275
11184
|
}).superRefine((p, ctx) => {
|
|
11276
11185
|
if (p.kind === "image" && !p.bakerImageId) {
|
|
11277
11186
|
ctx.addIssue({ code: "custom", path: ["bakerImageId"], message: "image uploads need a bakerImageId" });
|
|
@@ -11293,16 +11202,16 @@ var META_DRAFT_OP_KINDS = [
|
|
|
11293
11202
|
"customAudience.update",
|
|
11294
11203
|
"media.upload"
|
|
11295
11204
|
];
|
|
11296
|
-
var metaDraftOpKindSchema =
|
|
11297
|
-
var accountIdSchema2 =
|
|
11298
|
-
var updateTargetSchema2 =
|
|
11205
|
+
var metaDraftOpKindSchema = z9.enum(META_DRAFT_OP_KINDS);
|
|
11206
|
+
var accountIdSchema2 = z9.string().regex(NUMERIC_ID_REGEX3, "accountId must be the bare numeric ad account id");
|
|
11207
|
+
var updateTargetSchema2 = z9.union([z9.string().regex(NUMERIC_ID_REGEX3), tempRefSchema3]);
|
|
11299
11208
|
function createOp3(kind, payload) {
|
|
11300
|
-
return
|
|
11209
|
+
return z9.object({ kind: z9.literal(kind), accountId: accountIdSchema2, payload });
|
|
11301
11210
|
}
|
|
11302
11211
|
function updateOp3(kind, payload) {
|
|
11303
|
-
return
|
|
11212
|
+
return z9.object({ kind: z9.literal(kind), accountId: accountIdSchema2, target: updateTargetSchema2, payload });
|
|
11304
11213
|
}
|
|
11305
|
-
var metaDraftOpInputSchema =
|
|
11214
|
+
var metaDraftOpInputSchema = z9.discriminatedUnion("kind", [
|
|
11306
11215
|
createOp3("campaign.create", campaignCreateSchema3),
|
|
11307
11216
|
updateOp3("campaign.update", campaignUpdateSchema3),
|
|
11308
11217
|
createOp3("adSet.create", adSetCreateSchema),
|
|
@@ -11317,89 +11226,89 @@ var metaDraftOpInputSchema = z10.discriminatedUnion("kind", [
|
|
|
11317
11226
|
]);
|
|
11318
11227
|
|
|
11319
11228
|
// ../api/src/ads-meta/wire.ts
|
|
11320
|
-
import { z as
|
|
11321
|
-
var metaWriteModeSchema =
|
|
11322
|
-
var metaDraftOpResultSchema =
|
|
11323
|
-
status:
|
|
11229
|
+
import { z as z10 } from "zod";
|
|
11230
|
+
var metaWriteModeSchema = z10.enum(["live", "simulated"]);
|
|
11231
|
+
var metaDraftOpResultSchema = z10.object({
|
|
11232
|
+
status: z10.enum(["applied", "simulated", "failed", "skipped"]),
|
|
11324
11233
|
/** The resulting Meta node id (campaign/adset/creative/ad/audience) or simulated id. */
|
|
11325
|
-
id:
|
|
11234
|
+
id: z10.string().optional(),
|
|
11326
11235
|
/** For media.upload ops: the resulting image hash. */
|
|
11327
|
-
hash:
|
|
11328
|
-
error:
|
|
11329
|
-
skippedBecause:
|
|
11330
|
-
executedAt:
|
|
11236
|
+
hash: z10.string().optional(),
|
|
11237
|
+
error: z10.string().optional(),
|
|
11238
|
+
skippedBecause: z10.string().optional(),
|
|
11239
|
+
executedAt: z10.number().optional()
|
|
11331
11240
|
});
|
|
11332
|
-
var metaDraftStageRequestSchema =
|
|
11333
|
-
chatId:
|
|
11241
|
+
var metaDraftStageRequestSchema = z10.object({
|
|
11242
|
+
chatId: z10.string(),
|
|
11334
11243
|
op: metaDraftOpInputSchema
|
|
11335
11244
|
});
|
|
11336
|
-
var metaDraftStageResponseSchema =
|
|
11337
|
-
staged:
|
|
11338
|
-
ref:
|
|
11245
|
+
var metaDraftStageResponseSchema = z10.object({
|
|
11246
|
+
staged: z10.literal(true),
|
|
11247
|
+
ref: z10.string(),
|
|
11339
11248
|
kind: metaDraftOpKindSchema,
|
|
11340
11249
|
mode: metaWriteModeSchema,
|
|
11341
|
-
dependsOn:
|
|
11342
|
-
summary:
|
|
11343
|
-
warnings:
|
|
11250
|
+
dependsOn: z10.array(z10.string()),
|
|
11251
|
+
summary: z10.string(),
|
|
11252
|
+
warnings: z10.array(z10.string()),
|
|
11344
11253
|
/** True when the op amended an already-staged op in place instead of appending a new one. */
|
|
11345
|
-
amended:
|
|
11346
|
-
});
|
|
11347
|
-
var metaDraftDuplicateRequestSchema =
|
|
11348
|
-
chatId:
|
|
11349
|
-
accountId:
|
|
11350
|
-
entity:
|
|
11351
|
-
sourceId:
|
|
11352
|
-
overrides:
|
|
11254
|
+
amended: z10.boolean().optional()
|
|
11255
|
+
});
|
|
11256
|
+
var metaDraftDuplicateRequestSchema = z10.object({
|
|
11257
|
+
chatId: z10.string(),
|
|
11258
|
+
accountId: z10.string(),
|
|
11259
|
+
entity: z10.enum(["campaign", "adSet", "ad"]),
|
|
11260
|
+
sourceId: z10.string(),
|
|
11261
|
+
overrides: z10.record(z10.string(), z10.unknown()).optional(),
|
|
11353
11262
|
/** Pause the original after the copy publishes. */
|
|
11354
|
-
replace:
|
|
11263
|
+
replace: z10.boolean().optional()
|
|
11355
11264
|
});
|
|
11356
|
-
var metaDraftOpViewSchema =
|
|
11357
|
-
ref:
|
|
11265
|
+
var metaDraftOpViewSchema = z10.object({
|
|
11266
|
+
ref: z10.string(),
|
|
11358
11267
|
kind: metaDraftOpKindSchema,
|
|
11359
|
-
accountId:
|
|
11360
|
-
target:
|
|
11361
|
-
dependsOn:
|
|
11362
|
-
summary:
|
|
11363
|
-
stagedAt:
|
|
11268
|
+
accountId: z10.string(),
|
|
11269
|
+
target: z10.string().optional(),
|
|
11270
|
+
dependsOn: z10.array(z10.string()),
|
|
11271
|
+
summary: z10.string(),
|
|
11272
|
+
stagedAt: z10.number(),
|
|
11364
11273
|
result: metaDraftOpResultSchema.optional()
|
|
11365
11274
|
});
|
|
11366
|
-
var metaDraftListRequestSchema =
|
|
11367
|
-
chatId:
|
|
11275
|
+
var metaDraftListRequestSchema = z10.object({
|
|
11276
|
+
chatId: z10.string()
|
|
11368
11277
|
});
|
|
11369
|
-
var metaDraftAdvisorySchema =
|
|
11370
|
-
ref:
|
|
11371
|
-
message:
|
|
11278
|
+
var metaDraftAdvisorySchema = z10.object({
|
|
11279
|
+
ref: z10.string(),
|
|
11280
|
+
message: z10.string()
|
|
11372
11281
|
});
|
|
11373
|
-
var metaDraftListResponseSchema =
|
|
11374
|
-
status:
|
|
11282
|
+
var metaDraftListResponseSchema = z10.object({
|
|
11283
|
+
status: z10.enum(["active", "publishing", "applied", "discarded", "none"]),
|
|
11375
11284
|
mode: metaWriteModeSchema,
|
|
11376
|
-
count:
|
|
11377
|
-
ops:
|
|
11285
|
+
count: z10.number(),
|
|
11286
|
+
ops: z10.array(metaDraftOpViewSchema),
|
|
11378
11287
|
/** Non-blocking cross-op quality advisories — "good campaign, not just valid". */
|
|
11379
|
-
advisories:
|
|
11288
|
+
advisories: z10.array(metaDraftAdvisorySchema)
|
|
11380
11289
|
});
|
|
11381
|
-
var metaDraftRemoveRequestSchema =
|
|
11382
|
-
chatId:
|
|
11383
|
-
ref:
|
|
11290
|
+
var metaDraftRemoveRequestSchema = z10.object({
|
|
11291
|
+
chatId: z10.string(),
|
|
11292
|
+
ref: z10.string()
|
|
11384
11293
|
});
|
|
11385
|
-
var metaDraftRemoveResponseSchema =
|
|
11294
|
+
var metaDraftRemoveResponseSchema = z10.object({
|
|
11386
11295
|
/** The requested ref plus any dependents removed by cascade. */
|
|
11387
|
-
removed:
|
|
11296
|
+
removed: z10.array(z10.string())
|
|
11388
11297
|
});
|
|
11389
|
-
var metaDraftClearRequestSchema =
|
|
11390
|
-
chatId:
|
|
11298
|
+
var metaDraftClearRequestSchema = z10.object({
|
|
11299
|
+
chatId: z10.string()
|
|
11391
11300
|
});
|
|
11392
|
-
var metaDraftClearResponseSchema =
|
|
11393
|
-
cleared:
|
|
11301
|
+
var metaDraftClearResponseSchema = z10.object({
|
|
11302
|
+
cleared: z10.number()
|
|
11394
11303
|
});
|
|
11395
|
-
var metaFieldErrorSchema =
|
|
11396
|
-
path:
|
|
11397
|
-
message:
|
|
11304
|
+
var metaFieldErrorSchema = z10.object({
|
|
11305
|
+
path: z10.string(),
|
|
11306
|
+
message: z10.string()
|
|
11398
11307
|
});
|
|
11399
|
-
var metaDraftErrorResponseSchema =
|
|
11400
|
-
code:
|
|
11401
|
-
error:
|
|
11402
|
-
fields:
|
|
11308
|
+
var metaDraftErrorResponseSchema = z10.object({
|
|
11309
|
+
code: z10.string(),
|
|
11310
|
+
error: z10.string(),
|
|
11311
|
+
fields: z10.array(metaFieldErrorSchema).optional()
|
|
11403
11312
|
});
|
|
11404
11313
|
|
|
11405
11314
|
// src/commands/ads/meta/write-shared.ts
|
|
@@ -11410,19 +11319,19 @@ function failWriteValidation3(message) {
|
|
|
11410
11319
|
writeJsonEnvelope({ ok: false, error: { code: "VALIDATION_ERROR", message } });
|
|
11411
11320
|
process.exit(1);
|
|
11412
11321
|
}
|
|
11413
|
-
function loadJsonFileArg3(
|
|
11414
|
-
if (typeof
|
|
11322
|
+
function loadJsonFileArg3(path14) {
|
|
11323
|
+
if (typeof path14 !== "string" || path14.length === 0) {
|
|
11415
11324
|
return {};
|
|
11416
11325
|
}
|
|
11417
11326
|
try {
|
|
11418
|
-
const parsed = JSON.parse(readFileSync8(
|
|
11327
|
+
const parsed = JSON.parse(readFileSync8(path14, "utf8"));
|
|
11419
11328
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
11420
|
-
failWriteValidation3(`${
|
|
11329
|
+
failWriteValidation3(`${path14} must contain a JSON object`);
|
|
11421
11330
|
}
|
|
11422
11331
|
return parsed;
|
|
11423
11332
|
} catch (err) {
|
|
11424
11333
|
if (err instanceof SyntaxError) {
|
|
11425
|
-
failWriteValidation3(`${
|
|
11334
|
+
failWriteValidation3(`${path14} is not valid JSON: ${err.message}`);
|
|
11426
11335
|
}
|
|
11427
11336
|
throw err;
|
|
11428
11337
|
}
|
|
@@ -14485,7 +14394,7 @@ async function probeDuration(filePath) {
|
|
|
14485
14394
|
|
|
14486
14395
|
// src/commands/canvas/run.ts
|
|
14487
14396
|
import { readFile as readFile2 } from "fs/promises";
|
|
14488
|
-
import
|
|
14397
|
+
import path5 from "path";
|
|
14489
14398
|
import { defineCommand as defineCommand88 } from "citty";
|
|
14490
14399
|
|
|
14491
14400
|
// src/commands/canvas/placeholders.ts
|
|
@@ -14529,9 +14438,102 @@ function isResolvableRelative(value) {
|
|
|
14529
14438
|
return typeof value === "string" && value.length > 0 && !value.includes("[TODO") && !path2.isAbsolute(value);
|
|
14530
14439
|
}
|
|
14531
14440
|
|
|
14441
|
+
// src/commands/canvas/run-record.ts
|
|
14442
|
+
import path3 from "path";
|
|
14443
|
+
var MAX_RUN_NODES = 200;
|
|
14444
|
+
var MAX_OUTPUTS_PER_NODE = 10;
|
|
14445
|
+
var MAX_FINAL_OUTPUTS = 10;
|
|
14446
|
+
var MAX_CREATIVE_SLUG_LENGTH = 100;
|
|
14447
|
+
function creativeSlugFromCanvasPath(filePath) {
|
|
14448
|
+
const normalized = filePath.split(path3.sep).join("/");
|
|
14449
|
+
const match = normalized.match(/(?:^|\/)src\/creatives\/([a-z0-9](?:[a-z0-9-]*[a-z0-9])?)\//);
|
|
14450
|
+
const slug = match?.[1] ?? null;
|
|
14451
|
+
return slug && slug.length <= MAX_CREATIVE_SLUG_LENGTH ? slug : null;
|
|
14452
|
+
}
|
|
14453
|
+
var OUTPUT_KINDS = /* @__PURE__ */ new Set(["image", "video", "audio", "json", "text", "font"]);
|
|
14454
|
+
function toRecordOutput(slot, value) {
|
|
14455
|
+
const refs = collectAssetRefLikes(value);
|
|
14456
|
+
const ref = refs.length === 1 ? refs[0] : null;
|
|
14457
|
+
if (!ref || !isPersistedAssetRef(ref)) return null;
|
|
14458
|
+
const kind = typeof ref.kind === "string" && OUTPUT_KINDS.has(ref.kind) ? ref.kind : null;
|
|
14459
|
+
if (!kind) return null;
|
|
14460
|
+
return {
|
|
14461
|
+
slot,
|
|
14462
|
+
kind,
|
|
14463
|
+
sha256: ref.sha256,
|
|
14464
|
+
url: ref.url,
|
|
14465
|
+
mime: ref.mime,
|
|
14466
|
+
width: typeof ref.width === "number" ? ref.width : void 0,
|
|
14467
|
+
height: typeof ref.height === "number" ? ref.height : void 0,
|
|
14468
|
+
durationMs: typeof ref.duration_ms === "number" ? ref.duration_ms : void 0
|
|
14469
|
+
};
|
|
14470
|
+
}
|
|
14471
|
+
function nodeOutputsToRecord(nodeOutputs) {
|
|
14472
|
+
const out = [];
|
|
14473
|
+
for (const [slot, value] of Object.entries(nodeOutputs)) {
|
|
14474
|
+
if (Array.isArray(value)) {
|
|
14475
|
+
value.forEach((item, i) => {
|
|
14476
|
+
const rec = toRecordOutput(`${slot}#${i}`, item);
|
|
14477
|
+
if (rec) out.push(rec);
|
|
14478
|
+
});
|
|
14479
|
+
} else {
|
|
14480
|
+
const rec = toRecordOutput(slot, value);
|
|
14481
|
+
if (rec) out.push(rec);
|
|
14482
|
+
}
|
|
14483
|
+
}
|
|
14484
|
+
return out.slice(0, MAX_OUTPUTS_PER_NODE);
|
|
14485
|
+
}
|
|
14486
|
+
function finalOutputsToRecord(output) {
|
|
14487
|
+
if (Array.isArray(output)) {
|
|
14488
|
+
return output.map((item, i) => toRecordOutput(`final#${i}`, item)).filter((rec2) => rec2 !== null).slice(0, MAX_FINAL_OUTPUTS);
|
|
14489
|
+
}
|
|
14490
|
+
const rec = toRecordOutput("final", output);
|
|
14491
|
+
return rec ? [rec] : [];
|
|
14492
|
+
}
|
|
14493
|
+
function buildRunRecord(result, meta) {
|
|
14494
|
+
const nodes = result.node_runs.slice(0, MAX_RUN_NODES).map((run) => ({
|
|
14495
|
+
nodeId: run.node_id,
|
|
14496
|
+
nodeType: run.node_type,
|
|
14497
|
+
cached: run.cached,
|
|
14498
|
+
credits: run.credits,
|
|
14499
|
+
durationMs: run.duration_ms,
|
|
14500
|
+
outputs: nodeOutputsToRecord(result.outputs_by_node[run.node_id] ?? {})
|
|
14501
|
+
}));
|
|
14502
|
+
const finalOutputs = finalOutputsToRecord(result.output);
|
|
14503
|
+
return {
|
|
14504
|
+
runId: result.run_id,
|
|
14505
|
+
creativeSlug: meta.creativeSlug,
|
|
14506
|
+
canvasPath: meta.canvasPath,
|
|
14507
|
+
canvasSha: meta.canvasSha,
|
|
14508
|
+
chatId: meta.chatId,
|
|
14509
|
+
status: "completed",
|
|
14510
|
+
stats: {
|
|
14511
|
+
totalNodes: result.stats.total_nodes,
|
|
14512
|
+
cachedNodes: result.stats.cached_nodes,
|
|
14513
|
+
totalCredits: result.stats.total_credits,
|
|
14514
|
+
durationMs: result.stats.duration_ms
|
|
14515
|
+
},
|
|
14516
|
+
nodes,
|
|
14517
|
+
finalOutputs: finalOutputs.length > 0 ? finalOutputs : void 0
|
|
14518
|
+
};
|
|
14519
|
+
}
|
|
14520
|
+
function buildFailedRunRecord(runId, errorMessage, meta) {
|
|
14521
|
+
return {
|
|
14522
|
+
runId,
|
|
14523
|
+
creativeSlug: meta.creativeSlug,
|
|
14524
|
+
canvasPath: meta.canvasPath,
|
|
14525
|
+
canvasSha: meta.canvasSha,
|
|
14526
|
+
chatId: meta.chatId,
|
|
14527
|
+
status: "failed",
|
|
14528
|
+
errorMessage: errorMessage.slice(0, 2e3),
|
|
14529
|
+
stats: { totalNodes: 0, cachedNodes: 0, totalCredits: 0, durationMs: 0 },
|
|
14530
|
+
nodes: []
|
|
14531
|
+
};
|
|
14532
|
+
}
|
|
14533
|
+
|
|
14532
14534
|
// src/commands/canvas/run-retention.ts
|
|
14533
14535
|
import { rm } from "fs/promises";
|
|
14534
|
-
import
|
|
14536
|
+
import path4 from "path";
|
|
14535
14537
|
function runDirsToPrune(entries, keep, currentRunId) {
|
|
14536
14538
|
const runs = entries.filter((e) => /^r_[0-9A-Za-z]+$/.test(e) && e !== currentRunId).sort();
|
|
14537
14539
|
if (keep <= 0) return runs;
|
|
@@ -14548,7 +14550,7 @@ async function pruneOldRuns(outputsDir, keep, currentRunId, log) {
|
|
|
14548
14550
|
const toPrune = runDirsToPrune(entries, keep, currentRunId);
|
|
14549
14551
|
if (toPrune.length === 0) return;
|
|
14550
14552
|
for (const dir of toPrune) {
|
|
14551
|
-
await rm(
|
|
14553
|
+
await rm(path4.join(outputsDir, dir), { recursive: true, force: true }).catch(
|
|
14552
14554
|
(e) => log(`[prune ] could not remove ${dir}: ${e.message}`)
|
|
14553
14555
|
);
|
|
14554
14556
|
}
|
|
@@ -14575,10 +14577,22 @@ var runCommand = defineCommand88({
|
|
|
14575
14577
|
"keep-runs": {
|
|
14576
14578
|
type: "string",
|
|
14577
14579
|
description: "After the run, prune old r_* run dirs, keeping the N newest (off by default)"
|
|
14580
|
+
},
|
|
14581
|
+
"remote-cache": {
|
|
14582
|
+
type: "string",
|
|
14583
|
+
description: "on | off \u2014 company-scoped remote cache + durable asset persistence (default on; env BAKER_CANVAS_REMOTE_CACHE)"
|
|
14584
|
+
},
|
|
14585
|
+
// citty consumes any `--no-<flag>` as a negation of `<flag>`, so the
|
|
14586
|
+
// opt-out spelling `--no-record` requires the flag to be named `record`
|
|
14587
|
+
// (a literal "no-record" arg would never receive a value).
|
|
14588
|
+
record: {
|
|
14589
|
+
type: "boolean",
|
|
14590
|
+
default: true,
|
|
14591
|
+
description: "Post the durable run-history record to Baker (disable with --no-record)"
|
|
14578
14592
|
}
|
|
14579
14593
|
},
|
|
14580
14594
|
async run({ args }) {
|
|
14581
|
-
const filePath =
|
|
14595
|
+
const filePath = path5.resolve(String(args.file));
|
|
14582
14596
|
const raw = await readFile2(filePath, "utf8");
|
|
14583
14597
|
let parsed;
|
|
14584
14598
|
try {
|
|
@@ -14589,7 +14603,7 @@ var runCommand = defineCommand88({
|
|
|
14589
14603
|
`);
|
|
14590
14604
|
process.exit(2);
|
|
14591
14605
|
}
|
|
14592
|
-
parsed = resolveRelativeCanvasPaths(parsed,
|
|
14606
|
+
parsed = resolveRelativeCanvasPaths(parsed, path5.dirname(filePath));
|
|
14593
14607
|
const pending = unsuppliedPlaceholderAssets(parsed);
|
|
14594
14608
|
if (pending.length > 0) {
|
|
14595
14609
|
process.stderr.write(
|
|
@@ -14609,16 +14623,26 @@ var runCommand = defineCommand88({
|
|
|
14609
14623
|
);
|
|
14610
14624
|
process.exit(2);
|
|
14611
14625
|
}
|
|
14626
|
+
const remoteCache = args["remote-cache"] !== void 0 ? String(args["remote-cache"]) !== "off" : void 0;
|
|
14612
14627
|
const engine = createEngineFromEnv({
|
|
14613
14628
|
cacheDir: args["cache-dir"] ? String(args["cache-dir"]) : void 0,
|
|
14614
14629
|
outputsDir: args["outputs-dir"] ? String(args["outputs-dir"]) : void 0,
|
|
14615
14630
|
log: (line) => process.stdout.write(`${line}
|
|
14616
|
-
`)
|
|
14631
|
+
`),
|
|
14632
|
+
remoteCache
|
|
14617
14633
|
});
|
|
14634
|
+
const runId = args["run-id"] ? String(args["run-id"]) : `r_${ulid()}`;
|
|
14635
|
+
const recordMeta = {
|
|
14636
|
+
creativeSlug: creativeSlugFromCanvasPath(filePath) ?? void 0,
|
|
14637
|
+
canvasPath: path5.relative(process.cwd(), filePath) || void 0,
|
|
14638
|
+
canvasSha: sha256Hex(Buffer.from(raw)),
|
|
14639
|
+
chatId: getEnv().BAKER_CHAT_ID || void 0
|
|
14640
|
+
};
|
|
14641
|
+
const record = args.record === false ? null : buildRecorder();
|
|
14618
14642
|
try {
|
|
14619
14643
|
const policy = args["cache-policy"] ?? "read_write";
|
|
14620
14644
|
const result = await engine.run(parsed, {
|
|
14621
|
-
run_id:
|
|
14645
|
+
run_id: runId,
|
|
14622
14646
|
cache_policy: policy,
|
|
14623
14647
|
concurrency: resolveConcurrency(
|
|
14624
14648
|
// --concurrency wins; --parallel is the discoverable alias for the same bound.
|
|
@@ -14626,9 +14650,10 @@ var runCommand = defineCommand88({
|
|
|
14626
14650
|
process.env.BAKER_CANVAS_CONCURRENCY
|
|
14627
14651
|
)
|
|
14628
14652
|
});
|
|
14653
|
+
if (record) await record(buildRunRecord(result, recordMeta));
|
|
14629
14654
|
const keepRuns = args["keep-runs"] !== void 0 ? Number(args["keep-runs"]) : void 0;
|
|
14630
14655
|
if (keepRuns !== void 0 && Number.isFinite(keepRuns)) {
|
|
14631
|
-
const outputsDir = args["outputs-dir"] ?
|
|
14656
|
+
const outputsDir = args["outputs-dir"] ? path5.resolve(String(args["outputs-dir"])) : path5.resolve("canvas");
|
|
14632
14657
|
await pruneOldRuns(outputsDir, keepRuns, result.run_id, (line) => process.stdout.write(`${line}
|
|
14633
14658
|
`));
|
|
14634
14659
|
}
|
|
@@ -14656,6 +14681,7 @@ var runCommand = defineCommand88({
|
|
|
14656
14681
|
}
|
|
14657
14682
|
if (e instanceof LayerExecutionError) {
|
|
14658
14683
|
const failures = e.failures.map((f) => ({ node_id: f.nodeId, message: describeFailureReason(f.reason) }));
|
|
14684
|
+
if (record) await record(buildFailedRunRecord(runId, e.message, recordMeta));
|
|
14659
14685
|
process.stderr.write(
|
|
14660
14686
|
`${JSON.stringify({ ok: false, error: { code: "runtime", message: e.message, failures } }, null, 2)}
|
|
14661
14687
|
`
|
|
@@ -14663,40 +14689,54 @@ var runCommand = defineCommand88({
|
|
|
14663
14689
|
process.exit(1);
|
|
14664
14690
|
}
|
|
14665
14691
|
const msg = e instanceof Error ? e.message : String(e);
|
|
14692
|
+
if (record) await record(buildFailedRunRecord(runId, msg, recordMeta));
|
|
14666
14693
|
process.stderr.write(`${JSON.stringify({ ok: false, error: { code: "runtime", message: msg } }, null, 2)}
|
|
14667
14694
|
`);
|
|
14668
14695
|
process.exit(1);
|
|
14669
14696
|
}
|
|
14670
14697
|
}
|
|
14671
14698
|
});
|
|
14699
|
+
function buildRecorder() {
|
|
14700
|
+
return async (payload) => {
|
|
14701
|
+
try {
|
|
14702
|
+
const creds = requireCredentialsFromEnv();
|
|
14703
|
+
const client = new BackendClient({ baseUrl: creds.url, apiKey: creds.apiKey });
|
|
14704
|
+
await client.recordRun(payload);
|
|
14705
|
+
} catch (e) {
|
|
14706
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
14707
|
+
process.stderr.write(`[warn] run record not persisted (${msg})
|
|
14708
|
+
`);
|
|
14709
|
+
}
|
|
14710
|
+
};
|
|
14711
|
+
}
|
|
14672
14712
|
|
|
14673
14713
|
// src/commands/canvas/scaffold-static-ad.ts
|
|
14674
|
-
import { readFile as readFile3, writeFile } from "fs/promises";
|
|
14675
|
-
import
|
|
14714
|
+
import { access, cp, mkdir, readFile as readFile3, writeFile } from "fs/promises";
|
|
14715
|
+
import path8 from "path";
|
|
14676
14716
|
import { defineCommand as defineCommand89 } from "citty";
|
|
14677
14717
|
|
|
14678
14718
|
// src/engine/scaffold/staticAd.ts
|
|
14679
|
-
import { z as
|
|
14719
|
+
import { z as z11 } from "zod";
|
|
14680
14720
|
var GEN_ASPECT_RATIOS = /* @__PURE__ */ new Set(["1:1", "4:5", "9:16", "16:9", "4:3", "3:4", "2:3", "3:2", "21:9"]);
|
|
14681
14721
|
var DEFAULT_ASPECT_RATIO = "9:16";
|
|
14682
|
-
var Blueprint =
|
|
14683
|
-
meta:
|
|
14684
|
-
text_content:
|
|
14722
|
+
var Blueprint = z11.object({
|
|
14723
|
+
meta: z11.object({ estimated_aspect_ratio: z11.string().optional() }).loose().optional(),
|
|
14724
|
+
text_content: z11.array(z11.object({ text: z11.string().optional() }).loose()).optional()
|
|
14685
14725
|
}).loose();
|
|
14686
|
-
var ElementLocator =
|
|
14687
|
-
collection:
|
|
14688
|
-
index:
|
|
14726
|
+
var ElementLocator = z11.object({
|
|
14727
|
+
collection: z11.enum(["subjects", "people", "brands_logos"]),
|
|
14728
|
+
index: z11.number().int().nonnegative()
|
|
14689
14729
|
}).loose();
|
|
14690
|
-
var MainElement =
|
|
14730
|
+
var MainElement = z11.object({
|
|
14691
14731
|
// logo | product | person | animal | badge | other
|
|
14692
|
-
type:
|
|
14693
|
-
label:
|
|
14694
|
-
description:
|
|
14695
|
-
expression:
|
|
14696
|
-
reason:
|
|
14732
|
+
type: z11.string(),
|
|
14733
|
+
label: z11.string().optional(),
|
|
14734
|
+
description: z11.string().optional(),
|
|
14735
|
+
expression: z11.string().nullable().optional(),
|
|
14736
|
+
reason: z11.string().optional(),
|
|
14697
14737
|
locator: ElementLocator.optional()
|
|
14698
14738
|
}).loose();
|
|
14699
|
-
var MainElements =
|
|
14739
|
+
var MainElements = z11.array(MainElement);
|
|
14700
14740
|
function sanitizeId(raw, fallback) {
|
|
14701
14741
|
const id = raw.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
14702
14742
|
return /^[a-z]/.test(id) ? id : `${fallback}_${id}`.replace(/_+$/g, "") || fallback;
|
|
@@ -14858,18 +14898,106 @@ function staticAdReport(input, elementsInput, opts) {
|
|
|
14858
14898
|
};
|
|
14859
14899
|
}
|
|
14860
14900
|
|
|
14901
|
+
// src/commands/canvas/creative-definition.ts
|
|
14902
|
+
import path6 from "path";
|
|
14903
|
+
var PLATFORM_VALUES = ["meta", "google", "linkedin", "tiktok", "youtube", "x", "other"];
|
|
14904
|
+
var FORMAT_VALUES = ["1:1", "4:5", "9:16", "16:9", "1.91:1"];
|
|
14905
|
+
function titleFromSlug(slug) {
|
|
14906
|
+
const title = slug.split("-").filter(Boolean).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
14907
|
+
return title || slug;
|
|
14908
|
+
}
|
|
14909
|
+
function resolvePlatform(platform) {
|
|
14910
|
+
const value = platform?.trim();
|
|
14911
|
+
return value && PLATFORM_VALUES.includes(value) ? value : "meta";
|
|
14912
|
+
}
|
|
14913
|
+
function resolveFormats(aspect) {
|
|
14914
|
+
const value = aspect?.trim();
|
|
14915
|
+
return value && FORMAT_VALUES.includes(value) ? [value] : ["4:5"];
|
|
14916
|
+
}
|
|
14917
|
+
function referenceRelativePath(kind, ext) {
|
|
14918
|
+
const name = kind === "video" ? "source" : "original";
|
|
14919
|
+
return `references/${name}${ext}`;
|
|
14920
|
+
}
|
|
14921
|
+
function sourceExtension(source, isUrl, kind) {
|
|
14922
|
+
const raw = isUrl ? urlPathname(source) : source;
|
|
14923
|
+
const ext = path6.extname(raw).toLowerCase();
|
|
14924
|
+
if (/^\.[a-z0-9]{1,5}$/.test(ext)) return ext;
|
|
14925
|
+
return kind === "video" ? ".mp4" : ".jpg";
|
|
14926
|
+
}
|
|
14927
|
+
function urlPathname(source) {
|
|
14928
|
+
try {
|
|
14929
|
+
return new URL(source).pathname;
|
|
14930
|
+
} catch {
|
|
14931
|
+
return source;
|
|
14932
|
+
}
|
|
14933
|
+
}
|
|
14934
|
+
function describeBlueprintIntent(blueprint) {
|
|
14935
|
+
const intent = blueprint?.ad_intent;
|
|
14936
|
+
if (typeof intent === "string" && intent.trim()) return intent.trim();
|
|
14937
|
+
if (intent && typeof intent === "object") {
|
|
14938
|
+
const summary = intent.summary ?? intent.feeling;
|
|
14939
|
+
if (typeof summary === "string" && summary.trim()) return summary.trim();
|
|
14940
|
+
}
|
|
14941
|
+
return void 0;
|
|
14942
|
+
}
|
|
14943
|
+
function yamlScalar(value) {
|
|
14944
|
+
return JSON.stringify(value);
|
|
14945
|
+
}
|
|
14946
|
+
function buildCreativeDefinition(input) {
|
|
14947
|
+
const lines = ["---", `title: ${yamlScalar(input.title)}`, `kind: ${input.kind}`, `platform: ${input.platform}`];
|
|
14948
|
+
lines.push(`formats: [${input.formats.map(yamlScalar).join(", ")}]`);
|
|
14949
|
+
lines.push(`status: ${input.status ?? "draft"}`);
|
|
14950
|
+
if (input.sourceReferenceUrl) lines.push(`sourceReferenceUrl: ${yamlScalar(input.sourceReferenceUrl)}`);
|
|
14951
|
+
if (input.sourceAdvertiser) lines.push(`sourceAdvertiser: ${yamlScalar(input.sourceAdvertiser)}`);
|
|
14952
|
+
if (input.sourceKind) lines.push(`sourceKind: ${input.sourceKind}`);
|
|
14953
|
+
if (input.sourcePath) lines.push(`sourcePath: ${yamlScalar(input.sourcePath)}`);
|
|
14954
|
+
lines.push("---", "");
|
|
14955
|
+
lines.push(input.description?.trim() || `${input.title} \u2014 canvas-built ${input.kind} ad for ${input.platform}.`);
|
|
14956
|
+
lines.push("");
|
|
14957
|
+
return lines.join("\n");
|
|
14958
|
+
}
|
|
14959
|
+
|
|
14861
14960
|
// src/commands/canvas/scaffold-static-ad-paths.ts
|
|
14862
|
-
import
|
|
14863
|
-
function resolveScaffoldStaticAdPaths(rawFile, out, cwd = process.cwd()) {
|
|
14961
|
+
import path7 from "path";
|
|
14962
|
+
function resolveScaffoldStaticAdPaths(rawFile, out, cwd = process.cwd(), slug) {
|
|
14864
14963
|
const file = rawFile.trim();
|
|
14865
14964
|
const imageIsUrl = /^https?:\/\//i.test(file);
|
|
14866
|
-
const imageSource = imageIsUrl ? file :
|
|
14867
|
-
const outPath = out ?
|
|
14868
|
-
const blueprintPath =
|
|
14869
|
-
|
|
14965
|
+
const imageSource = imageIsUrl ? file : path7.resolve(cwd, file);
|
|
14966
|
+
const outPath = out ? path7.resolve(cwd, out) : slug ? path7.join(cwd, "src", "creatives", slug, `${slug}.canvas.json`) : imageIsUrl ? path7.join(cwd, "static-ad.canvas.json") : path7.join(path7.dirname(imageSource), "static-ad.canvas.json");
|
|
14967
|
+
const blueprintPath = path7.join(path7.dirname(outPath), "prompt.json");
|
|
14968
|
+
const creativeDir = slug ? path7.dirname(outPath) : null;
|
|
14969
|
+
const definitionPath = creativeDir ? path7.join(creativeDir, "_definition.md") : null;
|
|
14970
|
+
const referencesDir = creativeDir ? path7.join(creativeDir, "references") : null;
|
|
14971
|
+
return { imageIsUrl, imageSource, outPath, blueprintPath, creativeDir, definitionPath, referencesDir };
|
|
14972
|
+
}
|
|
14973
|
+
var SCAFFOLD_SLUG_PATTERN = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;
|
|
14974
|
+
var SCAFFOLD_SLUG_MAX_LENGTH = 100;
|
|
14975
|
+
function isValidScaffoldSlug(slug) {
|
|
14976
|
+
return slug.length <= SCAFFOLD_SLUG_MAX_LENGTH && SCAFFOLD_SLUG_PATTERN.test(slug);
|
|
14870
14977
|
}
|
|
14871
14978
|
|
|
14872
14979
|
// src/commands/canvas/scaffold-static-ad.ts
|
|
14980
|
+
async function fileExists(target) {
|
|
14981
|
+
try {
|
|
14982
|
+
await access(target);
|
|
14983
|
+
return true;
|
|
14984
|
+
} catch {
|
|
14985
|
+
return false;
|
|
14986
|
+
}
|
|
14987
|
+
}
|
|
14988
|
+
async function copySourceIntoReferences(source, isUrl, referencesDir) {
|
|
14989
|
+
await mkdir(referencesDir, { recursive: true });
|
|
14990
|
+
const relPath = referenceRelativePath("image", sourceExtension(source, isUrl, "image"));
|
|
14991
|
+
const dest = path8.join(referencesDir, path8.basename(relPath));
|
|
14992
|
+
if (isUrl) {
|
|
14993
|
+
const res = await fetch(source);
|
|
14994
|
+
if (!res.ok) throw new Error(`failed to download source image (${res.status})`);
|
|
14995
|
+
await writeFile(dest, Buffer.from(await res.arrayBuffer()));
|
|
14996
|
+
} else {
|
|
14997
|
+
await cp(source, dest);
|
|
14998
|
+
}
|
|
14999
|
+
return relPath;
|
|
15000
|
+
}
|
|
14873
15001
|
function resolveModel(kind, preferred) {
|
|
14874
15002
|
const ids = Object.keys(MODEL_REGISTRY[kind]);
|
|
14875
15003
|
return ids.includes(preferred) ? preferred : ids[0] ?? preferred;
|
|
@@ -15029,6 +15157,16 @@ var scaffoldStaticAdCommand = defineCommand89({
|
|
|
15029
15157
|
file: { type: "positional", required: true, description: "Path or http(s) URL to the source/inspiration image" },
|
|
15030
15158
|
context: { type: "string", description: "Known provenance (advertiser, category, market) to ground the describe" },
|
|
15031
15159
|
out: { type: "string", description: "Output canvas path (default <image-dir>/static-ad.canvas.json)" },
|
|
15160
|
+
slug: {
|
|
15161
|
+
type: "string",
|
|
15162
|
+
description: "Creative slug \u2014 writes the canvas to src/creatives/<slug>/<slug>.canvas.json (repo convention)"
|
|
15163
|
+
},
|
|
15164
|
+
title: { type: "string", description: "Creative title for _definition.md (default: title-cased slug)" },
|
|
15165
|
+
platform: {
|
|
15166
|
+
type: "string",
|
|
15167
|
+
description: "Ad platform for _definition.md (meta|google|linkedin|tiktok|youtube|x|other; default meta)"
|
|
15168
|
+
},
|
|
15169
|
+
advertiser: { type: "string", description: "Source advertiser recorded in _definition.md" },
|
|
15032
15170
|
"describe-model": { type: "string", description: "Override the image_describe model id" },
|
|
15033
15171
|
"select-model": { type: "string", description: "Override the text_generate model id for element selection" },
|
|
15034
15172
|
"layout-model": { type: "string", description: "Override the text_generate model id for the layout pass" },
|
|
@@ -15037,10 +15175,21 @@ var scaffoldStaticAdCommand = defineCommand89({
|
|
|
15037
15175
|
"skip-font": { type: "boolean", description: "Skip the brand-font \u2192 type-specimen slot" }
|
|
15038
15176
|
},
|
|
15039
15177
|
async run({ args }) {
|
|
15040
|
-
const
|
|
15178
|
+
const slug = args.slug ? String(args.slug) : void 0;
|
|
15179
|
+
if (slug && !isValidScaffoldSlug(slug)) {
|
|
15180
|
+
process.stderr.write(
|
|
15181
|
+
`${JSON.stringify({ ok: false, error: { code: "invalid_slug", message: "--slug must be lowercase kebab (a-z, 0-9, hyphens), max 100 chars" } }, null, 2)}
|
|
15182
|
+
`
|
|
15183
|
+
);
|
|
15184
|
+
process.exit(2);
|
|
15185
|
+
}
|
|
15186
|
+
const { imageIsUrl, imageSource, outPath, blueprintPath, definitionPath, referencesDir } = resolveScaffoldStaticAdPaths(
|
|
15041
15187
|
String(args.file),
|
|
15042
|
-
args.out ? String(args.out) : void 0
|
|
15188
|
+
args.out ? String(args.out) : void 0,
|
|
15189
|
+
process.cwd(),
|
|
15190
|
+
slug
|
|
15043
15191
|
);
|
|
15192
|
+
await mkdir(path8.dirname(outPath), { recursive: true });
|
|
15044
15193
|
const { describeModel, selectModel, layoutModel, genModel } = resolveModels(args);
|
|
15045
15194
|
const describeCanvas = buildDescribeCanvas(
|
|
15046
15195
|
imageSource,
|
|
@@ -15057,11 +15206,21 @@ var scaffoldStaticAdCommand = defineCommand89({
|
|
|
15057
15206
|
}
|
|
15058
15207
|
await writeFile(blueprintPath, `${JSON.stringify(annotated, null, 2)}
|
|
15059
15208
|
`, "utf8");
|
|
15209
|
+
let canvasImagePath = imageSource;
|
|
15210
|
+
let canvasImageIsUrl = imageIsUrl;
|
|
15211
|
+
let canvasBlueprintPath = blueprintPath;
|
|
15212
|
+
let sourceRelPath;
|
|
15213
|
+
if (referencesDir) {
|
|
15214
|
+
sourceRelPath = await copySourceIntoReferences(imageSource, imageIsUrl, referencesDir);
|
|
15215
|
+
canvasImagePath = sourceRelPath;
|
|
15216
|
+
canvasImageIsUrl = false;
|
|
15217
|
+
canvasBlueprintPath = "./prompt.json";
|
|
15218
|
+
}
|
|
15060
15219
|
const opts = {
|
|
15061
15220
|
genModel,
|
|
15062
|
-
imagePath:
|
|
15063
|
-
imageIsUrl,
|
|
15064
|
-
blueprintPath,
|
|
15221
|
+
imagePath: canvasImagePath,
|
|
15222
|
+
imageIsUrl: canvasImageIsUrl,
|
|
15223
|
+
blueprintPath: canvasBlueprintPath,
|
|
15065
15224
|
aspectRatio: args.aspect ? String(args.aspect) : void 0,
|
|
15066
15225
|
includeFont: !args["skip-font"]
|
|
15067
15226
|
};
|
|
@@ -15083,12 +15242,31 @@ var scaffoldStaticAdCommand = defineCommand89({
|
|
|
15083
15242
|
}
|
|
15084
15243
|
await writeFile(outPath, `${JSON.stringify(canvas, null, 2)}
|
|
15085
15244
|
`, "utf8");
|
|
15245
|
+
if (definitionPath && !await fileExists(definitionPath)) {
|
|
15246
|
+
await writeFile(
|
|
15247
|
+
definitionPath,
|
|
15248
|
+
buildCreativeDefinition({
|
|
15249
|
+
title: args.title ? String(args.title) : titleFromSlug(slug ?? ""),
|
|
15250
|
+
kind: "static",
|
|
15251
|
+
platform: resolvePlatform(args.platform ? String(args.platform) : void 0),
|
|
15252
|
+
formats: resolveFormats(args.aspect ? String(args.aspect) : report.aspect_ratio),
|
|
15253
|
+
sourceReferenceUrl: imageIsUrl ? imageSource : void 0,
|
|
15254
|
+
sourceAdvertiser: args.advertiser ? String(args.advertiser) : args.context ? String(args.context) : void 0,
|
|
15255
|
+
sourceKind: "image",
|
|
15256
|
+
sourcePath: sourceRelPath,
|
|
15257
|
+
description: describeBlueprintIntent(blueprint)
|
|
15258
|
+
}),
|
|
15259
|
+
"utf8"
|
|
15260
|
+
);
|
|
15261
|
+
}
|
|
15086
15262
|
process.stdout.write(
|
|
15087
15263
|
`${JSON.stringify(
|
|
15088
15264
|
{
|
|
15089
15265
|
ok: true,
|
|
15090
15266
|
canvas_path: outPath,
|
|
15091
15267
|
prompt_path: blueprintPath,
|
|
15268
|
+
definition_path: definitionPath ?? void 0,
|
|
15269
|
+
source_reference: sourceRelPath ?? void 0,
|
|
15092
15270
|
output: canvas.output,
|
|
15093
15271
|
models: { describe: describeModel, select: selectModel, layout: layoutModel, gen: opts.genModel },
|
|
15094
15272
|
aspect_ratio: report.aspect_ratio,
|
|
@@ -15099,7 +15277,7 @@ var scaffoldStaticAdCommand = defineCommand89({
|
|
|
15099
15277
|
run_estimated_credits: validation.estimatedCredits
|
|
15100
15278
|
},
|
|
15101
15279
|
checklist: {
|
|
15102
|
-
edit_prompt: `Edit ${
|
|
15280
|
+
edit_prompt: `Edit ${path8.basename(blueprintPath)} \u2014 it is the blueprint generated from your image; rewrite it into the ad you want (palette, copy, claims, subjects). It feeds the generator directly.`,
|
|
15103
15281
|
assets_to_supply: report.elements,
|
|
15104
15282
|
font_slot: report.includes_font ? "Drop a brand font at the [TODO] brandfont path, or delete the brandfont + type_ref nodes to skip it." : "skipped (--skip-font)",
|
|
15105
15283
|
note: "Replace every [TODO] ingest path with a real file, then `baker canvas validate` and `baker canvas run`. Running generates a billed image \u2014 it is not free."
|
|
@@ -15114,8 +15292,8 @@ var scaffoldStaticAdCommand = defineCommand89({
|
|
|
15114
15292
|
});
|
|
15115
15293
|
|
|
15116
15294
|
// src/commands/canvas/scaffold-video.ts
|
|
15117
|
-
import { cp, mkdir, readFile as readFile6, writeFile as writeFile2 } from "fs/promises";
|
|
15118
|
-
import
|
|
15295
|
+
import { cp as cp2, mkdir as mkdir2, readFile as readFile6, writeFile as writeFile2 } from "fs/promises";
|
|
15296
|
+
import path11 from "path";
|
|
15119
15297
|
import { defineCommand as defineCommand90 } from "citty";
|
|
15120
15298
|
|
|
15121
15299
|
// src/engine/nodes/local/lib/sceneDetect.ts
|
|
@@ -15232,7 +15410,7 @@ import { toCardinal as nwKo } from "n2words/ko-KR";
|
|
|
15232
15410
|
import { toCardinal as nwNl } from "n2words/nl-NL";
|
|
15233
15411
|
import { toCardinal as nwPl } from "n2words/pl-PL";
|
|
15234
15412
|
import { toCardinal as nwPt } from "n2words/pt-PT";
|
|
15235
|
-
import { z as
|
|
15413
|
+
import { z as z12 } from "zod";
|
|
15236
15414
|
|
|
15237
15415
|
// src/engine/scaffold/lib/shoot-modes.ts
|
|
15238
15416
|
var SHOOT_MODES = [
|
|
@@ -15545,71 +15723,71 @@ function trimArgs(durationS, offsetS = 0, dims) {
|
|
|
15545
15723
|
"{{out.video}}"
|
|
15546
15724
|
];
|
|
15547
15725
|
}
|
|
15548
|
-
var FrameAsset =
|
|
15549
|
-
var DialogueLine =
|
|
15550
|
-
speaker:
|
|
15551
|
-
line:
|
|
15726
|
+
var FrameAsset = z12.object({ url: z12.string().optional() }).loose().optional();
|
|
15727
|
+
var DialogueLine = z12.object({
|
|
15728
|
+
speaker: z12.string().optional(),
|
|
15729
|
+
line: z12.string().optional(),
|
|
15552
15730
|
// Absolute seconds on the source timeline (the deconstruct emits both).
|
|
15553
|
-
start_s:
|
|
15554
|
-
end_s:
|
|
15555
|
-
delivery:
|
|
15556
|
-
voice_description:
|
|
15731
|
+
start_s: z12.number().optional(),
|
|
15732
|
+
end_s: z12.number().optional(),
|
|
15733
|
+
delivery: z12.string().optional(),
|
|
15734
|
+
voice_description: z12.string().optional(),
|
|
15557
15735
|
// DECON-supplied: is this speaker's FACE visibly speaking in THIS scene? Element
|
|
15558
15736
|
// presence alone can't answer that — a founder pictured in a polaroid close-up is
|
|
15559
15737
|
// "present" yet the line is voiceover, and treating it as on-camera produced a
|
|
15560
15738
|
// native Seedance lip-sync clip of a still photograph. `false` pins the line to
|
|
15561
15739
|
// the VO path; absent keeps the presence-based decision (old blueprints).
|
|
15562
|
-
on_camera:
|
|
15740
|
+
on_camera: z12.boolean().optional()
|
|
15563
15741
|
}).loose();
|
|
15564
|
-
var Sfx =
|
|
15565
|
-
at_s:
|
|
15566
|
-
duration_s:
|
|
15567
|
-
sound_effect_prompt:
|
|
15568
|
-
description:
|
|
15742
|
+
var Sfx = z12.object({
|
|
15743
|
+
at_s: z12.number().optional(),
|
|
15744
|
+
duration_s: z12.number().optional(),
|
|
15745
|
+
sound_effect_prompt: z12.string().optional(),
|
|
15746
|
+
description: z12.string().optional()
|
|
15569
15747
|
}).loose();
|
|
15570
|
-
var CompositionRegion =
|
|
15748
|
+
var CompositionRegion = z12.object({
|
|
15571
15749
|
// full | top | bottom | left | right | inset
|
|
15572
|
-
panel:
|
|
15750
|
+
panel: z12.string().optional(),
|
|
15573
15751
|
// 9-grid anchor for an `inset` presenter box.
|
|
15574
|
-
position:
|
|
15575
|
-
is_presenter:
|
|
15752
|
+
position: z12.string().optional(),
|
|
15753
|
+
is_presenter: z12.boolean().optional(),
|
|
15576
15754
|
// The cast id shown/speaking in this region (routes lip-sync + element refs).
|
|
15577
|
-
cast_ref:
|
|
15755
|
+
cast_ref: z12.string().optional(),
|
|
15578
15756
|
// What the region's content IS: camera | screen_capture | static_graphic |
|
|
15579
15757
|
// generated. Authoritative for routing when present (regex-over-prose fallback
|
|
15580
15758
|
// otherwise): screen_capture/static_graphic are rebuilt from REAL surfaces on the
|
|
15581
15759
|
// overlay layer, never AI-generated.
|
|
15582
|
-
kind:
|
|
15760
|
+
kind: z12.string().optional(),
|
|
15583
15761
|
// Opaque id naming the SPECIFIC on-screen document/note/app-state this
|
|
15584
15762
|
// screen_capture region shows. Two scenes share it only when they show the SAME
|
|
15585
15763
|
// recording continuing (scrolling/typing/waiting within it) — a genuinely
|
|
15586
15764
|
// DIFFERENT document/note/recording (a source video splicing two screen captures)
|
|
15587
15765
|
// gets a different id. Breaks a persistent-layout run into separate surface stubs
|
|
15588
15766
|
// instead of asking the operator for one screenshot that can't cover both.
|
|
15589
|
-
surface_id:
|
|
15767
|
+
surface_id: z12.string().optional(),
|
|
15590
15768
|
// Camera bubble(s)/inset(s) embedded INSIDE this region's surface (a Loom-style
|
|
15591
15769
|
// presenter bubble inside a screen recording) — video-in-video the reproduction
|
|
15592
15770
|
// must re-composite, not paint into the surface.
|
|
15593
|
-
nested:
|
|
15594
|
-
summary:
|
|
15595
|
-
frame_prompt:
|
|
15596
|
-
motion_prompt:
|
|
15771
|
+
nested: z12.array(z12.object({}).loose()).optional(),
|
|
15772
|
+
summary: z12.string().optional(),
|
|
15773
|
+
frame_prompt: z12.string().optional(),
|
|
15774
|
+
motion_prompt: z12.string().optional()
|
|
15597
15775
|
}).loose();
|
|
15598
|
-
var SceneComposition =
|
|
15776
|
+
var SceneComposition = z12.object({
|
|
15599
15777
|
// full_frame (default) | split_screen | pip | keyed_overlay
|
|
15600
|
-
layout:
|
|
15778
|
+
layout: z12.string().optional(),
|
|
15601
15779
|
// split_screen only: vertical (top/bottom) | horizontal (left/right).
|
|
15602
|
-
split_axis:
|
|
15603
|
-
regions:
|
|
15780
|
+
split_axis: z12.string().optional(),
|
|
15781
|
+
regions: z12.array(CompositionRegion).optional()
|
|
15604
15782
|
}).loose();
|
|
15605
|
-
var CameraMotion =
|
|
15606
|
-
var TranscriptWord =
|
|
15607
|
-
var Scene =
|
|
15608
|
-
start_s:
|
|
15609
|
-
end_s:
|
|
15610
|
-
duration_s:
|
|
15611
|
-
summary:
|
|
15612
|
-
action_detail:
|
|
15783
|
+
var CameraMotion = z12.object({ movement: z12.string().optional(), detail: z12.string().optional() }).loose();
|
|
15784
|
+
var TranscriptWord = z12.object({ text: z12.string().optional() }).loose();
|
|
15785
|
+
var Scene = z12.object({
|
|
15786
|
+
start_s: z12.number().optional(),
|
|
15787
|
+
end_s: z12.number().optional(),
|
|
15788
|
+
duration_s: z12.number().optional(),
|
|
15789
|
+
summary: z12.string().optional(),
|
|
15790
|
+
action_detail: z12.string().optional(),
|
|
15613
15791
|
// The scene's spatial layout. Absent/full_frame ⇒ one uncut shot (default path).
|
|
15614
15792
|
// A layered layout (split_screen/pip/keyed_overlay) with regions ⇒ the scaffold
|
|
15615
15793
|
// builds one clip per region and stacks/overlays them into the scene picture.
|
|
@@ -15617,82 +15795,82 @@ var Scene = z13.object({
|
|
|
15617
15795
|
// The capture "look" for this scene — selected from the ad-native shoot-mode
|
|
15618
15796
|
// grammar (see lib/shoot-modes.ts). When absent the scaffold auto-derives a
|
|
15619
15797
|
// UGC/product mode; a human can override per scene by setting this.
|
|
15620
|
-
shoot_mode:
|
|
15798
|
+
shoot_mode: z12.string().optional(),
|
|
15621
15799
|
// Diegetic ambient the clip's native audio should carry (no music). When
|
|
15622
15800
|
// absent the scene falls back to its shoot mode's default ambience.
|
|
15623
|
-
ambient:
|
|
15801
|
+
ambient: z12.string().optional(),
|
|
15624
15802
|
camera_motion: CameraMotion.optional(),
|
|
15625
|
-
start_frame_prompt:
|
|
15626
|
-
end_frame_prompt:
|
|
15627
|
-
motion_prompt:
|
|
15803
|
+
start_frame_prompt: z12.string().optional(),
|
|
15804
|
+
end_frame_prompt: z12.string().optional(),
|
|
15805
|
+
motion_prompt: z12.string().optional(),
|
|
15628
15806
|
// The scene's role in the ad's persuasion arc (DECON-supplied); drives the
|
|
15629
15807
|
// script re-craft checklist. Inferred from position when absent.
|
|
15630
|
-
narrative_role:
|
|
15808
|
+
narrative_role: z12.string().optional(),
|
|
15631
15809
|
// DECON-supplied on the HOOK scene: the engineered physical/emotional state that
|
|
15632
15810
|
// makes the first frame stop the scroll (sweaty/breathless/urgent …). Injected
|
|
15633
15811
|
// into the hook's start-frame description so the generator renders that state,
|
|
15634
15812
|
// not a calm influencer (CCA-11).
|
|
15635
|
-
hook_mechanic:
|
|
15813
|
+
hook_mechanic: z12.object({ mechanic: z12.string().optional(), why_it_stops_scroll: z12.string().optional() }).loose().optional(),
|
|
15636
15814
|
// DECON-supplied per-scene location (so a gym hook isn't flattened to "home").
|
|
15637
|
-
scene_setting:
|
|
15815
|
+
scene_setting: z12.string().optional(),
|
|
15638
15816
|
// How this scene cuts to the next (DECON-supplied). A recognized non-cut type
|
|
15639
15817
|
// (fade/whip/zoom/dissolve/swipe) is reproduced as an ffmpeg xfade at the
|
|
15640
15818
|
// boundary; cut/match_cut/none/other stay hard cuts. The last scene's value is
|
|
15641
15819
|
// ignored (nothing follows it).
|
|
15642
|
-
transition_out:
|
|
15643
|
-
dialogue:
|
|
15644
|
-
sfx:
|
|
15645
|
-
overlays:
|
|
15646
|
-
floating_elements:
|
|
15820
|
+
transition_out: z12.object({ type: z12.string().optional(), description: z12.string().optional() }).loose().optional(),
|
|
15821
|
+
dialogue: z12.array(DialogueLine).optional(),
|
|
15822
|
+
sfx: z12.array(Sfx).optional(),
|
|
15823
|
+
overlays: z12.array(z12.unknown()).optional(),
|
|
15824
|
+
floating_elements: z12.array(z12.unknown()).optional(),
|
|
15647
15825
|
// DECON-supplied: how much the picture itself moves within the shot. Gates the
|
|
15648
15826
|
// flash-hold optimization — a sub-2s b-roll flash with REAL subject motion
|
|
15649
15827
|
// (pouring, spreading, hands working) must stay a real clip; freezing it turns
|
|
15650
15828
|
// a montage into a slideshow. Absent (old blueprints) keeps the cheap still.
|
|
15651
|
-
motion_level:
|
|
15652
|
-
transcript_slice:
|
|
15829
|
+
motion_level: z12.enum(["static", "subtle", "dynamic"]).optional(),
|
|
15830
|
+
transcript_slice: z12.array(TranscriptWord).optional(),
|
|
15653
15831
|
start_frame_asset: FrameAsset,
|
|
15654
15832
|
end_frame_asset: FrameAsset,
|
|
15655
15833
|
// DECON-supplied: true when this scene is a length-split CONTINUATION of the
|
|
15656
15834
|
// previous one (the SAME physical shot, broken up only because it exceeded the
|
|
15657
15835
|
// clip ceiling). The scaffold then shares the splice keyframe — this scene's
|
|
15658
15836
|
// start frame IS the previous scene's end frame — so the join is seamless.
|
|
15659
|
-
continues_previous:
|
|
15837
|
+
continues_previous: z12.boolean().optional()
|
|
15660
15838
|
}).loose();
|
|
15661
|
-
var VideoBlueprint =
|
|
15662
|
-
source:
|
|
15663
|
-
global:
|
|
15664
|
-
music:
|
|
15665
|
-
present:
|
|
15666
|
-
music_prompt:
|
|
15839
|
+
var VideoBlueprint = z12.object({
|
|
15840
|
+
source: z12.object({ aspect_ratio: z12.string().optional(), duration_s: z12.number().optional() }).loose().optional(),
|
|
15841
|
+
global: z12.object({
|
|
15842
|
+
music: z12.object({
|
|
15843
|
+
present: z12.boolean().optional(),
|
|
15844
|
+
music_prompt: z12.string().optional(),
|
|
15667
15845
|
// Absolute second the music enters in the reference (the bed often
|
|
15668
15846
|
// kicks in mid-ad, after the hook). We start the regenerated track here
|
|
15669
15847
|
// instead of at 0 so the timing matches.
|
|
15670
|
-
starts_at_s:
|
|
15848
|
+
starts_at_s: z12.number().optional(),
|
|
15671
15849
|
// Populated by the deconstruct when AudD (Shazam-style) recognizes the
|
|
15672
15850
|
// reference track. We never reuse it — only style the regenerated bed.
|
|
15673
|
-
identified_track:
|
|
15851
|
+
identified_track: z12.object({ title: z12.string().optional(), artist: z12.string().optional() }).loose().nullish()
|
|
15674
15852
|
}).loose().optional(),
|
|
15675
|
-
cast:
|
|
15676
|
-
|
|
15677
|
-
id:
|
|
15678
|
-
description:
|
|
15853
|
+
cast: z12.array(
|
|
15854
|
+
z12.object({
|
|
15855
|
+
id: z12.string().optional(),
|
|
15856
|
+
description: z12.string().optional(),
|
|
15679
15857
|
// The deconstruct's note on the target-market localization (e.g. "native
|
|
15680
15858
|
// French speaker") — read to derive the spoken-track language code.
|
|
15681
|
-
market_localization_note:
|
|
15859
|
+
market_localization_note: z12.string().optional()
|
|
15682
15860
|
}).loose()
|
|
15683
15861
|
).optional(),
|
|
15684
|
-
voiceover:
|
|
15862
|
+
voiceover: z12.object({
|
|
15685
15863
|
// on_camera | mixed → mouths are on screen (lip-sync candidates);
|
|
15686
15864
|
// voiceover | none → narration over the picture (no lip-sync).
|
|
15687
|
-
mode:
|
|
15688
|
-
voice_description:
|
|
15689
|
-
persona:
|
|
15865
|
+
mode: z12.string().optional(),
|
|
15866
|
+
voice_description: z12.string().optional(),
|
|
15867
|
+
persona: z12.string().optional()
|
|
15690
15868
|
}).loose().optional(),
|
|
15691
15869
|
// Visual palette — read only to colour a clean brand-card/CTA plate (the
|
|
15692
15870
|
// first hex is the dominant brand colour); never to drive frame generation.
|
|
15693
|
-
style:
|
|
15871
|
+
style: z12.object({ palette: z12.array(z12.object({ hex: z12.string().optional() }).loose()).optional() }).loose().optional()
|
|
15694
15872
|
}).loose().optional(),
|
|
15695
|
-
scenes:
|
|
15873
|
+
scenes: z12.array(Scene).min(1)
|
|
15696
15874
|
}).loose();
|
|
15697
15875
|
function injectHookPhysicality(blueprint) {
|
|
15698
15876
|
for (const scene of blueprint.scenes) {
|
|
@@ -15702,26 +15880,26 @@ function injectHookPhysicality(blueprint) {
|
|
|
15702
15880
|
scene.start_frame_prompt = `${prompt} The subject's physical state IS the scroll-stopper \u2014 render it explicitly, not a calm pose: ${why}.`;
|
|
15703
15881
|
}
|
|
15704
15882
|
}
|
|
15705
|
-
var AppearsItem =
|
|
15706
|
-
var RecurringElement =
|
|
15883
|
+
var AppearsItem = z12.union([z12.number(), z12.object({ scene: z12.number(), edge: z12.string().optional() }).loose()]);
|
|
15884
|
+
var RecurringElement = z12.object({
|
|
15707
15885
|
// person | animal | product | logo | badge | other
|
|
15708
|
-
type:
|
|
15709
|
-
label:
|
|
15710
|
-
description:
|
|
15711
|
-
expression:
|
|
15886
|
+
type: z12.string(),
|
|
15887
|
+
label: z12.string().optional(),
|
|
15888
|
+
description: z12.string().optional(),
|
|
15889
|
+
expression: z12.string().nullable().optional(),
|
|
15712
15890
|
// When the element maps to a global cast entry, its stable id (for annotation).
|
|
15713
|
-
cast_id:
|
|
15891
|
+
cast_id: z12.string().nullable().optional(),
|
|
15714
15892
|
// The label of another element that is the SAME individual as this one, shown
|
|
15715
15893
|
// in a DIFFERENT wardrobe/persona/state (e.g. one creator playing skeptic in a
|
|
15716
15894
|
// pink shirt and believer in a white shirt). Each look gets its own reference
|
|
15717
15895
|
// slot, but the face/identity must stay identical across them.
|
|
15718
|
-
same_as:
|
|
15896
|
+
same_as: z12.string().nullable().optional(),
|
|
15719
15897
|
// Scenes the element appears in. Either a bare list of scene indices (both
|
|
15720
15898
|
// edges) or per-{scene,edge} entries. Both forms are accepted and merged.
|
|
15721
|
-
scenes:
|
|
15722
|
-
appears_in:
|
|
15899
|
+
scenes: z12.array(z12.number()).optional(),
|
|
15900
|
+
appears_in: z12.array(AppearsItem).optional()
|
|
15723
15901
|
}).loose();
|
|
15724
|
-
var RecurringElements =
|
|
15902
|
+
var RecurringElements = z12.array(RecurringElement);
|
|
15725
15903
|
function sanitizeId2(raw, fallback) {
|
|
15726
15904
|
const id = raw.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
15727
15905
|
return /^[a-z]/.test(id) ? id : `${fallback}_${id}`.replace(/_+$/g, "") || fallback;
|
|
@@ -16139,7 +16317,7 @@ function scrubFloatSentences(text, floatDescs) {
|
|
|
16139
16317
|
return kept;
|
|
16140
16318
|
}
|
|
16141
16319
|
function sceneFloatDescs(scene) {
|
|
16142
|
-
const floats =
|
|
16320
|
+
const floats = z12.array(FloatingElement).safeParse(scene.floating_elements ?? []);
|
|
16143
16321
|
if (!floats.success) return [];
|
|
16144
16322
|
return floats.data.map((f) => f.description?.trim() ?? "").filter(Boolean);
|
|
16145
16323
|
}
|
|
@@ -17479,25 +17657,25 @@ function buildSfxMusic(blueprint, nodes) {
|
|
|
17479
17657
|
}
|
|
17480
17658
|
return tracks;
|
|
17481
17659
|
}
|
|
17482
|
-
var OverlayStyle =
|
|
17483
|
-
var Overlay =
|
|
17484
|
-
text:
|
|
17485
|
-
appears_at_s:
|
|
17486
|
-
duration_s:
|
|
17487
|
-
position:
|
|
17488
|
-
role:
|
|
17489
|
-
animation:
|
|
17490
|
-
animation_detail:
|
|
17660
|
+
var OverlayStyle = z12.object({ color_hex: z12.string().optional(), background: z12.string().optional(), size: z12.string().optional() }).loose();
|
|
17661
|
+
var Overlay = z12.object({
|
|
17662
|
+
text: z12.string().optional(),
|
|
17663
|
+
appears_at_s: z12.number().optional(),
|
|
17664
|
+
duration_s: z12.number().optional(),
|
|
17665
|
+
position: z12.string().optional(),
|
|
17666
|
+
role: z12.string().optional(),
|
|
17667
|
+
animation: z12.string().optional(),
|
|
17668
|
+
animation_detail: z12.string().optional(),
|
|
17491
17669
|
style: OverlayStyle.optional()
|
|
17492
17670
|
}).loose();
|
|
17493
|
-
var FloatingElement =
|
|
17494
|
-
kind:
|
|
17495
|
-
description:
|
|
17496
|
-
brand_name:
|
|
17497
|
-
what_it_represents:
|
|
17498
|
-
appears_at_s:
|
|
17499
|
-
duration_s:
|
|
17500
|
-
position:
|
|
17671
|
+
var FloatingElement = z12.object({
|
|
17672
|
+
kind: z12.string().optional(),
|
|
17673
|
+
description: z12.string().optional(),
|
|
17674
|
+
brand_name: z12.string().nullish(),
|
|
17675
|
+
what_it_represents: z12.string().optional(),
|
|
17676
|
+
appears_at_s: z12.number().optional(),
|
|
17677
|
+
duration_s: z12.number().optional(),
|
|
17678
|
+
position: z12.string().optional()
|
|
17501
17679
|
}).loose();
|
|
17502
17680
|
function escapeHtml(s) {
|
|
17503
17681
|
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
@@ -17529,7 +17707,7 @@ function positionClass(position) {
|
|
|
17529
17707
|
function collectCaptions(blueprint) {
|
|
17530
17708
|
return blueprint.scenes.flatMap((scene) => {
|
|
17531
17709
|
const sceneStart = scene.start_s ?? 0;
|
|
17532
|
-
const overlays =
|
|
17710
|
+
const overlays = z12.array(Overlay).safeParse(scene.overlays ?? []);
|
|
17533
17711
|
return overlays.success ? overlays.data.filter((ov) => Boolean(ov.text?.trim())).map((ov) => {
|
|
17534
17712
|
const at = ov.appears_at_s ?? sceneStart;
|
|
17535
17713
|
return { text: ov.text.trim(), at, end: at + (ov.duration_s ?? 2.5), ov };
|
|
@@ -17609,7 +17787,7 @@ function collectFloatWindows(blueprint, uiRouted) {
|
|
|
17609
17787
|
const windows = /* @__PURE__ */ new Map();
|
|
17610
17788
|
blueprint.scenes.forEach((scene, i) => {
|
|
17611
17789
|
const sceneStart = scene.start_s ?? 0;
|
|
17612
|
-
const floats =
|
|
17790
|
+
const floats = z12.array(FloatingElement).safeParse(scene.floating_elements ?? []);
|
|
17613
17791
|
if (!floats.success) return;
|
|
17614
17792
|
for (const fe of floats.data) {
|
|
17615
17793
|
const at = fe.appears_at_s ?? sceneStart;
|
|
@@ -17995,8 +18173,8 @@ function buildMotionBoard(blueprint) {
|
|
|
17995
18173
|
const end_s = scene.end_s ?? start_s + sceneDurationS(scene);
|
|
17996
18174
|
cursor = end_s;
|
|
17997
18175
|
const spoken = sceneSpokenText(scene);
|
|
17998
|
-
const overlays =
|
|
17999
|
-
const floats =
|
|
18176
|
+
const overlays = z12.array(Overlay).safeParse(scene.overlays ?? []);
|
|
18177
|
+
const floats = z12.array(FloatingElement).safeParse(scene.floating_elements ?? []);
|
|
18000
18178
|
const graphics = [
|
|
18001
18179
|
...(overlays.success ? overlays.data : []).filter((ov) => ov.text?.trim()).map((ov) => ({
|
|
18002
18180
|
kind: "text",
|
|
@@ -18223,23 +18401,23 @@ function videoReport(input, elementsInput) {
|
|
|
18223
18401
|
|
|
18224
18402
|
// src/commands/canvas/composition-path.ts
|
|
18225
18403
|
import { existsSync as existsSync3 } from "fs";
|
|
18226
|
-
import
|
|
18404
|
+
import path9 from "path";
|
|
18227
18405
|
function resolveShippedCanvasDir(name, startDir, exists = existsSync3, maxDepth = 8) {
|
|
18228
|
-
const rel =
|
|
18406
|
+
const rel = path9.join("canvas", name);
|
|
18229
18407
|
let dir = startDir;
|
|
18230
18408
|
for (let i = 0; i < maxDepth; i++) {
|
|
18231
|
-
const candidate =
|
|
18232
|
-
if (exists(
|
|
18233
|
-
const parent =
|
|
18409
|
+
const candidate = path9.join(dir, rel);
|
|
18410
|
+
if (exists(path9.join(candidate, "meta.json"))) return candidate;
|
|
18411
|
+
const parent = path9.dirname(dir);
|
|
18234
18412
|
if (parent === dir) break;
|
|
18235
18413
|
dir = parent;
|
|
18236
18414
|
}
|
|
18237
|
-
return
|
|
18415
|
+
return path9.resolve(startDir, "../../../", rel);
|
|
18238
18416
|
}
|
|
18239
18417
|
|
|
18240
18418
|
// src/commands/canvas/gitignore.ts
|
|
18241
18419
|
import { appendFile, readFile as readFile5 } from "fs/promises";
|
|
18242
|
-
import
|
|
18420
|
+
import path10 from "path";
|
|
18243
18421
|
function missingGitignoreEntries(existing, entries) {
|
|
18244
18422
|
const present = new Set(
|
|
18245
18423
|
existing.split("\n").map((l) => l.trim().replace(/\/+$/, "")).filter((l) => l.length > 0 && !l.startsWith("#"))
|
|
@@ -18247,7 +18425,7 @@ function missingGitignoreEntries(existing, entries) {
|
|
|
18247
18425
|
return entries.filter((e) => !present.has(e.trim().replace(/\/+$/, "")));
|
|
18248
18426
|
}
|
|
18249
18427
|
async function ensureGitignore(dir, entries) {
|
|
18250
|
-
const file =
|
|
18428
|
+
const file = path10.join(dir, ".gitignore");
|
|
18251
18429
|
let existing;
|
|
18252
18430
|
try {
|
|
18253
18431
|
existing = await readFile5(file, "utf8");
|
|
@@ -18308,8 +18486,8 @@ async function loadTranscriptBestEffort(ref) {
|
|
|
18308
18486
|
async function stageCaptions(outDir, transcript) {
|
|
18309
18487
|
const text = transcript?.trim();
|
|
18310
18488
|
if (!text || text === "[]") return {};
|
|
18311
|
-
const compositionPath =
|
|
18312
|
-
await
|
|
18489
|
+
const compositionPath = path11.join(outDir, "tiktok-captions-composition");
|
|
18490
|
+
await cp2(SHIPPED_CAPTIONS_DIR, compositionPath, { recursive: true });
|
|
18313
18491
|
return { compositionPath };
|
|
18314
18492
|
}
|
|
18315
18493
|
function patchCompositionMeta(metaJson, dims) {
|
|
@@ -18326,10 +18504,10 @@ function patchCompositionHtml(html, dims) {
|
|
|
18326
18504
|
return html.replace(/(<meta\s+name="viewport"\s+content="width=)\d+(,\s*height=)\d+(")/i, `$1${dims.w}$2${dims.h}$3`).replace(/(width:\s*)\d+(px;\s*height:\s*)\d+(px;)/i, `$1${dims.w}$2${dims.h}$3`).replace(/(data-width=")\d+(")/i, `$1${dims.w}$2`).replace(/(data-height=")\d+(")/i, `$1${dims.h}$2`);
|
|
18327
18505
|
}
|
|
18328
18506
|
async function stampCompositionDims(compositionDir, dims) {
|
|
18329
|
-
const metaPath =
|
|
18507
|
+
const metaPath = path11.join(compositionDir, "meta.json");
|
|
18330
18508
|
const rawMeta = await readFile6(metaPath, "utf8");
|
|
18331
18509
|
await writeFile2(metaPath, patchCompositionMeta(rawMeta, dims), "utf8");
|
|
18332
|
-
const htmlPath =
|
|
18510
|
+
const htmlPath = path11.join(compositionDir, "index.html");
|
|
18333
18511
|
const rawHtml = await readFile6(htmlPath, "utf8");
|
|
18334
18512
|
await writeFile2(htmlPath, patchCompositionHtml(rawHtml, dims), "utf8");
|
|
18335
18513
|
}
|
|
@@ -18469,6 +18647,10 @@ var scaffoldVideoCommand = defineCommand90({
|
|
|
18469
18647
|
args: {
|
|
18470
18648
|
file: { type: "positional", required: true, description: "Path to the reference video" },
|
|
18471
18649
|
out: { type: "string", description: "Output canvas path (default <video-dir>/<name>.video.canvas.json)" },
|
|
18650
|
+
slug: {
|
|
18651
|
+
type: "string",
|
|
18652
|
+
description: "Creative slug \u2014 writes the canvas to src/creatives/<slug>/<slug>.canvas.json (repo convention)"
|
|
18653
|
+
},
|
|
18472
18654
|
frames: { type: "string", description: '"generate" (default, anchored regen) or "reuse" (wire real frames in)' },
|
|
18473
18655
|
ambient: {
|
|
18474
18656
|
type: "boolean",
|
|
@@ -18495,11 +18677,19 @@ var scaffoldVideoCommand = defineCommand90({
|
|
|
18495
18677
|
}
|
|
18496
18678
|
},
|
|
18497
18679
|
async run({ args }) {
|
|
18498
|
-
const videoPath =
|
|
18499
|
-
const base =
|
|
18500
|
-
const
|
|
18501
|
-
|
|
18502
|
-
|
|
18680
|
+
const videoPath = path11.resolve(String(args.file));
|
|
18681
|
+
const base = path11.basename(videoPath, path11.extname(videoPath));
|
|
18682
|
+
const slug = args.slug ? String(args.slug) : void 0;
|
|
18683
|
+
if (slug && !isValidScaffoldSlug(slug)) {
|
|
18684
|
+
process.stderr.write(
|
|
18685
|
+
`${JSON.stringify({ ok: false, error: { code: "invalid_slug", message: "--slug must be lowercase kebab (a-z, 0-9, hyphens), max 100 chars" } }, null, 2)}
|
|
18686
|
+
`
|
|
18687
|
+
);
|
|
18688
|
+
process.exit(2);
|
|
18689
|
+
}
|
|
18690
|
+
const outPath = args.out ? path11.resolve(String(args.out)) : slug ? path11.join(process.cwd(), "src", "creatives", slug, `${slug}.canvas.json`) : path11.join(path11.dirname(videoPath), `${base}.video.canvas.json`);
|
|
18691
|
+
const outDir = path11.dirname(outPath);
|
|
18692
|
+
const blueprintPath = path11.join(outDir, "prompt.json");
|
|
18503
18693
|
const frames = args.frames === "reuse" ? "reuse" : "generate";
|
|
18504
18694
|
const maxScenes = args["max-scenes"] ? Number(args["max-scenes"]) : void 0;
|
|
18505
18695
|
if (Number.isFinite(maxScenes)) {
|
|
@@ -18518,7 +18708,7 @@ var scaffoldVideoCommand = defineCommand90({
|
|
|
18518
18708
|
shotCuts
|
|
18519
18709
|
});
|
|
18520
18710
|
const { blueprint, elements, transcript, creditsSpent } = await runAnalysisPasses(deconstructCanvas, selectModel);
|
|
18521
|
-
await
|
|
18711
|
+
await mkdir2(outDir, { recursive: true });
|
|
18522
18712
|
const annotated = annotateBlueprintWithElements(blueprint, elements);
|
|
18523
18713
|
await writeFile2(blueprintPath, `${JSON.stringify(annotated, null, 2)}
|
|
18524
18714
|
`, "utf8");
|
|
@@ -18539,10 +18729,10 @@ var scaffoldVideoCommand = defineCommand90({
|
|
|
18539
18729
|
`
|
|
18540
18730
|
);
|
|
18541
18731
|
}
|
|
18542
|
-
const compositionDest =
|
|
18543
|
-
await
|
|
18732
|
+
const compositionDest = path11.join(outDir, "video-overlay-composition");
|
|
18733
|
+
await cp2(SHIPPED_COMPOSITION_DIR, compositionDest, { recursive: true });
|
|
18544
18734
|
await stampCompositionDims(compositionDest, outDims);
|
|
18545
|
-
const indexPath =
|
|
18735
|
+
const indexPath = path11.join(compositionDest, "index.html");
|
|
18546
18736
|
const overlayHtml = buildOverlayHtml(blueprint, { captionsActive: Boolean(transcript) });
|
|
18547
18737
|
const indexHtml = await readFile6(indexPath, "utf8");
|
|
18548
18738
|
const injected = indexHtml.replace("<!--OVERLAYS-->", () => overlayHtml);
|
|
@@ -18558,9 +18748,9 @@ var scaffoldVideoCommand = defineCommand90({
|
|
|
18558
18748
|
const opts = {
|
|
18559
18749
|
imageModel,
|
|
18560
18750
|
videoModel,
|
|
18561
|
-
overlayCompositionPath:
|
|
18562
|
-
captionsCompositionPath: captions.compositionPath ?
|
|
18563
|
-
blueprintPath:
|
|
18751
|
+
overlayCompositionPath: path11.relative(outDir, compositionDest),
|
|
18752
|
+
captionsCompositionPath: captions.compositionPath ? path11.relative(outDir, captions.compositionPath) : void 0,
|
|
18753
|
+
blueprintPath: path11.relative(outDir, blueprintPath),
|
|
18564
18754
|
frames,
|
|
18565
18755
|
ambient: Boolean(args.ambient),
|
|
18566
18756
|
...args.aspect ? { aspect: String(args.aspect) } : {},
|
|
@@ -18618,7 +18808,7 @@ var scaffoldVideoCommand = defineCommand90({
|
|
|
18618
18808
|
run_estimated_credits: validation.estimatedCredits
|
|
18619
18809
|
},
|
|
18620
18810
|
checklist: {
|
|
18621
|
-
edit_prompt: `Edit ${
|
|
18811
|
+
edit_prompt: `Edit ${path11.basename(blueprintPath)} \u2014 the blueprint deconstructed from your video; rewrite it into the ad you want (cast, palette, copy, claims). Every scene frame reads it via target_blueprint.`,
|
|
18622
18812
|
recurring_elements_to_supply: report.elements,
|
|
18623
18813
|
voices_to_confirm: report.dialogue.map((d) => ({
|
|
18624
18814
|
scene: d.scene,
|
|
@@ -18645,7 +18835,7 @@ var scaffoldVideoCommand = defineCommand90({
|
|
|
18645
18835
|
|
|
18646
18836
|
// src/commands/canvas/set-prompt.ts
|
|
18647
18837
|
import { readFile as readFile7, writeFile as writeFile3 } from "fs/promises";
|
|
18648
|
-
import
|
|
18838
|
+
import path12 from "path";
|
|
18649
18839
|
import { defineCommand as defineCommand91 } from "citty";
|
|
18650
18840
|
function setNodePrompt(canvas, nodeId, text) {
|
|
18651
18841
|
const nodes = canvas?.nodes;
|
|
@@ -18673,7 +18863,7 @@ var setPromptCommand = defineCommand91({
|
|
|
18673
18863
|
"text-file": { type: "string", description: "Read the new prompt from a UTF-8 file (preserves accents/newlines)" }
|
|
18674
18864
|
},
|
|
18675
18865
|
async run({ args }) {
|
|
18676
|
-
const filePath =
|
|
18866
|
+
const filePath = path12.resolve(String(args.file));
|
|
18677
18867
|
let canvas;
|
|
18678
18868
|
try {
|
|
18679
18869
|
canvas = JSON.parse(await readFile7(filePath, "utf8"));
|
|
@@ -18683,7 +18873,7 @@ var setPromptCommand = defineCommand91({
|
|
|
18683
18873
|
process.exit(2);
|
|
18684
18874
|
}
|
|
18685
18875
|
let text;
|
|
18686
|
-
if (args["text-file"]) text = await readFile7(
|
|
18876
|
+
if (args["text-file"]) text = await readFile7(path12.resolve(String(args["text-file"])), "utf8");
|
|
18687
18877
|
else if (args.text !== void 0) text = String(args.text);
|
|
18688
18878
|
else {
|
|
18689
18879
|
process.stderr.write(
|
|
@@ -18704,7 +18894,7 @@ var setPromptCommand = defineCommand91({
|
|
|
18704
18894
|
process.exit(2);
|
|
18705
18895
|
return;
|
|
18706
18896
|
}
|
|
18707
|
-
const validation = await validateCanvasDeep(resolveRelativeCanvasPaths(updated,
|
|
18897
|
+
const validation = await validateCanvasDeep(resolveRelativeCanvasPaths(updated, path12.dirname(filePath)), defaultRegistry());
|
|
18708
18898
|
if (!validation.ok) {
|
|
18709
18899
|
process.stderr.write(`${JSON.stringify({ ok: false, error: { code: "validation", issues: validation.issues } }, null, 2)}
|
|
18710
18900
|
`);
|
|
@@ -18720,7 +18910,7 @@ var setPromptCommand = defineCommand91({
|
|
|
18720
18910
|
|
|
18721
18911
|
// src/commands/canvas/validate.ts
|
|
18722
18912
|
import { readFile as readFile8 } from "fs/promises";
|
|
18723
|
-
import
|
|
18913
|
+
import path13 from "path";
|
|
18724
18914
|
import { defineCommand as defineCommand92 } from "citty";
|
|
18725
18915
|
var validateCommand = defineCommand92({
|
|
18726
18916
|
meta: {
|
|
@@ -18729,7 +18919,7 @@ var validateCommand = defineCommand92({
|
|
|
18729
18919
|
},
|
|
18730
18920
|
args: { file: { type: "positional", required: true, description: "Path to canvas JSON" } },
|
|
18731
18921
|
async run({ args }) {
|
|
18732
|
-
const filePath =
|
|
18922
|
+
const filePath = path13.resolve(String(args.file));
|
|
18733
18923
|
const raw = await readFile8(filePath, "utf8");
|
|
18734
18924
|
let parsed;
|
|
18735
18925
|
try {
|
|
@@ -18740,7 +18930,7 @@ var validateCommand = defineCommand92({
|
|
|
18740
18930
|
`);
|
|
18741
18931
|
process.exit(2);
|
|
18742
18932
|
}
|
|
18743
|
-
parsed = resolveRelativeCanvasPaths(parsed,
|
|
18933
|
+
parsed = resolveRelativeCanvasPaths(parsed, path13.dirname(filePath));
|
|
18744
18934
|
const result = await validateCanvasDeep(parsed, defaultRegistry());
|
|
18745
18935
|
if (!result.ok) {
|
|
18746
18936
|
process.stderr.write(`${JSON.stringify({ ok: false, issues: result.issues }, null, 2)}
|
|
@@ -18877,6 +19067,16 @@ registerSchema({
|
|
|
18877
19067
|
type: "string",
|
|
18878
19068
|
description: "Optional URL of the original reference ad",
|
|
18879
19069
|
required: false
|
|
19070
|
+
},
|
|
19071
|
+
slug: {
|
|
19072
|
+
type: "string",
|
|
19073
|
+
description: "Creative slug (src/creatives/<slug>/) \u2014 attaches the image to that creative's row",
|
|
19074
|
+
required: false
|
|
19075
|
+
},
|
|
19076
|
+
runId: {
|
|
19077
|
+
type: "string",
|
|
19078
|
+
description: "Canvas run id (r_\u2026) of the approved generation to pin as published",
|
|
19079
|
+
required: false
|
|
18880
19080
|
}
|
|
18881
19081
|
}
|
|
18882
19082
|
});
|
|
@@ -18886,6 +19086,13 @@ function detectCreativeContentType(filePath) {
|
|
|
18886
19086
|
unsupportedMessage: "Unsupported creative image extension. Use PNG, JPG, or WebP."
|
|
18887
19087
|
});
|
|
18888
19088
|
}
|
|
19089
|
+
function chatIdFromEnv() {
|
|
19090
|
+
try {
|
|
19091
|
+
return getEnv().BAKER_CHAT_ID || void 0;
|
|
19092
|
+
} catch {
|
|
19093
|
+
return void 0;
|
|
19094
|
+
}
|
|
19095
|
+
}
|
|
18889
19096
|
function parseOptionalUrl(value) {
|
|
18890
19097
|
if (value === void 0 || value.trim() === "") {
|
|
18891
19098
|
return void 0;
|
|
@@ -18916,7 +19123,11 @@ async function publishCreative(args, deps = defaultImageApiDeps) {
|
|
|
18916
19123
|
return publishImageAsCreative(deps, {
|
|
18917
19124
|
imageId: upload.imageId,
|
|
18918
19125
|
title,
|
|
18919
|
-
sourceReferenceUrl
|
|
19126
|
+
sourceReferenceUrl,
|
|
19127
|
+
slug: args.slug,
|
|
19128
|
+
runId: args.runId,
|
|
19129
|
+
// Attribute the publish to the driving chat (injected by the bridge).
|
|
19130
|
+
chatId: chatIdFromEnv()
|
|
18920
19131
|
});
|
|
18921
19132
|
}
|
|
18922
19133
|
var publishCommand = defineCommand94({
|
|
@@ -18932,6 +19143,16 @@ var publishCommand = defineCommand94({
|
|
|
18932
19143
|
type: "string",
|
|
18933
19144
|
description: "Optional URL of the original reference ad",
|
|
18934
19145
|
required: false
|
|
19146
|
+
},
|
|
19147
|
+
slug: {
|
|
19148
|
+
type: "string",
|
|
19149
|
+
description: "Creative slug (src/creatives/<slug>/) \u2014 attaches the image to that creative's row",
|
|
19150
|
+
required: false
|
|
19151
|
+
},
|
|
19152
|
+
runId: {
|
|
19153
|
+
type: "string",
|
|
19154
|
+
description: "Canvas run id (r_\u2026) of the approved generation to pin as published",
|
|
19155
|
+
required: false
|
|
18935
19156
|
}
|
|
18936
19157
|
},
|
|
18937
19158
|
run: async ({ args }) => {
|
|
@@ -18950,7 +19171,9 @@ var publishCommand = defineCommand94({
|
|
|
18950
19171
|
file,
|
|
18951
19172
|
title,
|
|
18952
19173
|
context: args.context,
|
|
18953
|
-
sourceReferenceUrl: args.sourceReferenceUrl
|
|
19174
|
+
sourceReferenceUrl: args.sourceReferenceUrl,
|
|
19175
|
+
slug: args.slug,
|
|
19176
|
+
runId: args.runId
|
|
18954
19177
|
});
|
|
18955
19178
|
writeJson({ ok: true, data });
|
|
18956
19179
|
} catch (err) {
|
|
@@ -19848,9 +20071,9 @@ async function readImageBuffer(pathOrUrl) {
|
|
|
19848
20071
|
}
|
|
19849
20072
|
return readFile10(pathOrUrl);
|
|
19850
20073
|
}
|
|
19851
|
-
async function isDirectory(
|
|
20074
|
+
async function isDirectory(path14) {
|
|
19852
20075
|
try {
|
|
19853
|
-
const s = await stat2(
|
|
20076
|
+
const s = await stat2(path14);
|
|
19854
20077
|
return s.isDirectory();
|
|
19855
20078
|
} catch {
|
|
19856
20079
|
return false;
|
|
@@ -23912,121 +24135,11 @@ var schemaCommand = defineCommand147({
|
|
|
23912
24135
|
}
|
|
23913
24136
|
});
|
|
23914
24137
|
|
|
23915
|
-
// src/commands/tags/index.ts
|
|
23916
|
-
import { defineCommand as defineCommand148 } from "citty";
|
|
23917
|
-
|
|
23918
|
-
// src/commands/tags/shared.ts
|
|
23919
|
-
function failApi3(err) {
|
|
23920
|
-
if (err instanceof ApiError) {
|
|
23921
|
-
writeJson({ ok: false, error: { code: err.code, message: err.message } });
|
|
23922
|
-
process.exit(1);
|
|
23923
|
-
}
|
|
23924
|
-
if (err instanceof Error) {
|
|
23925
|
-
writeJson({ ok: false, error: { code: "INTERNAL_ERROR", message: err.message } });
|
|
23926
|
-
process.exit(1);
|
|
23927
|
-
}
|
|
23928
|
-
writeJson({ ok: false, error: { code: "INTERNAL_ERROR", message: "Unexpected error" } });
|
|
23929
|
-
process.exit(1);
|
|
23930
|
-
}
|
|
23931
|
-
function renderEffectiveEntry(entry) {
|
|
23932
|
-
const parts = [entry.ref, entry.type];
|
|
23933
|
-
if (entry.identifier !== void 0) {
|
|
23934
|
-
parts.push(entry.identifier);
|
|
23935
|
-
}
|
|
23936
|
-
if (entry.staged !== void 0) {
|
|
23937
|
-
parts.push(`[staged: ${entry.staged}]`);
|
|
23938
|
-
}
|
|
23939
|
-
const secretBits = [
|
|
23940
|
-
...entry.secretsSet.map((field) => `${field} \u2713 set`),
|
|
23941
|
-
...entry.secretsPending.map((field) => `${field} \u23F3 pending`)
|
|
23942
|
-
];
|
|
23943
|
-
if (secretBits.length > 0) {
|
|
23944
|
-
parts.push(`[secrets: ${secretBits.join(", ")}]`);
|
|
23945
|
-
}
|
|
23946
|
-
return parts.join(" ");
|
|
23947
|
-
}
|
|
23948
|
-
|
|
23949
|
-
// src/commands/tags/index.ts
|
|
23950
|
-
registerSchema({
|
|
23951
|
-
command: "tags.list",
|
|
23952
|
-
description: "Effective marketing tags for this chat: production tags overlaid with the changes staged in this chat. The printed refs (tag ids or tag_temp_*) are exactly what flow side-effect tagIds should reference. Read-only \u2014 every tag change (create, edit, delete) goes through the request_tag_input approval tool.",
|
|
23953
|
-
args: {
|
|
23954
|
-
json: { type: "boolean", description: "Print the raw JSON envelope instead of the readable list", required: false }
|
|
23955
|
-
}
|
|
23956
|
-
});
|
|
23957
|
-
async function listTags(json) {
|
|
23958
|
-
try {
|
|
23959
|
-
const chatId = requireChatId();
|
|
23960
|
-
const response = await apiPost("/api/tags/list", { chatId });
|
|
23961
|
-
if (json) {
|
|
23962
|
-
writeJson({ ok: true, data: response });
|
|
23963
|
-
return;
|
|
23964
|
-
}
|
|
23965
|
-
if (response.tags.length === 0) {
|
|
23966
|
-
process.stdout.write("No tags configured. Propose one with the request_tag_input tool (baker_ui).\n");
|
|
23967
|
-
return;
|
|
23968
|
-
}
|
|
23969
|
-
process.stdout.write(`${response.tags.map(renderEffectiveEntry).join("\n")}
|
|
23970
|
-
`);
|
|
23971
|
-
} catch (err) {
|
|
23972
|
-
failApi3(err);
|
|
23973
|
-
}
|
|
23974
|
-
}
|
|
23975
|
-
var listCommand7 = defineCommand148({
|
|
23976
|
-
meta: {
|
|
23977
|
-
name: "list",
|
|
23978
|
-
description: "Effective tags for this chat (production + staged). Refs printed here are what flow side-effect tagIds should use. Example: baker tags list"
|
|
23979
|
-
},
|
|
23980
|
-
args: { json: { type: "boolean", description: "Print the raw JSON envelope instead of the readable list" } },
|
|
23981
|
-
run: async ({ args }) => {
|
|
23982
|
-
await listTags(args.json === true);
|
|
23983
|
-
}
|
|
23984
|
-
});
|
|
23985
|
-
async function listDraft3() {
|
|
23986
|
-
try {
|
|
23987
|
-
const chatId = requireChatId();
|
|
23988
|
-
const response = await apiPost("/api/tags/draft", { chatId });
|
|
23989
|
-
writeJson({ ok: true, data: response });
|
|
23990
|
-
} catch (err) {
|
|
23991
|
-
failApi3(err);
|
|
23992
|
-
}
|
|
23993
|
-
}
|
|
23994
|
-
var draftCommand3 = defineCommand148({
|
|
23995
|
-
meta: {
|
|
23996
|
-
name: "draft",
|
|
23997
|
-
description: "Review the tag changes staged in this chat (read-only). Staged changes were approved via request_tag_input and apply when the chat is published; to amend or drop one, propose a follow-up change through the same tool (a delete on a tag_temp_* ref drops the staged create)."
|
|
23998
|
-
},
|
|
23999
|
-
run: async () => {
|
|
24000
|
-
await listDraft3();
|
|
24001
|
-
}
|
|
24002
|
-
});
|
|
24003
|
-
var tagsCommand3 = defineCommand148({
|
|
24004
|
-
meta: {
|
|
24005
|
-
name: "tags",
|
|
24006
|
-
description: `Read the client's marketing/analytics tags (Meta pixel, GA4, Google Ads, GTM, Clarity, Hotjar, \u2026) \u2014 production tags plus the changes staged in this chat.
|
|
24007
|
-
|
|
24008
|
-
This command is READ-ONLY. Every tag change \u2014 create, edit, or delete \u2014 goes through the request_tag_input tool (baker_ui MCP server): propose one or more changes (each becomes a tab in one approval form), pre-fill the non-secret fields you know, and the user reviews, fills secrets, and approves or skips each. Secret values (accessToken, apiSecret, authorizationToken, apiKey, conversionToken, OAuth connections) never pass through the CLI or the chat.
|
|
24009
|
-
|
|
24010
|
-
Refs: \`baker tags list\` prints each tag's ref \u2014 a real tag id, or tag_temp_* for creates staged in this chat. Use these refs as flow side-effect tagIds; they keep resolving after publish.
|
|
24011
|
-
|
|
24012
|
-
Examples:
|
|
24013
|
-
baker tags list # production + staged, with secret status
|
|
24014
|
-
baker tags draft # review the staged changes awaiting publish`
|
|
24015
|
-
},
|
|
24016
|
-
subCommands: {
|
|
24017
|
-
list: listCommand7,
|
|
24018
|
-
draft: draftCommand3
|
|
24019
|
-
},
|
|
24020
|
-
run: async () => {
|
|
24021
|
-
await listTags(false);
|
|
24022
|
-
}
|
|
24023
|
-
});
|
|
24024
|
-
|
|
24025
24138
|
// src/commands/testimonials/index.ts
|
|
24026
|
-
import { defineCommand as
|
|
24139
|
+
import { defineCommand as defineCommand151 } from "citty";
|
|
24027
24140
|
|
|
24028
24141
|
// src/commands/testimonials/get.ts
|
|
24029
|
-
import { defineCommand as
|
|
24142
|
+
import { defineCommand as defineCommand148 } from "citty";
|
|
24030
24143
|
registerSchema({
|
|
24031
24144
|
command: "testimonials.get",
|
|
24032
24145
|
description: "Get a single testimonial by ID",
|
|
@@ -24034,7 +24147,7 @@ registerSchema({
|
|
|
24034
24147
|
id: { type: "string", description: "Testimonial ID", required: true }
|
|
24035
24148
|
}
|
|
24036
24149
|
});
|
|
24037
|
-
var getCommand4 =
|
|
24150
|
+
var getCommand4 = defineCommand148({
|
|
24038
24151
|
meta: { name: "get", description: "Get a single testimonial by ID. Example: baker testimonials get j571abc123" },
|
|
24039
24152
|
args: {
|
|
24040
24153
|
id: { type: "positional", description: "Testimonial ID", required: false },
|
|
@@ -24071,7 +24184,7 @@ var getCommand4 = defineCommand149({
|
|
|
24071
24184
|
});
|
|
24072
24185
|
|
|
24073
24186
|
// src/commands/testimonials/list.ts
|
|
24074
|
-
import { defineCommand as
|
|
24187
|
+
import { defineCommand as defineCommand149 } from "citty";
|
|
24075
24188
|
registerSchema({
|
|
24076
24189
|
command: "testimonials.list",
|
|
24077
24190
|
description: "List testimonials with optional filters.",
|
|
@@ -24101,7 +24214,7 @@ registerSchema({
|
|
|
24101
24214
|
limit: { type: "number", description: "Max results (default 50)", required: false, default: 50 }
|
|
24102
24215
|
}
|
|
24103
24216
|
});
|
|
24104
|
-
var
|
|
24217
|
+
var listCommand7 = defineCommand149({
|
|
24105
24218
|
meta: {
|
|
24106
24219
|
name: "list",
|
|
24107
24220
|
description: "List testimonials with optional filters. Example: baker testimonials list --source google --sentiment positive"
|
|
@@ -24150,7 +24263,7 @@ var listCommand8 = defineCommand150({
|
|
|
24150
24263
|
});
|
|
24151
24264
|
|
|
24152
24265
|
// src/commands/testimonials/search.ts
|
|
24153
|
-
import { defineCommand as
|
|
24266
|
+
import { defineCommand as defineCommand150 } from "citty";
|
|
24154
24267
|
registerSchema({
|
|
24155
24268
|
command: "testimonials.search",
|
|
24156
24269
|
description: "Search testimonials by text query. Uses hybrid BM25 + vector + reranking.",
|
|
@@ -24181,7 +24294,7 @@ registerSchema({
|
|
|
24181
24294
|
tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
|
|
24182
24295
|
}
|
|
24183
24296
|
});
|
|
24184
|
-
var searchCommand2 =
|
|
24297
|
+
var searchCommand2 = defineCommand150({
|
|
24185
24298
|
meta: {
|
|
24186
24299
|
name: "search",
|
|
24187
24300
|
description: "Semantic search testimonials by text query. Uses hybrid BM25 + vector + reranking. Example: baker testimonials search 'great service' --rating-min 4"
|
|
@@ -24252,10 +24365,10 @@ var searchCommand2 = defineCommand151({
|
|
|
24252
24365
|
});
|
|
24253
24366
|
|
|
24254
24367
|
// src/commands/testimonials/tags.ts
|
|
24255
|
-
var
|
|
24368
|
+
var tagsCommand3 = makeTagsCommand("testimonials", "testimonial", "/api/testimonials/tags");
|
|
24256
24369
|
|
|
24257
24370
|
// src/commands/testimonials/index.ts
|
|
24258
|
-
var testimonialsCommand =
|
|
24371
|
+
var testimonialsCommand = defineCommand151({
|
|
24259
24372
|
meta: {
|
|
24260
24373
|
name: "testimonials",
|
|
24261
24374
|
description: `Find and browse testimonials in Baker. Subcommands: search, get, list, tags.
|
|
@@ -24270,16 +24383,16 @@ Examples:
|
|
|
24270
24383
|
subCommands: {
|
|
24271
24384
|
get: getCommand4,
|
|
24272
24385
|
search: searchCommand2,
|
|
24273
|
-
list:
|
|
24274
|
-
tags:
|
|
24386
|
+
list: listCommand7,
|
|
24387
|
+
tags: tagsCommand3
|
|
24275
24388
|
}
|
|
24276
24389
|
});
|
|
24277
24390
|
|
|
24278
24391
|
// src/commands/videos/index.ts
|
|
24279
|
-
import { defineCommand as
|
|
24392
|
+
import { defineCommand as defineCommand156 } from "citty";
|
|
24280
24393
|
|
|
24281
24394
|
// src/commands/videos/delete.ts
|
|
24282
|
-
import { defineCommand as
|
|
24395
|
+
import { defineCommand as defineCommand152 } from "citty";
|
|
24283
24396
|
registerSchema({
|
|
24284
24397
|
command: "videos.delete",
|
|
24285
24398
|
description: "Delete a video by ID",
|
|
@@ -24293,7 +24406,7 @@ registerSchema({
|
|
|
24293
24406
|
}
|
|
24294
24407
|
}
|
|
24295
24408
|
});
|
|
24296
|
-
var deleteCommand3 =
|
|
24409
|
+
var deleteCommand3 = defineCommand152({
|
|
24297
24410
|
meta: {
|
|
24298
24411
|
name: "delete",
|
|
24299
24412
|
description: "Delete a video by ID. Use --dry-run to preview. Example: baker videos delete j571abc123 --dry-run"
|
|
@@ -24334,7 +24447,7 @@ var deleteCommand3 = defineCommand153({
|
|
|
24334
24447
|
});
|
|
24335
24448
|
|
|
24336
24449
|
// src/commands/videos/get.ts
|
|
24337
|
-
import { defineCommand as
|
|
24450
|
+
import { defineCommand as defineCommand153 } from "citty";
|
|
24338
24451
|
registerSchema({
|
|
24339
24452
|
command: "videos.get",
|
|
24340
24453
|
description: "Get a single video by ID",
|
|
@@ -24342,7 +24455,7 @@ registerSchema({
|
|
|
24342
24455
|
id: { type: "string", description: "Video ID", required: true }
|
|
24343
24456
|
}
|
|
24344
24457
|
});
|
|
24345
|
-
var getCommand5 =
|
|
24458
|
+
var getCommand5 = defineCommand153({
|
|
24346
24459
|
meta: { name: "get", description: "Get a single video by ID. Example: baker videos get j571abc123" },
|
|
24347
24460
|
args: {
|
|
24348
24461
|
id: { type: "positional", description: "Video ID", required: false },
|
|
@@ -24379,7 +24492,7 @@ var getCommand5 = defineCommand154({
|
|
|
24379
24492
|
});
|
|
24380
24493
|
|
|
24381
24494
|
// src/commands/videos/search.ts
|
|
24382
|
-
import { defineCommand as
|
|
24495
|
+
import { defineCommand as defineCommand154 } from "citty";
|
|
24383
24496
|
registerSchema({
|
|
24384
24497
|
command: "videos.search",
|
|
24385
24498
|
description: "Search videos by text query. Only returns ready videos.",
|
|
@@ -24389,7 +24502,7 @@ registerSchema({
|
|
|
24389
24502
|
tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
|
|
24390
24503
|
}
|
|
24391
24504
|
});
|
|
24392
|
-
var searchCommand3 =
|
|
24505
|
+
var searchCommand3 = defineCommand154({
|
|
24393
24506
|
meta: {
|
|
24394
24507
|
name: "search",
|
|
24395
24508
|
description: "Semantic search videos by text query. Uses hybrid BM25 + vector + reranking. Example: baker videos search 'product demo' --tags tutorial"
|
|
@@ -24436,12 +24549,12 @@ var searchCommand3 = defineCommand155({
|
|
|
24436
24549
|
});
|
|
24437
24550
|
|
|
24438
24551
|
// src/commands/videos/tags.ts
|
|
24439
|
-
var
|
|
24552
|
+
var tagsCommand4 = makeTagsCommand("videos", "video", "/api/videos/tags");
|
|
24440
24553
|
|
|
24441
24554
|
// src/commands/videos/upload.ts
|
|
24442
24555
|
import { readFile as readFile12, stat as stat3 } from "fs/promises";
|
|
24443
24556
|
import { extname as extname3 } from "path";
|
|
24444
|
-
import { defineCommand as
|
|
24557
|
+
import { defineCommand as defineCommand155 } from "citty";
|
|
24445
24558
|
var MIME_MAP = {
|
|
24446
24559
|
".mp4": "video/mp4",
|
|
24447
24560
|
".mov": "video/quicktime",
|
|
@@ -24475,7 +24588,7 @@ function detectContentType(filePath) {
|
|
|
24475
24588
|
}
|
|
24476
24589
|
return mime;
|
|
24477
24590
|
}
|
|
24478
|
-
var uploadCommand2 =
|
|
24591
|
+
var uploadCommand2 = defineCommand155({
|
|
24479
24592
|
meta: {
|
|
24480
24593
|
name: "upload",
|
|
24481
24594
|
description: "Upload a video file to Baker via Mux direct upload. Auto-detects content type. Example: baker videos upload ./demo.mp4"
|
|
@@ -24529,7 +24642,7 @@ var uploadCommand2 = defineCommand156({
|
|
|
24529
24642
|
});
|
|
24530
24643
|
|
|
24531
24644
|
// src/commands/videos/index.ts
|
|
24532
|
-
var videosCommand =
|
|
24645
|
+
var videosCommand = defineCommand156({
|
|
24533
24646
|
meta: {
|
|
24534
24647
|
name: "videos",
|
|
24535
24648
|
description: `Find and manage videos in Baker. Subcommands: search, get, upload, delete, tags.
|
|
@@ -24547,15 +24660,15 @@ Examples:
|
|
|
24547
24660
|
search: searchCommand3,
|
|
24548
24661
|
upload: uploadCommand2,
|
|
24549
24662
|
delete: deleteCommand3,
|
|
24550
|
-
tags:
|
|
24663
|
+
tags: tagsCommand4
|
|
24551
24664
|
}
|
|
24552
24665
|
});
|
|
24553
24666
|
|
|
24554
24667
|
// src/commands/winning-ads/index.ts
|
|
24555
|
-
import { defineCommand as
|
|
24668
|
+
import { defineCommand as defineCommand159 } from "citty";
|
|
24556
24669
|
|
|
24557
24670
|
// src/commands/winning-ads/advertisers.ts
|
|
24558
|
-
import { defineCommand as
|
|
24671
|
+
import { defineCommand as defineCommand157 } from "citty";
|
|
24559
24672
|
registerSchema({
|
|
24560
24673
|
command: "winning-ads.advertisers",
|
|
24561
24674
|
description: "Resolve a brand name to advertiser_id(s) in the ad-dna corpus \u2014 to find your OWN advertiser (to --exclude-advertiser) or a competitor (to --advertiser-id).",
|
|
@@ -24568,7 +24681,7 @@ registerSchema({
|
|
|
24568
24681
|
function identity(record) {
|
|
24569
24682
|
return record;
|
|
24570
24683
|
}
|
|
24571
|
-
var advertisersCommand2 =
|
|
24684
|
+
var advertisersCommand2 = defineCommand157({
|
|
24572
24685
|
meta: {
|
|
24573
24686
|
name: "advertisers",
|
|
24574
24687
|
description: 'Resolve a brand name to advertiser_id(s). Use it to find your own advertiser for --exclude-advertiser, or a competitor for --advertiser-id. Example: baker winning-ads advertisers "Deel" --output md'
|
|
@@ -24619,7 +24732,7 @@ var advertisersCommand2 = defineCommand158({
|
|
|
24619
24732
|
});
|
|
24620
24733
|
|
|
24621
24734
|
// src/commands/winning-ads/search.ts
|
|
24622
|
-
import { defineCommand as
|
|
24735
|
+
import { defineCommand as defineCommand158 } from "citty";
|
|
24623
24736
|
registerSchema({
|
|
24624
24737
|
command: "winning-ads.search",
|
|
24625
24738
|
description: "Search the ad-dna corpus of scored winning ads. Returns a lean shortlist (advertiser, summary, scores, media_url) to pick a reference to reproduce.",
|
|
@@ -24727,7 +24840,7 @@ function buildSearchBody(args) {
|
|
|
24727
24840
|
}
|
|
24728
24841
|
return body;
|
|
24729
24842
|
}
|
|
24730
|
-
var searchCommand4 =
|
|
24843
|
+
var searchCommand4 = defineCommand158({
|
|
24731
24844
|
meta: {
|
|
24732
24845
|
name: "search",
|
|
24733
24846
|
description: "Search winning reference ads. Example: baker winning-ads search 'B2B SaaS before/after AI automation' --platform meta --format static --winner-category winner --exclude-advertiser adv_123 --output md"
|
|
@@ -24839,7 +24952,7 @@ var searchCommand4 = defineCommand159({
|
|
|
24839
24952
|
});
|
|
24840
24953
|
|
|
24841
24954
|
// src/commands/winning-ads/index.ts
|
|
24842
|
-
var winningAdsCommand =
|
|
24955
|
+
var winningAdsCommand = defineCommand159({
|
|
24843
24956
|
meta: {
|
|
24844
24957
|
name: "winning-ads",
|
|
24845
24958
|
description: `Search the ad-dna corpus of scored "winning" ads for reference creatives to reproduce. Proxied through the Baker backend (BAKER_API_KEY) \u2014 no separate token needed.
|
|
@@ -24879,11 +24992,11 @@ function getCliVersion() {
|
|
|
24879
24992
|
}
|
|
24880
24993
|
|
|
24881
24994
|
// src/cli.ts
|
|
24882
|
-
var main =
|
|
24995
|
+
var main = defineCommand160({
|
|
24883
24996
|
meta: {
|
|
24884
24997
|
name: "baker",
|
|
24885
24998
|
version: getCliVersion(),
|
|
24886
|
-
description: `AI-agent CLI for finding and managing images, videos, testimonials, action items, scheduled actions,
|
|
24999
|
+
description: `AI-agent CLI for finding and managing images, videos, testimonials, action items, scheduled actions, and ad platform data in Baker.
|
|
24887
25000
|
|
|
24888
25001
|
Auth: Set BAKER_API_KEY (starts with bk_) and BAKER_API_URL environment variables.
|
|
24889
25002
|
Chat: Set BAKER_CHAT_ID for action and scheduled-action commands that stage changes against a chat.
|
|
@@ -24903,7 +25016,6 @@ Introspection: Run 'baker schema <command>' to inspect argument schemas.`
|
|
|
24903
25016
|
videos: videosCommand,
|
|
24904
25017
|
testimonials: testimonialsCommand,
|
|
24905
25018
|
canvas: canvasCommand,
|
|
24906
|
-
tags: tagsCommand3,
|
|
24907
25019
|
"winning-ads": winningAdsCommand,
|
|
24908
25020
|
mcp: mcpCommand,
|
|
24909
25021
|
schema: schemaCommand
|