@koda-sl/baker-cli 0.121.0-dev.3a1b48e85 → 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 -28
- package/dist/{chunk-MWFJ5NOP.js → chunk-7WLX7E7H.js} +303 -61
- package/dist/chunk-7WLX7E7H.js.map +1 -0
- package/dist/cli.js +1225 -1396
- 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,307 +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 TAG_SECRET_FIELDS = {
|
|
1943
|
-
meta: ["accessToken"],
|
|
1944
|
-
amplitude: [],
|
|
1945
|
-
googleAds: ["oauthProviderId", "customerAccountId", "customerId", "loginCustomerId"],
|
|
1946
|
-
tiktok: ["accessToken"],
|
|
1947
|
-
vwo: [],
|
|
1948
|
-
hotjar: [],
|
|
1949
|
-
clarity: [],
|
|
1950
|
-
pinterest: ["conversionToken"],
|
|
1951
|
-
code: [],
|
|
1952
|
-
googleAnalytics: ["apiSecret"],
|
|
1953
|
-
googleTagManager: ["authorizationToken"],
|
|
1954
|
-
hubspot: [],
|
|
1955
|
-
linkedinInsightTag: ["oauthProviderId"],
|
|
1956
|
-
onetrust: [],
|
|
1957
|
-
posthog: [],
|
|
1958
|
-
datafast: ["apiKey"],
|
|
1959
|
-
recaptcha: [],
|
|
1960
|
-
twitterAds: ["oauthProviderId"]
|
|
1961
|
-
};
|
|
1962
|
-
var TAG_REQUESTABLE_SECRET_FIELDS = {
|
|
1963
|
-
meta: ["accessToken"],
|
|
1964
|
-
amplitude: [],
|
|
1965
|
-
googleAds: ["oauthProviderId", "customerAccountId"],
|
|
1966
|
-
tiktok: ["accessToken"],
|
|
1967
|
-
vwo: [],
|
|
1968
|
-
hotjar: [],
|
|
1969
|
-
clarity: [],
|
|
1970
|
-
pinterest: ["conversionToken"],
|
|
1971
|
-
code: [],
|
|
1972
|
-
googleAnalytics: ["apiSecret"],
|
|
1973
|
-
googleTagManager: ["authorizationToken"],
|
|
1974
|
-
hubspot: [],
|
|
1975
|
-
linkedinInsightTag: ["oauthProviderId"],
|
|
1976
|
-
onetrust: [],
|
|
1977
|
-
posthog: [],
|
|
1978
|
-
datafast: ["apiKey"],
|
|
1979
|
-
recaptcha: [],
|
|
1980
|
-
twitterAds: ["oauthProviderId"]
|
|
1981
|
-
};
|
|
1982
|
-
var tagDraftOpKindSchema = z5.enum(["create", "update", "delete"]);
|
|
1983
|
-
var tagDraftOpViewSchema = z5.object({
|
|
1984
|
-
/** `tag_temp_*` for staged creates; the real tag id for update/delete ops. */
|
|
1985
|
-
ref: z5.string(),
|
|
1986
|
-
kind: tagDraftOpKindSchema,
|
|
1987
|
-
type: tagTypeSchema,
|
|
1988
|
-
/** Present on update/delete ops — the real tag this op targets. */
|
|
1989
|
-
tagId: z5.string().optional(),
|
|
1990
|
-
/** Non-secret config (create: full; update: the staged patch). Secrets are structurally absent. */
|
|
1991
|
-
config: z5.record(z5.string(), z5.string()),
|
|
1992
|
-
/** Update only — fields the op explicitly clears. */
|
|
1993
|
-
clearFields: z5.array(z5.string()).optional(),
|
|
1994
|
-
/** Names of secret fields already provided via the dashboard secure form. Never values. */
|
|
1995
|
-
secretsSet: z5.array(z5.string()),
|
|
1996
|
-
/** Names of secret fields still awaiting user input. */
|
|
1997
|
-
secretsPending: z5.array(z5.string()),
|
|
1998
|
-
summary: z5.string(),
|
|
1999
|
-
stagedAt: z5.number()
|
|
2000
|
-
});
|
|
2001
|
-
var tagsEffectiveEntrySchema = z5.object({
|
|
2002
|
-
/** Real tag id, or `tag_temp_*` for staged creates. Use as flow side-effect `tagIds` value. */
|
|
2003
|
-
ref: z5.string(),
|
|
2004
|
-
tagId: z5.string().optional(),
|
|
2005
|
-
type: tagTypeSchema,
|
|
2006
|
-
/** Value of the type's identifying field, when set. */
|
|
2007
|
-
identifier: z5.string().optional(),
|
|
2008
|
-
/** Redacted config; for staged updates, production config with the patch merged. */
|
|
2009
|
-
config: z5.record(z5.string(), z5.string()),
|
|
2010
|
-
/** Absent = live production tag with no staged changes in this chat. */
|
|
2011
|
-
staged: tagDraftOpKindSchema.optional(),
|
|
2012
|
-
secretsSet: z5.array(z5.string()),
|
|
2013
|
-
secretsPending: z5.array(z5.string())
|
|
2014
|
-
});
|
|
2015
|
-
var tagsListRequestSchema = z5.object({ chatId: z5.string() });
|
|
2016
|
-
var tagsListResponseSchema = z5.object({ tags: z5.array(tagsEffectiveEntrySchema) });
|
|
2017
|
-
var tagsDraftStageRequestSchema = z5.discriminatedUnion("kind", [
|
|
2018
|
-
z5.object({
|
|
2019
|
-
kind: z5.literal("create"),
|
|
2020
|
-
chatId: z5.string(),
|
|
2021
|
-
type: tagTypeSchema,
|
|
2022
|
-
config: z5.record(z5.string(), z5.string()),
|
|
2023
|
-
requestSecrets: z5.array(z5.string()).optional(),
|
|
2024
|
-
summary: z5.string().optional()
|
|
2025
|
-
}),
|
|
2026
|
-
z5.object({
|
|
2027
|
-
kind: z5.literal("update"),
|
|
2028
|
-
chatId: z5.string(),
|
|
2029
|
-
ref: z5.string(),
|
|
2030
|
-
config: z5.record(z5.string(), z5.string()).optional(),
|
|
2031
|
-
clearFields: z5.array(z5.string()).optional(),
|
|
2032
|
-
requestSecrets: z5.array(z5.string()).optional(),
|
|
2033
|
-
summary: z5.string().optional()
|
|
2034
|
-
}),
|
|
2035
|
-
z5.object({
|
|
2036
|
-
kind: z5.literal("delete"),
|
|
2037
|
-
chatId: z5.string(),
|
|
2038
|
-
ref: z5.string()
|
|
2039
|
-
})
|
|
2040
|
-
]);
|
|
2041
|
-
var tagsDraftStageResponseSchema = z5.object({
|
|
2042
|
-
/** Null when the request dissolved a staged create (delete/clearing an unpublished temp ref). */
|
|
2043
|
-
op: tagDraftOpViewSchema.nullable(),
|
|
2044
|
-
/** True when a `delete <tag_temp_*>` dropped the staged create instead of staging a delete. */
|
|
2045
|
-
removedStagedCreate: z5.boolean().optional()
|
|
2046
|
-
});
|
|
2047
|
-
var tagsDraftListRequestSchema = z5.object({ chatId: z5.string() });
|
|
2048
|
-
var tagsDraftListResponseSchema = z5.object({
|
|
2049
|
-
status: z5.enum(["active", "publishing", "applied", "discarded", "none"]),
|
|
2050
|
-
ops: z5.array(tagDraftOpViewSchema)
|
|
2051
|
-
});
|
|
2052
|
-
var tagsDraftRemoveRequestSchema = z5.object({ chatId: z5.string(), ref: z5.string() });
|
|
2053
|
-
var tagsDraftRemoveResponseSchema = z5.object({ removed: z5.boolean() });
|
|
2054
|
-
var tagsDraftClearRequestSchema = z5.object({ chatId: z5.string() });
|
|
2055
|
-
var tagsDraftClearResponseSchema = z5.object({ cleared: z5.number() });
|
|
2056
|
-
var tagInputRequestSchema = z5.object({
|
|
2057
|
-
mode: z5.enum(["create", "edit"]),
|
|
2058
|
-
tagType: tagTypeSchema,
|
|
2059
|
-
/** Edit mode — the real tag id or `tag_temp_*` ref being edited. */
|
|
2060
|
-
ref: z5.string().optional(),
|
|
2061
|
-
/** Non-secret values the agent proposes to prefill. Secret keys are stripped at every boundary. */
|
|
2062
|
-
prefilledConfig: z5.record(z5.string(), z5.string()).optional(),
|
|
2063
|
-
/** Secret field names the agent asks the user to provide. */
|
|
2064
|
-
requestedSecretFields: z5.array(z5.string()).optional(),
|
|
2065
|
-
/** Short message shown above the form explaining why the input is needed. */
|
|
2066
|
-
message: z5.string().optional()
|
|
2067
|
-
});
|
|
2068
|
-
var tagInputResultSchema = z5.discriminatedUnion("status", [
|
|
2069
|
-
z5.object({
|
|
2070
|
-
status: z5.literal("submitted"),
|
|
2071
|
-
ref: z5.string(),
|
|
2072
|
-
type: tagTypeSchema,
|
|
2073
|
-
/** Identifying field name → value (non-secret), when the type has one. */
|
|
2074
|
-
identifier: z5.record(z5.string(), z5.string()).optional(),
|
|
2075
|
-
secretFieldsSet: z5.array(z5.string()),
|
|
2076
|
-
note: z5.string().optional()
|
|
2077
|
-
}),
|
|
2078
|
-
z5.object({
|
|
2079
|
-
status: z5.literal("declined"),
|
|
2080
|
-
reason: z5.string().optional()
|
|
2081
|
-
})
|
|
2082
|
-
]);
|
|
2083
|
-
|
|
2084
1927
|
// ../api/src/testimonials.ts
|
|
2085
|
-
import { z as
|
|
2086
|
-
var testimonialSourceTypeSchema =
|
|
2087
|
-
var testimonialStatusSchema =
|
|
2088
|
-
var testimonialSentimentSchema =
|
|
2089
|
-
var testimonialDocSchema =
|
|
2090
|
-
_id:
|
|
2091
|
-
_creationTime:
|
|
2092
|
-
companyId:
|
|
2093
|
-
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(),
|
|
2094
1937
|
sourceType: testimonialSourceTypeSchema,
|
|
2095
|
-
reviewText:
|
|
2096
|
-
reviewTitle:
|
|
2097
|
-
searchText:
|
|
2098
|
-
reviewerName:
|
|
2099
|
-
reviewerImageUrl:
|
|
2100
|
-
reviewerImageId:
|
|
2101
|
-
reviewerLocation:
|
|
2102
|
-
rating:
|
|
2103
|
-
reviewDate:
|
|
2104
|
-
ownerAnswer:
|
|
2105
|
-
mediaUrls:
|
|
2106
|
-
imageIds:
|
|
2107
|
-
videoIds:
|
|
2108
|
-
sourceUrl:
|
|
2109
|
-
rawData:
|
|
2110
|
-
tags:
|
|
2111
|
-
highlight:
|
|
2112
|
-
language:
|
|
2113
|
-
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(),
|
|
2114
1957
|
sentiment: testimonialSentimentSchema.optional(),
|
|
2115
|
-
textEmbedding:
|
|
2116
|
-
externalId:
|
|
2117
|
-
contentHash:
|
|
1958
|
+
textEmbedding: z5.array(z5.number()).optional(),
|
|
1959
|
+
externalId: z5.string().optional(),
|
|
1960
|
+
contentHash: z5.string().optional(),
|
|
2118
1961
|
status: testimonialStatusSchema,
|
|
2119
|
-
errorMessage:
|
|
2120
|
-
createdAt:
|
|
2121
|
-
updatedAt:
|
|
1962
|
+
errorMessage: z5.string().optional(),
|
|
1963
|
+
createdAt: z5.number(),
|
|
1964
|
+
updatedAt: z5.number()
|
|
2122
1965
|
});
|
|
2123
|
-
var testimonialsListRequestSchema =
|
|
1966
|
+
var testimonialsListRequestSchema = z5.object({
|
|
2124
1967
|
source: testimonialSourceTypeSchema.optional(),
|
|
2125
|
-
rating_min:
|
|
2126
|
-
rating_max:
|
|
2127
|
-
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(),
|
|
2128
1971
|
status: testimonialStatusSchema.optional(),
|
|
2129
1972
|
sentiment: testimonialSentimentSchema.optional(),
|
|
2130
|
-
language:
|
|
2131
|
-
limit:
|
|
2132
|
-
});
|
|
2133
|
-
var testimonialsListResponseSchema =
|
|
2134
|
-
var testimonialsGetRequestSchema =
|
|
2135
|
-
var testimonialsSearchRequestSchema =
|
|
2136
|
-
query:
|
|
2137
|
-
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(),
|
|
2138
1981
|
source: testimonialSourceTypeSchema.optional(),
|
|
2139
|
-
rating_min:
|
|
2140
|
-
rating_max:
|
|
2141
|
-
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(),
|
|
2142
1985
|
status: testimonialStatusSchema.optional(),
|
|
2143
1986
|
sentiment: testimonialSentimentSchema.optional(),
|
|
2144
|
-
language:
|
|
1987
|
+
language: z5.string().min(2).max(5).optional()
|
|
2145
1988
|
}).refine(
|
|
2146
1989
|
(data) => data.rating_min === void 0 || data.rating_max === void 0 || data.rating_min <= data.rating_max,
|
|
2147
1990
|
{ message: "rating_min must be less than or equal to rating_max" }
|
|
2148
1991
|
);
|
|
2149
|
-
var testimonialsSearchResponseSchema =
|
|
2150
|
-
var testimonialsOutscraperWebhookResponseSchema =
|
|
2151
|
-
ok:
|
|
2152
|
-
note:
|
|
1992
|
+
var testimonialsSearchResponseSchema = z5.array(testimonialDocSchema);
|
|
1993
|
+
var testimonialsOutscraperWebhookResponseSchema = z5.object({
|
|
1994
|
+
ok: z5.literal(true),
|
|
1995
|
+
note: z5.string().optional()
|
|
2153
1996
|
});
|
|
2154
1997
|
|
|
2155
1998
|
// ../api/src/videos.ts
|
|
2156
|
-
import { z as
|
|
2157
|
-
var videoStatusSchema =
|
|
2158
|
-
var videoTranscriptSegmentSchema =
|
|
2159
|
-
text:
|
|
2160
|
-
startSecond:
|
|
2161
|
-
endSecond:
|
|
2162
|
-
});
|
|
2163
|
-
var videoSceneSchema =
|
|
2164
|
-
title:
|
|
2165
|
-
description:
|
|
2166
|
-
startSecond:
|
|
2167
|
-
endSecond:
|
|
2168
|
-
thumbnailTime:
|
|
2169
|
-
});
|
|
2170
|
-
var videoDocSchema =
|
|
2171
|
-
_id:
|
|
2172
|
-
_creationTime:
|
|
2173
|
-
companyId:
|
|
2174
|
-
muxAssetId:
|
|
2175
|
-
muxPlaybackId:
|
|
2176
|
-
muxUploadId:
|
|
2177
|
-
name:
|
|
2178
|
-
description:
|
|
2179
|
-
tags:
|
|
2180
|
-
source:
|
|
2181
|
-
externalId:
|
|
2182
|
-
sourceId:
|
|
2183
|
-
width:
|
|
2184
|
-
height:
|
|
2185
|
-
aspectRatio:
|
|
2186
|
-
duration:
|
|
2187
|
-
transcript:
|
|
2188
|
-
transcriptSegments:
|
|
2189
|
-
scenes:
|
|
2190
|
-
descriptionEmbedding:
|
|
2191
|
-
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(),
|
|
2192
2035
|
status: videoStatusSchema,
|
|
2193
|
-
errorMessage:
|
|
2194
|
-
createdAt:
|
|
2195
|
-
updatedAt:
|
|
2196
|
-
thumbnailUrl:
|
|
2197
|
-
});
|
|
2198
|
-
var videosWebhookResponseSchema =
|
|
2199
|
-
var videosGetRequestSchema =
|
|
2200
|
-
var videosSearchRequestSchema =
|
|
2201
|
-
query:
|
|
2202
|
-
limit:
|
|
2203
|
-
tags:
|
|
2204
|
-
});
|
|
2205
|
-
var videoSearchResultSchema =
|
|
2206
|
-
_id:
|
|
2207
|
-
thumbnailUrl:
|
|
2208
|
-
name:
|
|
2209
|
-
description:
|
|
2210
|
-
tags:
|
|
2211
|
-
status:
|
|
2212
|
-
duration:
|
|
2213
|
-
muxPlaybackId:
|
|
2214
|
-
createdAt:
|
|
2215
|
-
});
|
|
2216
|
-
var videosSearchResponseSchema =
|
|
2217
|
-
var videosUploadResponseSchema =
|
|
2218
|
-
var videosDeleteRequestSchema =
|
|
2219
|
-
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) });
|
|
2220
2063
|
|
|
2221
2064
|
// src/commands/actions/complete.ts
|
|
2222
2065
|
import { defineCommand as defineCommand2 } from "citty";
|
|
@@ -4029,37 +3872,37 @@ var GEO_TARGET_CONSTANT_REGEX = /^geoTargetConstants\/\d+$/;
|
|
|
4029
3872
|
var LANGUAGE_CONSTANT_REGEX = /^languageConstants\/\d+$/;
|
|
4030
3873
|
|
|
4031
3874
|
// ../api/src/ads-google/ops.ts
|
|
4032
|
-
import { z as
|
|
4033
|
-
var tempRefSchema2 =
|
|
4034
|
-
var refSchema =
|
|
4035
|
-
|
|
4036
|
-
|
|
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"),
|
|
4037
3880
|
tempRefSchema2
|
|
4038
3881
|
]);
|
|
4039
3882
|
var targetRefSchema = refSchema;
|
|
4040
|
-
var microsSchema =
|
|
4041
|
-
var httpsUrlSchema2 =
|
|
4042
|
-
var customerIdSchema =
|
|
4043
|
-
var stageableStatusSchema2 =
|
|
4044
|
-
var matchTypeSchema =
|
|
4045
|
-
var keywordTextSchema =
|
|
4046
|
-
var budgetCreateSchema =
|
|
4047
|
-
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),
|
|
4048
3891
|
amountMicros: microsSchema,
|
|
4049
|
-
deliveryMethod:
|
|
4050
|
-
explicitlyShared:
|
|
3892
|
+
deliveryMethod: z7.enum(BUDGET_DELIVERY_METHODS).default("STANDARD"),
|
|
3893
|
+
explicitlyShared: z7.boolean().default(false)
|
|
4051
3894
|
});
|
|
4052
|
-
var budgetUpdateSchema =
|
|
4053
|
-
name:
|
|
3895
|
+
var budgetUpdateSchema = z7.object({
|
|
3896
|
+
name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.budget.nameMax).optional(),
|
|
4054
3897
|
amountMicros: microsSchema.optional(),
|
|
4055
|
-
deliveryMethod:
|
|
3898
|
+
deliveryMethod: z7.enum(BUDGET_DELIVERY_METHODS).optional()
|
|
4056
3899
|
}).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
|
|
4057
|
-
var biddingConfigSchema =
|
|
4058
|
-
type:
|
|
3900
|
+
var biddingConfigSchema = z7.object({
|
|
3901
|
+
type: z7.enum(BIDDING_STRATEGY_TYPES),
|
|
4059
3902
|
targetCpaMicros: microsSchema.optional(),
|
|
4060
|
-
targetRoas:
|
|
3903
|
+
targetRoas: z7.number().positive().optional(),
|
|
4061
3904
|
cpcBidCeilingMicros: microsSchema.optional(),
|
|
4062
|
-
enhancedCpcEnabled:
|
|
3905
|
+
enhancedCpcEnabled: z7.boolean().optional()
|
|
4063
3906
|
}).superRefine((p, ctx) => {
|
|
4064
3907
|
if (p.type === "TARGET_CPA" && p.targetCpaMicros === void 0) {
|
|
4065
3908
|
ctx.addIssue({ code: "custom", path: ["targetCpaMicros"], message: "TARGET_CPA needs targetCpaMicros" });
|
|
@@ -4068,17 +3911,17 @@ var biddingConfigSchema = z8.object({
|
|
|
4068
3911
|
ctx.addIssue({ code: "custom", path: ["targetRoas"], message: "TARGET_ROAS needs targetRoas" });
|
|
4069
3912
|
}
|
|
4070
3913
|
});
|
|
4071
|
-
var networkSettingsSchema =
|
|
4072
|
-
targetGoogleSearch:
|
|
4073
|
-
targetSearchNetwork:
|
|
4074
|
-
targetContentNetwork:
|
|
4075
|
-
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()
|
|
4076
3919
|
});
|
|
4077
|
-
var dateSchema =
|
|
4078
|
-
var campaignCreateSchema2 =
|
|
4079
|
-
name:
|
|
4080
|
-
channelType:
|
|
4081
|
-
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(),
|
|
4082
3925
|
budget: refSchema,
|
|
4083
3926
|
/** Inline standard bidding, or a portfolio strategy ref via biddingStrategy. */
|
|
4084
3927
|
bidding: biddingConfigSchema.optional(),
|
|
@@ -4087,7 +3930,7 @@ var campaignCreateSchema2 = z8.object({
|
|
|
4087
3930
|
startDate: dateSchema.optional(),
|
|
4088
3931
|
endDate: dateSchema.optional(),
|
|
4089
3932
|
/** Advisory Google Ads UI objective — drives warnings, not sent to the API. */
|
|
4090
|
-
objective:
|
|
3933
|
+
objective: z7.enum(CAMPAIGN_OBJECTIVES).optional(),
|
|
4091
3934
|
status: stageableStatusSchema2.default("PAUSED")
|
|
4092
3935
|
}).superRefine((p, ctx) => {
|
|
4093
3936
|
if (!p.bidding && !p.biddingStrategy) {
|
|
@@ -4111,129 +3954,129 @@ var campaignCreateSchema2 = z8.object({
|
|
|
4111
3954
|
ctx.addIssue({ code: "custom", path: ["endDate"], message: "endDate must be after startDate" });
|
|
4112
3955
|
}
|
|
4113
3956
|
});
|
|
4114
|
-
var campaignUpdateSchema2 =
|
|
4115
|
-
name:
|
|
3957
|
+
var campaignUpdateSchema2 = z7.object({
|
|
3958
|
+
name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.campaign.nameMax).optional(),
|
|
4116
3959
|
budget: refSchema.optional(),
|
|
4117
3960
|
bidding: biddingConfigSchema.optional(),
|
|
4118
3961
|
networkSettings: networkSettingsSchema.optional(),
|
|
4119
3962
|
startDate: dateSchema.optional(),
|
|
4120
3963
|
endDate: dateSchema.optional(),
|
|
4121
|
-
status:
|
|
3964
|
+
status: z7.enum(["ENABLED", "PAUSED", "REMOVED"]).optional()
|
|
4122
3965
|
}).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
|
|
4123
|
-
var adGroupCreateSchema =
|
|
4124
|
-
name:
|
|
3966
|
+
var adGroupCreateSchema = z7.object({
|
|
3967
|
+
name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.adGroup.nameMax),
|
|
4125
3968
|
campaign: refSchema,
|
|
4126
|
-
type:
|
|
3969
|
+
type: z7.enum(AD_GROUP_TYPES).default("SEARCH_STANDARD"),
|
|
4127
3970
|
cpcBidMicros: microsSchema.optional(),
|
|
4128
3971
|
status: stageableStatusSchema2.default("PAUSED")
|
|
4129
3972
|
});
|
|
4130
|
-
var adGroupUpdateSchema =
|
|
4131
|
-
name:
|
|
3973
|
+
var adGroupUpdateSchema = z7.object({
|
|
3974
|
+
name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.adGroup.nameMax).optional(),
|
|
4132
3975
|
cpcBidMicros: microsSchema.optional(),
|
|
4133
|
-
status:
|
|
3976
|
+
status: z7.enum(["ENABLED", "PAUSED", "REMOVED"]).optional()
|
|
4134
3977
|
}).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
|
|
4135
|
-
var keywordAddSchema =
|
|
3978
|
+
var keywordAddSchema = z7.object({
|
|
4136
3979
|
adGroup: refSchema,
|
|
4137
3980
|
text: keywordTextSchema,
|
|
4138
3981
|
matchType: matchTypeSchema,
|
|
4139
3982
|
cpcBidMicros: microsSchema.optional(),
|
|
4140
|
-
finalUrls:
|
|
3983
|
+
finalUrls: z7.array(httpsUrlSchema2).optional(),
|
|
4141
3984
|
status: stageableStatusSchema2.default("ENABLED")
|
|
4142
3985
|
});
|
|
4143
|
-
var keywordUpdateSchema =
|
|
3986
|
+
var keywordUpdateSchema = z7.object({
|
|
4144
3987
|
cpcBidMicros: microsSchema.optional(),
|
|
4145
|
-
finalUrls:
|
|
4146
|
-
status:
|
|
3988
|
+
finalUrls: z7.array(httpsUrlSchema2).optional(),
|
|
3989
|
+
status: z7.enum(["ENABLED", "PAUSED", "REMOVED"]).optional()
|
|
4147
3990
|
}).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
|
|
4148
|
-
var negativeKeywordAddSchema =
|
|
4149
|
-
level:
|
|
3991
|
+
var negativeKeywordAddSchema = z7.object({
|
|
3992
|
+
level: z7.enum(["adGroup", "campaign"]),
|
|
4150
3993
|
parent: refSchema,
|
|
4151
3994
|
text: keywordTextSchema,
|
|
4152
3995
|
matchType: matchTypeSchema
|
|
4153
3996
|
});
|
|
4154
|
-
var sharedSetCreateSchema =
|
|
4155
|
-
name:
|
|
4156
|
-
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")
|
|
4157
4000
|
});
|
|
4158
|
-
var sharedSetMemberAddSchema =
|
|
4001
|
+
var sharedSetMemberAddSchema = z7.object({
|
|
4159
4002
|
sharedSet: refSchema,
|
|
4160
4003
|
text: keywordTextSchema,
|
|
4161
4004
|
matchType: matchTypeSchema
|
|
4162
4005
|
});
|
|
4163
|
-
var campaignSharedSetAttachSchema =
|
|
4006
|
+
var campaignSharedSetAttachSchema = z7.object({
|
|
4164
4007
|
campaign: refSchema,
|
|
4165
4008
|
sharedSet: refSchema
|
|
4166
4009
|
});
|
|
4167
|
-
var adTextAssetSchema =
|
|
4168
|
-
text:
|
|
4169
|
-
pinnedField:
|
|
4010
|
+
var adTextAssetSchema = z7.object({
|
|
4011
|
+
text: z7.string().min(1),
|
|
4012
|
+
pinnedField: z7.enum(PINNED_FIELDS).optional()
|
|
4170
4013
|
});
|
|
4171
|
-
var responsiveSearchAdSchema =
|
|
4172
|
-
format:
|
|
4173
|
-
headlines:
|
|
4014
|
+
var responsiveSearchAdSchema = z7.object({
|
|
4015
|
+
format: z7.literal("responsiveSearch"),
|
|
4016
|
+
headlines: z7.array(
|
|
4174
4017
|
adTextAssetSchema.refine(
|
|
4175
4018
|
(a) => a.text.length <= GOOGLE_ADS_LIMITS.responsiveSearchAd.headlineTextMax,
|
|
4176
4019
|
"headline exceeds 30 chars"
|
|
4177
4020
|
)
|
|
4178
4021
|
).min(GOOGLE_ADS_LIMITS.responsiveSearchAd.headlinesMin).max(GOOGLE_ADS_LIMITS.responsiveSearchAd.headlinesMax),
|
|
4179
|
-
descriptions:
|
|
4022
|
+
descriptions: z7.array(
|
|
4180
4023
|
adTextAssetSchema.refine(
|
|
4181
4024
|
(a) => a.text.length <= GOOGLE_ADS_LIMITS.responsiveSearchAd.descriptionTextMax,
|
|
4182
4025
|
"description exceeds 90 chars"
|
|
4183
4026
|
)
|
|
4184
4027
|
).min(GOOGLE_ADS_LIMITS.responsiveSearchAd.descriptionsMin).max(GOOGLE_ADS_LIMITS.responsiveSearchAd.descriptionsMax),
|
|
4185
|
-
path1:
|
|
4186
|
-
path2:
|
|
4187
|
-
finalUrls:
|
|
4188
|
-
});
|
|
4189
|
-
var responsiveDisplayAdSchema =
|
|
4190
|
-
format:
|
|
4191
|
-
headlines:
|
|
4192
|
-
longHeadline:
|
|
4193
|
-
descriptions:
|
|
4194
|
-
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),
|
|
4195
4038
|
// A Responsive Display Ad's images are fields on the ad's own content (never campaign-level
|
|
4196
4039
|
// asset links). Google requires ≥1 landscape marketing image (1.91:1) AND ≥1 square marketing
|
|
4197
4040
|
// image (1:1) to serve; the logo images are optional.
|
|
4198
|
-
marketingImageAssets:
|
|
4199
|
-
squareMarketingImageAssets:
|
|
4200
|
-
logoImageAssets:
|
|
4201
|
-
finalUrls:
|
|
4202
|
-
});
|
|
4203
|
-
var callAdSchema =
|
|
4204
|
-
format:
|
|
4205
|
-
countryCode:
|
|
4206
|
-
phoneNumber:
|
|
4207
|
-
headline1:
|
|
4208
|
-
headline2:
|
|
4209
|
-
description1:
|
|
4210
|
-
description2:
|
|
4211
|
-
businessName:
|
|
4212
|
-
finalUrls:
|
|
4213
|
-
});
|
|
4214
|
-
var appAdSchema =
|
|
4215
|
-
format:
|
|
4216
|
-
headlines:
|
|
4217
|
-
descriptions:
|
|
4218
|
-
});
|
|
4219
|
-
var videoAdSchema =
|
|
4220
|
-
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"),
|
|
4221
4064
|
// A raw YouTube id is not a publishable Google Ads reference — the video must be staged as
|
|
4222
4065
|
// its own `google.asset.create` (type: youtubeVideo) first, then referenced here by asset ref.
|
|
4223
|
-
videoAssets:
|
|
4224
|
-
finalUrls:
|
|
4225
|
-
});
|
|
4226
|
-
var demandGenAdSchema =
|
|
4227
|
-
format:
|
|
4228
|
-
headlines:
|
|
4229
|
-
descriptions:
|
|
4230
|
-
businessName:
|
|
4231
|
-
finalUrls:
|
|
4232
|
-
imageAssets:
|
|
4233
|
-
squareImageAssets:
|
|
4234
|
-
logoImageAssets:
|
|
4235
|
-
});
|
|
4236
|
-
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", [
|
|
4237
4080
|
responsiveSearchAdSchema,
|
|
4238
4081
|
responsiveDisplayAdSchema,
|
|
4239
4082
|
callAdSchema,
|
|
@@ -4241,45 +4084,45 @@ var adContentSchema = z8.discriminatedUnion("format", [
|
|
|
4241
4084
|
videoAdSchema,
|
|
4242
4085
|
demandGenAdSchema
|
|
4243
4086
|
]);
|
|
4244
|
-
var adCreateSchema =
|
|
4087
|
+
var adCreateSchema = z7.object({
|
|
4245
4088
|
adGroup: refSchema,
|
|
4246
4089
|
status: stageableStatusSchema2.default("PAUSED"),
|
|
4247
4090
|
content: adContentSchema
|
|
4248
4091
|
});
|
|
4249
|
-
var adUpdateSchema =
|
|
4250
|
-
status:
|
|
4092
|
+
var adUpdateSchema = z7.object({
|
|
4093
|
+
status: z7.enum(["ENABLED", "PAUSED", "REMOVED"]).optional(),
|
|
4251
4094
|
/** Whole-content replacement for RSA-like formats; re-validated against adContentSchema. */
|
|
4252
|
-
content:
|
|
4095
|
+
content: z7.record(z7.string(), z7.unknown()).optional()
|
|
4253
4096
|
}).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
|
|
4254
|
-
var textAssetSchema =
|
|
4255
|
-
var imageAssetSchema =
|
|
4256
|
-
type:
|
|
4257
|
-
imageId:
|
|
4258
|
-
name:
|
|
4259
|
-
});
|
|
4260
|
-
var youtubeVideoAssetSchema =
|
|
4261
|
-
type:
|
|
4262
|
-
youtubeVideoId:
|
|
4263
|
-
name:
|
|
4264
|
-
});
|
|
4265
|
-
var sitelinkAssetSchema =
|
|
4266
|
-
type:
|
|
4267
|
-
linkText:
|
|
4268
|
-
description1:
|
|
4269
|
-
description2:
|
|
4270
|
-
finalUrls:
|
|
4271
|
-
});
|
|
4272
|
-
var calloutAssetSchema =
|
|
4273
|
-
type:
|
|
4274
|
-
calloutText:
|
|
4275
|
-
});
|
|
4276
|
-
var structuredSnippetAssetSchema =
|
|
4277
|
-
type:
|
|
4278
|
-
header:
|
|
4279
|
-
values:
|
|
4280
|
-
});
|
|
4281
|
-
var callToActionAssetSchema =
|
|
4282
|
-
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", [
|
|
4283
4126
|
textAssetSchema,
|
|
4284
4127
|
imageAssetSchema,
|
|
4285
4128
|
youtubeVideoAssetSchema,
|
|
@@ -4288,136 +4131,136 @@ var assetCreateSchema = z8.discriminatedUnion("type", [
|
|
|
4288
4131
|
structuredSnippetAssetSchema,
|
|
4289
4132
|
callToActionAssetSchema
|
|
4290
4133
|
]);
|
|
4291
|
-
var assetUpdateSchema =
|
|
4292
|
-
name:
|
|
4293
|
-
linkText:
|
|
4294
|
-
description1:
|
|
4295
|
-
description2:
|
|
4296
|
-
finalUrls:
|
|
4297
|
-
calloutText:
|
|
4298
|
-
header:
|
|
4299
|
-
values:
|
|
4300
|
-
callToAction:
|
|
4301
|
-
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()
|
|
4302
4145
|
}).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
|
|
4303
|
-
var assetLinkAttachSchema =
|
|
4304
|
-
level:
|
|
4146
|
+
var assetLinkAttachSchema = z7.object({
|
|
4147
|
+
level: z7.enum(["campaign", "adGroup", "customer"]),
|
|
4305
4148
|
parent: refSchema.optional(),
|
|
4306
4149
|
asset: refSchema,
|
|
4307
|
-
fieldType:
|
|
4150
|
+
fieldType: z7.enum(ASSET_FIELD_TYPES)
|
|
4308
4151
|
}).superRefine((value, ctx) => {
|
|
4309
4152
|
if (value.level !== "customer" && !value.parent) {
|
|
4310
4153
|
ctx.addIssue({
|
|
4311
|
-
code:
|
|
4154
|
+
code: z7.ZodIssueCode.custom,
|
|
4312
4155
|
path: ["parent"],
|
|
4313
4156
|
message: `parent is required for a ${value.level}-level asset link (--parent-ref)`
|
|
4314
4157
|
});
|
|
4315
4158
|
}
|
|
4316
4159
|
});
|
|
4317
|
-
var assetGroupCreateSchema =
|
|
4160
|
+
var assetGroupCreateSchema = z7.object({
|
|
4318
4161
|
campaign: refSchema,
|
|
4319
|
-
name:
|
|
4320
|
-
finalUrls:
|
|
4321
|
-
headlines:
|
|
4322
|
-
longHeadlines:
|
|
4323
|
-
descriptions:
|
|
4324
|
-
businessName:
|
|
4325
|
-
imageAssets:
|
|
4326
|
-
squareImageAssets:
|
|
4327
|
-
logoAssets:
|
|
4328
|
-
status:
|
|
4329
|
-
});
|
|
4330
|
-
var assetGroupUpdateSchema =
|
|
4331
|
-
name:
|
|
4332
|
-
finalUrls:
|
|
4333
|
-
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()
|
|
4334
4177
|
}).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
|
|
4335
|
-
var audienceCreateSchema2 =
|
|
4336
|
-
name:
|
|
4337
|
-
type:
|
|
4338
|
-
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(),
|
|
4339
4182
|
/** Customer-match members (crm-based) — file-first for large lists. */
|
|
4340
|
-
members:
|
|
4341
|
-
sourceFileRef:
|
|
4183
|
+
members: z7.array(z7.record(z7.string(), z7.string())).optional(),
|
|
4184
|
+
sourceFileRef: z7.string().optional()
|
|
4342
4185
|
});
|
|
4343
|
-
var audienceCriterionAttachSchema =
|
|
4344
|
-
level:
|
|
4186
|
+
var audienceCriterionAttachSchema = z7.object({
|
|
4187
|
+
level: z7.enum(["campaign", "adGroup"]),
|
|
4345
4188
|
parent: refSchema,
|
|
4346
4189
|
userList: refSchema,
|
|
4347
|
-
negative:
|
|
4190
|
+
negative: z7.boolean().default(false)
|
|
4348
4191
|
});
|
|
4349
|
-
var conversionActionCreateSchema =
|
|
4350
|
-
name:
|
|
4351
|
-
type:
|
|
4352
|
-
category:
|
|
4353
|
-
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"),
|
|
4354
4197
|
defaultValueMicros: microsSchema.optional(),
|
|
4355
|
-
defaultCurrencyCode:
|
|
4356
|
-
clickThroughLookbackWindowDays:
|
|
4357
|
-
viewThroughLookbackWindowDays:
|
|
4358
|
-
status:
|
|
4359
|
-
});
|
|
4360
|
-
var conversionActionUpdateSchema =
|
|
4361
|
-
name:
|
|
4362
|
-
category:
|
|
4363
|
-
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(),
|
|
4364
4207
|
defaultValueMicros: microsSchema.optional(),
|
|
4365
|
-
defaultCurrencyCode:
|
|
4366
|
-
clickThroughLookbackWindowDays:
|
|
4367
|
-
viewThroughLookbackWindowDays:
|
|
4368
|
-
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()
|
|
4369
4212
|
}).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
|
|
4370
|
-
var biddingStrategyCreateSchema =
|
|
4371
|
-
name:
|
|
4213
|
+
var biddingStrategyCreateSchema = z7.object({
|
|
4214
|
+
name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.biddingStrategy.nameMax),
|
|
4372
4215
|
config: biddingConfigSchema
|
|
4373
4216
|
}).superRefine((p, ctx) => {
|
|
4374
4217
|
if (p.config.type === "MANUAL_CPC") {
|
|
4375
4218
|
ctx.addIssue({ code: "custom", path: ["config", "type"], message: "portfolio strategies cannot be Manual CPC" });
|
|
4376
4219
|
}
|
|
4377
4220
|
});
|
|
4378
|
-
var biddingStrategyUpdateSchema =
|
|
4379
|
-
name:
|
|
4221
|
+
var biddingStrategyUpdateSchema = z7.object({
|
|
4222
|
+
name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.biddingStrategy.nameMax).optional(),
|
|
4380
4223
|
config: biddingConfigSchema.optional()
|
|
4381
4224
|
}).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
|
|
4382
|
-
var labelCreateSchema =
|
|
4383
|
-
name:
|
|
4384
|
-
backgroundColor:
|
|
4385
|
-
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()
|
|
4386
4229
|
});
|
|
4387
|
-
var labelAttachSchema =
|
|
4388
|
-
level:
|
|
4230
|
+
var labelAttachSchema = z7.object({
|
|
4231
|
+
level: z7.enum(["campaign", "adGroup", "ad"]),
|
|
4389
4232
|
parent: refSchema,
|
|
4390
4233
|
label: refSchema
|
|
4391
4234
|
});
|
|
4392
|
-
var locationCriterionSchema =
|
|
4393
|
-
criterionType:
|
|
4394
|
-
geoTargetConstant:
|
|
4395
|
-
});
|
|
4396
|
-
var languageCriterionSchema =
|
|
4397
|
-
criterionType:
|
|
4398
|
-
languageConstant:
|
|
4399
|
-
});
|
|
4400
|
-
var adScheduleCriterionSchema =
|
|
4401
|
-
criterionType:
|
|
4402
|
-
dayOfWeek:
|
|
4403
|
-
startHour:
|
|
4404
|
-
startMinute:
|
|
4405
|
-
endHour:
|
|
4406
|
-
endMinute:
|
|
4407
|
-
});
|
|
4408
|
-
var deviceCriterionSchema =
|
|
4409
|
-
criterionType:
|
|
4410
|
-
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),
|
|
4411
4254
|
// Google's `CampaignCriterion.bid_modifier`: "The modifier must be in the range 0.1 - 10.0. Use 0
|
|
4412
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.
|
|
4413
|
-
bidModifier:
|
|
4256
|
+
bidModifier: z7.number().min(0).max(10).optional().refine((v) => v === void 0 || v === 0 || v >= 0.1, {
|
|
4414
4257
|
message: "bid modifier must be 0 (exclude the device) or between 0.1 and 10.0"
|
|
4415
4258
|
})
|
|
4416
4259
|
});
|
|
4417
|
-
var campaignCriterionAddSchema =
|
|
4260
|
+
var campaignCriterionAddSchema = z7.object({
|
|
4418
4261
|
campaign: refSchema,
|
|
4419
|
-
negative:
|
|
4420
|
-
criterion:
|
|
4262
|
+
negative: z7.boolean().default(false),
|
|
4263
|
+
criterion: z7.discriminatedUnion("criterionType", [
|
|
4421
4264
|
locationCriterionSchema,
|
|
4422
4265
|
languageCriterionSchema,
|
|
4423
4266
|
adScheduleCriterionSchema,
|
|
@@ -4427,7 +4270,7 @@ var campaignCriterionAddSchema = z8.object({
|
|
|
4427
4270
|
const c = val.criterion;
|
|
4428
4271
|
if (c.criterionType === "adSchedule" && c.endHour === 24 && c.endMinute !== "ZERO") {
|
|
4429
4272
|
ctx.addIssue({
|
|
4430
|
-
code:
|
|
4273
|
+
code: z7.ZodIssueCode.custom,
|
|
4431
4274
|
message: "endHour 24 (midnight) cannot have a non-zero endMinute",
|
|
4432
4275
|
path: ["criterion", "endMinute"]
|
|
4433
4276
|
});
|
|
@@ -4479,17 +4322,17 @@ var GOOGLE_DRAFT_OP_KINDS = [
|
|
|
4479
4322
|
"google.campaignCriterion.add",
|
|
4480
4323
|
"google.campaignCriterion.remove"
|
|
4481
4324
|
];
|
|
4482
|
-
var googleDraftOpKindSchema =
|
|
4325
|
+
var googleDraftOpKindSchema = z7.enum(GOOGLE_DRAFT_OP_KINDS);
|
|
4483
4326
|
function createOp2(kind, payload) {
|
|
4484
|
-
return
|
|
4327
|
+
return z7.object({ kind: z7.literal(kind), customerId: customerIdSchema, payload });
|
|
4485
4328
|
}
|
|
4486
4329
|
function updateOp2(kind, payload) {
|
|
4487
|
-
return
|
|
4330
|
+
return z7.object({ kind: z7.literal(kind), customerId: customerIdSchema, target: targetRefSchema, payload });
|
|
4488
4331
|
}
|
|
4489
4332
|
function targetOp(kind) {
|
|
4490
|
-
return
|
|
4333
|
+
return z7.object({ kind: z7.literal(kind), customerId: customerIdSchema, target: targetRefSchema });
|
|
4491
4334
|
}
|
|
4492
|
-
var googleDraftOpInputSchema =
|
|
4335
|
+
var googleDraftOpInputSchema = z7.discriminatedUnion("kind", [
|
|
4493
4336
|
createOp2("google.budget.create", budgetCreateSchema),
|
|
4494
4337
|
updateOp2("google.budget.update", budgetUpdateSchema),
|
|
4495
4338
|
createOp2("google.campaign.create", campaignCreateSchema2),
|
|
@@ -4537,132 +4380,132 @@ var googleDraftOpInputSchema = z8.discriminatedUnion("kind", [
|
|
|
4537
4380
|
]);
|
|
4538
4381
|
|
|
4539
4382
|
// ../api/src/ads-google/wire.ts
|
|
4540
|
-
import { z as
|
|
4541
|
-
var googleWriteModeSchema =
|
|
4542
|
-
var googleDraftOpResultSchema =
|
|
4543
|
-
status:
|
|
4544
|
-
resourceName:
|
|
4545
|
-
error:
|
|
4546
|
-
skippedBecause:
|
|
4547
|
-
executedAt:
|
|
4548
|
-
});
|
|
4549
|
-
var googleDraftStageRequestSchema =
|
|
4550
|
-
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(),
|
|
4551
4394
|
op: googleDraftOpInputSchema
|
|
4552
4395
|
});
|
|
4553
|
-
var googleDraftStageResponseSchema =
|
|
4554
|
-
staged:
|
|
4555
|
-
ref:
|
|
4396
|
+
var googleDraftStageResponseSchema = z8.object({
|
|
4397
|
+
staged: z8.literal(true),
|
|
4398
|
+
ref: z8.string(),
|
|
4556
4399
|
kind: googleDraftOpKindSchema,
|
|
4557
4400
|
mode: googleWriteModeSchema,
|
|
4558
|
-
dependsOn:
|
|
4559
|
-
summary:
|
|
4560
|
-
warnings:
|
|
4401
|
+
dependsOn: z8.array(z8.string()),
|
|
4402
|
+
summary: z8.string(),
|
|
4403
|
+
warnings: z8.array(z8.string()),
|
|
4561
4404
|
/** True when the op amended an already-staged op in place instead of appending a new one. */
|
|
4562
|
-
amended:
|
|
4405
|
+
amended: z8.boolean().optional()
|
|
4563
4406
|
});
|
|
4564
|
-
var googleDraftAmendRequestSchema =
|
|
4565
|
-
chatId:
|
|
4566
|
-
ref:
|
|
4567
|
-
patch:
|
|
4407
|
+
var googleDraftAmendRequestSchema = z8.object({
|
|
4408
|
+
chatId: z8.string(),
|
|
4409
|
+
ref: z8.string(),
|
|
4410
|
+
patch: z8.record(z8.string(), z8.unknown())
|
|
4568
4411
|
});
|
|
4569
|
-
var googleDraftShowRequestSchema =
|
|
4570
|
-
chatId:
|
|
4571
|
-
ref:
|
|
4412
|
+
var googleDraftShowRequestSchema = z8.object({
|
|
4413
|
+
chatId: z8.string(),
|
|
4414
|
+
ref: z8.string()
|
|
4572
4415
|
});
|
|
4573
4416
|
var GOOGLE_DRAFT_BATCH_MAX = 500;
|
|
4574
|
-
var googleDraftStageBatchRequestSchema =
|
|
4575
|
-
chatId:
|
|
4576
|
-
ops:
|
|
4417
|
+
var googleDraftStageBatchRequestSchema = z8.object({
|
|
4418
|
+
chatId: z8.string(),
|
|
4419
|
+
ops: z8.array(googleDraftOpInputSchema).min(1).max(GOOGLE_DRAFT_BATCH_MAX)
|
|
4577
4420
|
});
|
|
4578
|
-
var googleDraftStageBatchResponseSchema =
|
|
4579
|
-
staged:
|
|
4421
|
+
var googleDraftStageBatchResponseSchema = z8.object({
|
|
4422
|
+
staged: z8.literal(true),
|
|
4580
4423
|
mode: googleWriteModeSchema,
|
|
4581
|
-
count:
|
|
4582
|
-
ops:
|
|
4583
|
-
|
|
4584
|
-
ref:
|
|
4424
|
+
count: z8.number(),
|
|
4425
|
+
ops: z8.array(
|
|
4426
|
+
z8.object({
|
|
4427
|
+
ref: z8.string(),
|
|
4585
4428
|
kind: googleDraftOpKindSchema,
|
|
4586
|
-
dependsOn:
|
|
4587
|
-
summary:
|
|
4588
|
-
warnings:
|
|
4429
|
+
dependsOn: z8.array(z8.string()),
|
|
4430
|
+
summary: z8.string(),
|
|
4431
|
+
warnings: z8.array(z8.string())
|
|
4589
4432
|
})
|
|
4590
4433
|
)
|
|
4591
4434
|
});
|
|
4592
|
-
var googleDraftOpViewSchema =
|
|
4593
|
-
ref:
|
|
4435
|
+
var googleDraftOpViewSchema = z8.object({
|
|
4436
|
+
ref: z8.string(),
|
|
4594
4437
|
kind: googleDraftOpKindSchema,
|
|
4595
|
-
customerId:
|
|
4596
|
-
target:
|
|
4597
|
-
dependsOn:
|
|
4598
|
-
summary:
|
|
4599
|
-
stagedAt:
|
|
4438
|
+
customerId: z8.string(),
|
|
4439
|
+
target: z8.string().optional(),
|
|
4440
|
+
dependsOn: z8.array(z8.string()),
|
|
4441
|
+
summary: z8.string(),
|
|
4442
|
+
stagedAt: z8.number(),
|
|
4600
4443
|
result: googleDraftOpResultSchema.optional()
|
|
4601
4444
|
});
|
|
4602
|
-
var googleDraftShowResponseSchema =
|
|
4445
|
+
var googleDraftShowResponseSchema = z8.object({
|
|
4603
4446
|
op: googleDraftOpViewSchema.extend({
|
|
4604
|
-
payload:
|
|
4605
|
-
warnings:
|
|
4606
|
-
annotations:
|
|
4447
|
+
payload: z8.unknown().optional(),
|
|
4448
|
+
warnings: z8.array(z8.string()).optional(),
|
|
4449
|
+
annotations: z8.unknown().optional()
|
|
4607
4450
|
})
|
|
4608
4451
|
});
|
|
4609
|
-
var googleDraftListRequestSchema =
|
|
4610
|
-
chatId:
|
|
4452
|
+
var googleDraftListRequestSchema = z8.object({
|
|
4453
|
+
chatId: z8.string()
|
|
4611
4454
|
});
|
|
4612
|
-
var googleDraftAdvisorySchema =
|
|
4613
|
-
scope:
|
|
4614
|
-
message:
|
|
4455
|
+
var googleDraftAdvisorySchema = z8.object({
|
|
4456
|
+
scope: z8.enum(["campaign", "adGroup"]),
|
|
4457
|
+
message: z8.string()
|
|
4615
4458
|
});
|
|
4616
|
-
var googleDraftStatusCollectionSchema =
|
|
4617
|
-
label:
|
|
4618
|
-
added:
|
|
4619
|
-
removed:
|
|
4620
|
-
existing:
|
|
4459
|
+
var googleDraftStatusCollectionSchema = z8.object({
|
|
4460
|
+
label: z8.string(),
|
|
4461
|
+
added: z8.number(),
|
|
4462
|
+
removed: z8.number(),
|
|
4463
|
+
existing: z8.number()
|
|
4621
4464
|
});
|
|
4622
|
-
var googleDraftChangeOperationSchema =
|
|
4623
|
-
var googleDraftStatusNodeSchema =
|
|
4624
|
-
() =>
|
|
4625
|
-
entity:
|
|
4626
|
-
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(),
|
|
4627
4470
|
operation: googleDraftChangeOperationSchema.optional(),
|
|
4628
|
-
existing:
|
|
4629
|
-
collections:
|
|
4630
|
-
children:
|
|
4631
|
-
warnings:
|
|
4471
|
+
existing: z8.boolean(),
|
|
4472
|
+
collections: z8.array(googleDraftStatusCollectionSchema),
|
|
4473
|
+
children: z8.array(googleDraftStatusNodeSchema),
|
|
4474
|
+
warnings: z8.array(z8.string()).optional()
|
|
4632
4475
|
})
|
|
4633
4476
|
);
|
|
4634
|
-
var googleDraftListResponseSchema =
|
|
4635
|
-
status:
|
|
4477
|
+
var googleDraftListResponseSchema = z8.object({
|
|
4478
|
+
status: z8.enum(["active", "publishing", "applied", "discarded", "none"]),
|
|
4636
4479
|
mode: googleWriteModeSchema,
|
|
4637
|
-
count:
|
|
4638
|
-
ops:
|
|
4480
|
+
count: z8.number(),
|
|
4481
|
+
ops: z8.array(googleDraftOpViewSchema),
|
|
4639
4482
|
/** Grouped campaign ▸ ad group ▸ ad tree for the readable CLI status view. */
|
|
4640
|
-
tree:
|
|
4483
|
+
tree: z8.array(googleDraftStatusNodeSchema).optional(),
|
|
4641
4484
|
/** Non-blocking completeness advisories for the whole draft. */
|
|
4642
|
-
advisories:
|
|
4485
|
+
advisories: z8.array(googleDraftAdvisorySchema).optional()
|
|
4643
4486
|
});
|
|
4644
|
-
var googleDraftRemoveRequestSchema =
|
|
4645
|
-
chatId:
|
|
4646
|
-
ref:
|
|
4487
|
+
var googleDraftRemoveRequestSchema = z8.object({
|
|
4488
|
+
chatId: z8.string(),
|
|
4489
|
+
ref: z8.string()
|
|
4647
4490
|
});
|
|
4648
|
-
var googleDraftRemoveResponseSchema =
|
|
4491
|
+
var googleDraftRemoveResponseSchema = z8.object({
|
|
4649
4492
|
/** The requested ref plus any dependents removed by cascade. */
|
|
4650
|
-
removed:
|
|
4493
|
+
removed: z8.array(z8.string())
|
|
4651
4494
|
});
|
|
4652
|
-
var googleDraftClearRequestSchema =
|
|
4653
|
-
chatId:
|
|
4495
|
+
var googleDraftClearRequestSchema = z8.object({
|
|
4496
|
+
chatId: z8.string()
|
|
4654
4497
|
});
|
|
4655
|
-
var googleDraftClearResponseSchema =
|
|
4656
|
-
cleared:
|
|
4498
|
+
var googleDraftClearResponseSchema = z8.object({
|
|
4499
|
+
cleared: z8.number()
|
|
4657
4500
|
});
|
|
4658
|
-
var googleFieldErrorSchema =
|
|
4659
|
-
path:
|
|
4660
|
-
message:
|
|
4501
|
+
var googleFieldErrorSchema = z8.object({
|
|
4502
|
+
path: z8.string(),
|
|
4503
|
+
message: z8.string()
|
|
4661
4504
|
});
|
|
4662
|
-
var googleDraftErrorResponseSchema =
|
|
4663
|
-
code:
|
|
4664
|
-
error:
|
|
4665
|
-
fields:
|
|
4505
|
+
var googleDraftErrorResponseSchema = z8.object({
|
|
4506
|
+
code: z8.string(),
|
|
4507
|
+
error: z8.string(),
|
|
4508
|
+
fields: z8.array(googleFieldErrorSchema).optional()
|
|
4666
4509
|
});
|
|
4667
4510
|
|
|
4668
4511
|
// src/commands/ads/google/draft-status.ts
|
|
@@ -4827,11 +4670,11 @@ function rawTextEntries(value) {
|
|
|
4827
4670
|
const values = Array.isArray(value) ? value : typeof value === "string" ? [value] : [];
|
|
4828
4671
|
return values.filter((v) => typeof v === "string").flatMap((v) => v.split(",")).map((v) => v.trim()).filter(Boolean);
|
|
4829
4672
|
}
|
|
4830
|
-
function rawFileEntries(
|
|
4831
|
-
if (typeof
|
|
4673
|
+
function rawFileEntries(path14) {
|
|
4674
|
+
if (typeof path14 !== "string" || path14.length === 0) {
|
|
4832
4675
|
return [];
|
|
4833
4676
|
}
|
|
4834
|
-
return readFileSync2(
|
|
4677
|
+
return readFileSync2(path14, "utf8").split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#"));
|
|
4835
4678
|
}
|
|
4836
4679
|
function keywordEntries(args) {
|
|
4837
4680
|
const defaultMatch = typeof args["match-type"] === "string" ? args["match-type"].toUpperCase() : void 0;
|
|
@@ -4854,19 +4697,19 @@ function keywordEntries(args) {
|
|
|
4854
4697
|
}
|
|
4855
4698
|
return entries;
|
|
4856
4699
|
}
|
|
4857
|
-
function loadJsonFileArg(
|
|
4858
|
-
if (typeof
|
|
4700
|
+
function loadJsonFileArg(path14) {
|
|
4701
|
+
if (typeof path14 !== "string" || path14.length === 0) {
|
|
4859
4702
|
return {};
|
|
4860
4703
|
}
|
|
4861
4704
|
try {
|
|
4862
|
-
const parsed = JSON.parse(readFileSync2(
|
|
4705
|
+
const parsed = JSON.parse(readFileSync2(path14, "utf8"));
|
|
4863
4706
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
4864
|
-
failWriteValidation(`${
|
|
4707
|
+
failWriteValidation(`${path14} must contain a JSON object`);
|
|
4865
4708
|
}
|
|
4866
4709
|
return parsed;
|
|
4867
4710
|
} catch (err) {
|
|
4868
4711
|
if (err instanceof SyntaxError) {
|
|
4869
|
-
failWriteValidation(`${
|
|
4712
|
+
failWriteValidation(`${path14} is not valid JSON: ${err.message}`);
|
|
4870
4713
|
}
|
|
4871
4714
|
throw err;
|
|
4872
4715
|
}
|
|
@@ -4977,10 +4820,10 @@ async function stageUpdate(kind, customerId, target, payload) {
|
|
|
4977
4820
|
async function stageTarget(kind, customerId, target) {
|
|
4978
4821
|
await stageGoogleOp({ kind, customerId, target });
|
|
4979
4822
|
}
|
|
4980
|
-
async function draftAction(
|
|
4823
|
+
async function draftAction(path14, body) {
|
|
4981
4824
|
try {
|
|
4982
4825
|
const chatId = requireChatId();
|
|
4983
|
-
const response = await apiPost(
|
|
4826
|
+
const response = await apiPost(path14, { chatId, ...body });
|
|
4984
4827
|
writeJsonEnvelope(response);
|
|
4985
4828
|
} catch (err) {
|
|
4986
4829
|
handleGoogleError(err);
|
|
@@ -8735,19 +8578,19 @@ function failWriteValidation2(message) {
|
|
|
8735
8578
|
writeJsonEnvelope({ ok: false, error: { code: "VALIDATION_ERROR", message } });
|
|
8736
8579
|
process.exit(1);
|
|
8737
8580
|
}
|
|
8738
|
-
function loadJsonFileArg2(
|
|
8739
|
-
if (typeof
|
|
8581
|
+
function loadJsonFileArg2(path14) {
|
|
8582
|
+
if (typeof path14 !== "string" || path14.length === 0) {
|
|
8740
8583
|
return {};
|
|
8741
8584
|
}
|
|
8742
8585
|
try {
|
|
8743
|
-
const parsed = JSON.parse(readFileSync6(
|
|
8586
|
+
const parsed = JSON.parse(readFileSync6(path14, "utf8"));
|
|
8744
8587
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
8745
|
-
failWriteValidation2(`${
|
|
8588
|
+
failWriteValidation2(`${path14} must contain a JSON object`);
|
|
8746
8589
|
}
|
|
8747
8590
|
return parsed;
|
|
8748
8591
|
} catch (err) {
|
|
8749
8592
|
if (err instanceof SyntaxError) {
|
|
8750
|
-
failWriteValidation2(`${
|
|
8593
|
+
failWriteValidation2(`${path14} is not valid JSON: ${err.message}`);
|
|
8751
8594
|
}
|
|
8752
8595
|
throw err;
|
|
8753
8596
|
}
|
|
@@ -8832,15 +8675,15 @@ function parseLocaleFlag(value) {
|
|
|
8832
8675
|
}
|
|
8833
8676
|
return { language: match[1], country: match[2].toUpperCase() };
|
|
8834
8677
|
}
|
|
8835
|
-
function loadTargetingFileArg(
|
|
8836
|
-
if (typeof
|
|
8678
|
+
function loadTargetingFileArg(path14) {
|
|
8679
|
+
if (typeof path14 !== "string" || path14.length === 0) {
|
|
8837
8680
|
return void 0;
|
|
8838
8681
|
}
|
|
8839
|
-
const parsed = loadJsonFileArg2(
|
|
8682
|
+
const parsed = loadJsonFileArg2(path14);
|
|
8840
8683
|
const criteria = parsed.targetingCriteria ?? parsed;
|
|
8841
8684
|
if (!criteria.include) {
|
|
8842
8685
|
failWriteValidation2(
|
|
8843
|
-
`${
|
|
8686
|
+
`${path14} must contain targeting criteria with an "include" block (see baker schema ads.linkedin.campaigns.create)`
|
|
8844
8687
|
);
|
|
8845
8688
|
}
|
|
8846
8689
|
return criteria;
|
|
@@ -8875,14 +8718,14 @@ function parseCsvLine(line) {
|
|
|
8875
8718
|
cells.push(current);
|
|
8876
8719
|
return cells.map((cell) => cell.trim());
|
|
8877
8720
|
}
|
|
8878
|
-
function parseListFileArg(
|
|
8879
|
-
if (typeof
|
|
8721
|
+
function parseListFileArg(path14, maxRows) {
|
|
8722
|
+
if (typeof path14 !== "string" || path14.length === 0) {
|
|
8880
8723
|
return void 0;
|
|
8881
8724
|
}
|
|
8882
|
-
const raw = readFileSync6(
|
|
8725
|
+
const raw = readFileSync6(path14, "utf8");
|
|
8883
8726
|
const lines = raw.split(/\r?\n/).filter((line) => line.trim().length > 0);
|
|
8884
8727
|
if (lines.length < 2) {
|
|
8885
|
-
failWriteValidation2(`${
|
|
8728
|
+
failWriteValidation2(`${path14} needs a header row and at least one data row`);
|
|
8886
8729
|
}
|
|
8887
8730
|
const columns = parseCsvLine(lines[0]).map((column) => column.trim());
|
|
8888
8731
|
const rows = [];
|
|
@@ -8901,7 +8744,7 @@ function parseListFileArg(path12, maxRows) {
|
|
|
8901
8744
|
}
|
|
8902
8745
|
}
|
|
8903
8746
|
if (rows.length > maxRows) {
|
|
8904
|
-
failWriteValidation2(`${
|
|
8747
|
+
failWriteValidation2(`${path14} has ${rows.length} rows \u2014 the inline limit is ${maxRows}. Split the list.`);
|
|
8905
8748
|
}
|
|
8906
8749
|
return { columns, rows };
|
|
8907
8750
|
}
|
|
@@ -9546,7 +9389,7 @@ var leadFormsCreateCommand = defineCommand38({
|
|
|
9546
9389
|
Required: name, headline (\u226460), privacyPolicyUrl, questions[] (\u226412; playbook: \u22644 for completion).
|
|
9547
9390
|
Each question is a predefined profile field ({ name, predefinedField: "EMAIL" }) or a custom question ({ name, questionType: "MULTIPLE_CHOICE", options: [...] }; \u22643 custom).
|
|
9548
9391
|
Best-practice fields the preview will nudge for if missing: 1-3 qualifying questions, consents[] (disclosure checkboxes), thankYou.message + thankYou.landingUrl|appointmentUrl.
|
|
9549
|
-
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`
|
|
9550
9393
|
},
|
|
9551
9394
|
args: {
|
|
9552
9395
|
...accountArgs,
|
|
@@ -10970,72 +10813,72 @@ var NUMERIC_ID_REGEX3 = /^\d+$/;
|
|
|
10970
10813
|
var IMAGE_HASH_REGEX = /^[A-Fa-f0-9]{16,}$/;
|
|
10971
10814
|
|
|
10972
10815
|
// ../api/src/ads-meta/ops.ts
|
|
10973
|
-
import { z as
|
|
10974
|
-
var tempRefSchema3 =
|
|
10975
|
-
var parentRefSchema2 =
|
|
10976
|
-
var moneySchema2 =
|
|
10977
|
-
amount:
|
|
10978
|
-
currencyCode:
|
|
10979
|
-
});
|
|
10980
|
-
var httpsUrlSchema3 =
|
|
10981
|
-
var bakerMediaIdSchema2 =
|
|
10982
|
-
var stageableStatusSchema3 =
|
|
10983
|
-
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);
|
|
10984
10827
|
function currencyMinimums2(currencyCode) {
|
|
10985
10828
|
return CURRENCY_MINIMUMS2[currencyCode] ?? DEFAULT_CURRENCY_MINIMUM2;
|
|
10986
10829
|
}
|
|
10987
|
-
function validateDailyBudgetFloor(money, ctx,
|
|
10830
|
+
function validateDailyBudgetFloor(money, ctx, path14) {
|
|
10988
10831
|
if (money?.currencyCode) {
|
|
10989
10832
|
const min = currencyMinimums2(money.currencyCode).dailyBudgetMin;
|
|
10990
10833
|
if (Number(money.amount) < min) {
|
|
10991
|
-
ctx.addIssue({ code: "custom", path:
|
|
10834
|
+
ctx.addIssue({ code: "custom", path: path14, message: `below the ${min} ${money.currencyCode} daily minimum` });
|
|
10992
10835
|
}
|
|
10993
10836
|
}
|
|
10994
10837
|
}
|
|
10995
|
-
var geoLocationsSchema =
|
|
10996
|
-
countries:
|
|
10997
|
-
regions:
|
|
10998
|
-
cities:
|
|
10999
|
-
zips:
|
|
11000
|
-
location_types:
|
|
11001
|
-
}).catchall(
|
|
11002
|
-
var idNameSchema =
|
|
11003
|
-
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({
|
|
11004
10847
|
geo_locations: geoLocationsSchema.optional(),
|
|
11005
10848
|
excluded_geo_locations: geoLocationsSchema.optional(),
|
|
11006
|
-
age_min:
|
|
11007
|
-
age_max:
|
|
11008
|
-
genders:
|
|
11009
|
-
locales:
|
|
11010
|
-
interests:
|
|
11011
|
-
behaviors:
|
|
11012
|
-
custom_audiences:
|
|
11013
|
-
excluded_custom_audiences:
|
|
11014
|
-
flexible_spec:
|
|
11015
|
-
exclusions:
|
|
11016
|
-
publisher_platforms:
|
|
11017
|
-
facebook_positions:
|
|
11018
|
-
instagram_positions:
|
|
11019
|
-
audience_network_positions:
|
|
11020
|
-
messenger_positions:
|
|
11021
|
-
device_platforms:
|
|
11022
|
-
targeting_automation:
|
|
11023
|
-
}).catchall(
|
|
11024
|
-
var specialAdCategoriesSchema =
|
|
11025
|
-
var campaignCreateSchema3 =
|
|
11026
|
-
name:
|
|
11027
|
-
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),
|
|
11028
10871
|
status: stageableStatusSchema3.default("PAUSED"),
|
|
11029
10872
|
special_ad_categories: specialAdCategoriesSchema,
|
|
11030
|
-
special_ad_category_country:
|
|
11031
|
-
buying_type:
|
|
11032
|
-
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(),
|
|
11033
10876
|
/** Campaign Budget Optimization (Advantage campaign budget) — mutually exclusive with ad-set budgets. */
|
|
11034
10877
|
dailyBudget: moneySchema2.optional(),
|
|
11035
10878
|
lifetimeBudget: moneySchema2.optional(),
|
|
11036
10879
|
spendCap: moneySchema2.optional(),
|
|
11037
|
-
start_time:
|
|
11038
|
-
stop_time:
|
|
10880
|
+
start_time: z9.number().int().positive().optional(),
|
|
10881
|
+
stop_time: z9.number().int().positive().optional()
|
|
11039
10882
|
}).superRefine((p, ctx) => {
|
|
11040
10883
|
if (p.dailyBudget && p.lifetimeBudget) {
|
|
11041
10884
|
ctx.addIssue({ code: "custom", path: ["dailyBudget"], message: "set only one of dailyBudget or lifetimeBudget" });
|
|
@@ -11045,15 +10888,15 @@ var campaignCreateSchema3 = z10.object({
|
|
|
11045
10888
|
ctx.addIssue({ code: "custom", path: ["stop_time"], message: "stop_time must be after start_time" });
|
|
11046
10889
|
}
|
|
11047
10890
|
});
|
|
11048
|
-
var campaignUpdateSchema3 =
|
|
11049
|
-
name:
|
|
10891
|
+
var campaignUpdateSchema3 = z9.object({
|
|
10892
|
+
name: z9.string().min(1).max(META_LIMITS.campaign.nameMax).optional(),
|
|
11050
10893
|
status: updateStatusSchema.optional(),
|
|
11051
|
-
bid_strategy:
|
|
10894
|
+
bid_strategy: z9.enum(BID_STRATEGIES).optional(),
|
|
11052
10895
|
dailyBudget: moneySchema2.optional(),
|
|
11053
10896
|
lifetimeBudget: moneySchema2.optional(),
|
|
11054
10897
|
spendCap: moneySchema2.optional(),
|
|
11055
|
-
start_time:
|
|
11056
|
-
stop_time:
|
|
10898
|
+
start_time: z9.number().int().positive().optional(),
|
|
10899
|
+
stop_time: z9.number().int().positive().optional()
|
|
11057
10900
|
}).superRefine((p, ctx) => {
|
|
11058
10901
|
if (!Object.values(p).some((val) => val !== void 0)) {
|
|
11059
10902
|
ctx.addIssue({ code: "custom", message: "update needs at least one field" });
|
|
@@ -11063,38 +10906,38 @@ var campaignUpdateSchema3 = z10.object({
|
|
|
11063
10906
|
}
|
|
11064
10907
|
validateDailyBudgetFloor(p.dailyBudget, ctx, ["dailyBudget", "amount"]);
|
|
11065
10908
|
});
|
|
11066
|
-
var promotedObjectSchema =
|
|
10909
|
+
var promotedObjectSchema = z9.object({
|
|
11067
10910
|
page_id: parentRefSchema2.optional(),
|
|
11068
|
-
pixel_id:
|
|
11069
|
-
custom_event_type:
|
|
11070
|
-
application_id:
|
|
11071
|
-
object_store_url:
|
|
11072
|
-
product_catalog_id:
|
|
11073
|
-
product_set_id:
|
|
11074
|
-
whatsapp_phone_number:
|
|
11075
|
-
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()
|
|
11076
10919
|
}).partial();
|
|
11077
|
-
var attributionSpecSchema =
|
|
11078
|
-
|
|
11079
|
-
event_type:
|
|
11080
|
-
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)])
|
|
11081
10924
|
})
|
|
11082
10925
|
);
|
|
11083
10926
|
var adSetFields = {
|
|
11084
|
-
name:
|
|
10927
|
+
name: z9.string().min(1).max(META_LIMITS.adSet.nameMax),
|
|
11085
10928
|
campaign_id: parentRefSchema2,
|
|
11086
10929
|
status: stageableStatusSchema3.default("PAUSED"),
|
|
11087
10930
|
dailyBudget: moneySchema2.optional(),
|
|
11088
10931
|
lifetimeBudget: moneySchema2.optional(),
|
|
11089
10932
|
bidAmount: moneySchema2.optional(),
|
|
11090
|
-
bid_strategy:
|
|
11091
|
-
billing_event:
|
|
11092
|
-
optimization_goal:
|
|
11093
|
-
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(),
|
|
11094
10937
|
promoted_object: promotedObjectSchema.optional(),
|
|
11095
10938
|
attribution_spec: attributionSpecSchema.optional(),
|
|
11096
|
-
start_time:
|
|
11097
|
-
end_time:
|
|
10939
|
+
start_time: z9.number().int().positive().optional(),
|
|
10940
|
+
end_time: z9.number().int().positive().optional(),
|
|
11098
10941
|
targeting: metaTargetingSchema
|
|
11099
10942
|
};
|
|
11100
10943
|
function validateAdSetBudgetAndBid(p, ctx) {
|
|
@@ -11112,22 +10955,22 @@ function validateAdSetBudgetAndBid(p, ctx) {
|
|
|
11112
10955
|
ctx.addIssue({ code: "custom", path: ["end_time"], message: "end_time must be after start_time" });
|
|
11113
10956
|
}
|
|
11114
10957
|
}
|
|
11115
|
-
var adSetCreateSchema =
|
|
10958
|
+
var adSetCreateSchema = z9.object(adSetFields).superRefine((p, ctx) => {
|
|
11116
10959
|
validateAdSetBudgetAndBid(p, ctx);
|
|
11117
10960
|
});
|
|
11118
|
-
var adSetUpdateSchema =
|
|
10961
|
+
var adSetUpdateSchema = z9.object({
|
|
11119
10962
|
name: adSetFields.name.optional(),
|
|
11120
10963
|
status: updateStatusSchema.optional(),
|
|
11121
10964
|
dailyBudget: moneySchema2.optional(),
|
|
11122
10965
|
lifetimeBudget: moneySchema2.optional(),
|
|
11123
10966
|
bidAmount: moneySchema2.optional(),
|
|
11124
|
-
bid_strategy:
|
|
11125
|
-
optimization_goal:
|
|
11126
|
-
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(),
|
|
11127
10970
|
promoted_object: promotedObjectSchema.optional(),
|
|
11128
10971
|
attribution_spec: attributionSpecSchema.optional(),
|
|
11129
|
-
start_time:
|
|
11130
|
-
end_time:
|
|
10972
|
+
start_time: z9.number().int().positive().optional(),
|
|
10973
|
+
end_time: z9.number().int().positive().optional(),
|
|
11131
10974
|
targeting: metaTargetingSchema.optional()
|
|
11132
10975
|
}).superRefine((p, ctx) => {
|
|
11133
10976
|
if (!Object.values(p).some((val) => val !== void 0)) {
|
|
@@ -11135,38 +10978,38 @@ var adSetUpdateSchema = z10.object({
|
|
|
11135
10978
|
}
|
|
11136
10979
|
validateAdSetBudgetAndBid(p, ctx);
|
|
11137
10980
|
});
|
|
11138
|
-
var messageSchema =
|
|
11139
|
-
var headlineSchema2 =
|
|
11140
|
-
var descriptionSchema =
|
|
11141
|
-
var callToActionSchema =
|
|
11142
|
-
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),
|
|
11143
10986
|
/** Overrides the base link for the CTA button; defaults to the ad's link. */
|
|
11144
10987
|
link: httpsUrlSchema3.optional()
|
|
11145
10988
|
});
|
|
11146
|
-
var creativeEnhancementsSchema =
|
|
11147
|
-
standardEnhancements:
|
|
11148
|
-
features:
|
|
10989
|
+
var creativeEnhancementsSchema = z9.object({
|
|
10990
|
+
standardEnhancements: z9.enum(ENROLL_STATUSES).optional(),
|
|
10991
|
+
features: z9.record(z9.string(), z9.enum(ENROLL_STATUSES)).optional()
|
|
11149
10992
|
});
|
|
11150
10993
|
var creativeSharedFields = {
|
|
11151
|
-
name:
|
|
10994
|
+
name: z9.string().max(META_LIMITS.creative.nameMax).optional(),
|
|
11152
10995
|
/** Facebook Page id backing the ad's identity. */
|
|
11153
10996
|
page_id: parentRefSchema2,
|
|
11154
10997
|
/** Instagram account id for IG placements (aka instagram_actor_id on read). */
|
|
11155
|
-
instagram_user_id:
|
|
10998
|
+
instagram_user_id: z9.string().regex(NUMERIC_ID_REGEX3).optional(),
|
|
11156
10999
|
/** URL tracking parameters appended to the destination, e.g. "utm_source=fb&utm_campaign=x". */
|
|
11157
|
-
url_tags:
|
|
11000
|
+
url_tags: z9.string().max(1e3).optional(),
|
|
11158
11001
|
enhancements: creativeEnhancementsSchema.optional()
|
|
11159
11002
|
};
|
|
11160
11003
|
var imageMediaFields = {
|
|
11161
|
-
imageHash:
|
|
11004
|
+
imageHash: z9.string().regex(IMAGE_HASH_REGEX).optional(),
|
|
11162
11005
|
imageRef: tempRefSchema3.optional()
|
|
11163
11006
|
};
|
|
11164
11007
|
var videoMediaFields = {
|
|
11165
|
-
videoId:
|
|
11008
|
+
videoId: z9.string().regex(NUMERIC_ID_REGEX3).optional(),
|
|
11166
11009
|
videoRef: tempRefSchema3.optional(),
|
|
11167
11010
|
/** Thumbnail for a video creative — image hash, ref, or public url. */
|
|
11168
|
-
thumbnailHash:
|
|
11169
|
-
imageUrl:
|
|
11011
|
+
thumbnailHash: z9.string().regex(IMAGE_HASH_REGEX).optional(),
|
|
11012
|
+
imageUrl: z9.string().url().optional()
|
|
11170
11013
|
};
|
|
11171
11014
|
function countImageRefs(p) {
|
|
11172
11015
|
return [p.imageHash, p.imageRef].filter(Boolean).length;
|
|
@@ -11174,8 +11017,8 @@ function countImageRefs(p) {
|
|
|
11174
11017
|
function countVideoRefs(p) {
|
|
11175
11018
|
return [p.videoId, p.videoRef].filter(Boolean).length;
|
|
11176
11019
|
}
|
|
11177
|
-
var singleCreativeSchema =
|
|
11178
|
-
creativeType:
|
|
11020
|
+
var singleCreativeSchema = z9.object({
|
|
11021
|
+
creativeType: z9.literal("single"),
|
|
11179
11022
|
...creativeSharedFields,
|
|
11180
11023
|
/** Primary text. */
|
|
11181
11024
|
message: messageSchema,
|
|
@@ -11184,7 +11027,7 @@ var singleCreativeSchema = z10.object({
|
|
|
11184
11027
|
headline: headlineSchema2.optional(),
|
|
11185
11028
|
description: descriptionSchema.optional(),
|
|
11186
11029
|
/** Display URL / caption shown under the headline. */
|
|
11187
|
-
caption:
|
|
11030
|
+
caption: z9.string().max(255).optional(),
|
|
11188
11031
|
call_to_action: callToActionSchema.optional(),
|
|
11189
11032
|
...imageMediaFields,
|
|
11190
11033
|
...videoMediaFields
|
|
@@ -11208,10 +11051,10 @@ var singleCreativeSchema = z10.object({
|
|
|
11208
11051
|
});
|
|
11209
11052
|
}
|
|
11210
11053
|
});
|
|
11211
|
-
var carouselCardSchema =
|
|
11054
|
+
var carouselCardSchema = z9.object({
|
|
11212
11055
|
link: httpsUrlSchema3,
|
|
11213
|
-
headline:
|
|
11214
|
-
description:
|
|
11056
|
+
headline: z9.string().max(META_LIMITS.creative.headlineMax).optional(),
|
|
11057
|
+
description: z9.string().max(META_LIMITS.creative.descriptionMax).optional(),
|
|
11215
11058
|
call_to_action: callToActionSchema.optional(),
|
|
11216
11059
|
...imageMediaFields,
|
|
11217
11060
|
...videoMediaFields
|
|
@@ -11231,35 +11074,35 @@ var carouselCardSchema = z10.object({
|
|
|
11231
11074
|
ctx.addIssue({ code: "custom", path: ["videoId"], message: "each card is an image OR a video, not both" });
|
|
11232
11075
|
}
|
|
11233
11076
|
});
|
|
11234
|
-
var carouselCreativeSchema2 =
|
|
11235
|
-
creativeType:
|
|
11077
|
+
var carouselCreativeSchema2 = z9.object({
|
|
11078
|
+
creativeType: z9.literal("carousel"),
|
|
11236
11079
|
...creativeSharedFields,
|
|
11237
11080
|
message: messageSchema,
|
|
11238
11081
|
/** Optional "see more" card destination applied when a card has no own link. */
|
|
11239
11082
|
link: httpsUrlSchema3.optional(),
|
|
11240
11083
|
call_to_action: callToActionSchema.optional(),
|
|
11241
|
-
cards:
|
|
11084
|
+
cards: z9.array(carouselCardSchema).min(META_LIMITS.creative.carouselCardsMin).max(META_LIMITS.creative.carouselCardsMax)
|
|
11242
11085
|
});
|
|
11243
|
-
var dynamicImageSchema =
|
|
11244
|
-
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({
|
|
11245
11088
|
videoId: videoMediaFields.videoId,
|
|
11246
11089
|
videoRef: videoMediaFields.videoRef,
|
|
11247
11090
|
thumbnailHash: videoMediaFields.thumbnailHash
|
|
11248
11091
|
}).refine((p) => countVideoRefs(p) === 1, "each dynamic video needs exactly one reference");
|
|
11249
11092
|
var DYN = META_LIMITS.creative;
|
|
11250
|
-
var dynamicCreativeSchema =
|
|
11251
|
-
creativeType:
|
|
11093
|
+
var dynamicCreativeSchema = z9.object({
|
|
11094
|
+
creativeType: z9.literal("dynamic"),
|
|
11252
11095
|
...creativeSharedFields,
|
|
11253
|
-
bodies:
|
|
11254
|
-
titles:
|
|
11255
|
-
descriptions:
|
|
11256
|
-
images:
|
|
11257
|
-
videos:
|
|
11258
|
-
ad_formats:
|
|
11259
|
-
call_to_action_types:
|
|
11260
|
-
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),
|
|
11261
11104
|
/** Multi-language / placement customization — structural passthrough for v1. */
|
|
11262
|
-
asset_customization_rules:
|
|
11105
|
+
asset_customization_rules: z9.array(z9.record(z9.string(), z9.unknown())).optional()
|
|
11263
11106
|
}).superRefine((p, ctx) => {
|
|
11264
11107
|
if (!(p.images?.length || p.videos?.length)) {
|
|
11265
11108
|
ctx.addIssue({
|
|
@@ -11269,57 +11112,57 @@ var dynamicCreativeSchema = z10.object({
|
|
|
11269
11112
|
});
|
|
11270
11113
|
}
|
|
11271
11114
|
});
|
|
11272
|
-
var existingPostCreativeSchema =
|
|
11273
|
-
creativeType:
|
|
11115
|
+
var existingPostCreativeSchema = z9.object({
|
|
11116
|
+
creativeType: z9.literal("existing_post"),
|
|
11274
11117
|
name: creativeSharedFields.name,
|
|
11275
11118
|
/** "<page_id>_<post_id>" object story id of the post to promote. */
|
|
11276
|
-
object_story_id:
|
|
11119
|
+
object_story_id: z9.string().regex(/^\d+_\d+$/, 'expected "<page_id>_<post_id>"'),
|
|
11277
11120
|
instagram_user_id: creativeSharedFields.instagram_user_id,
|
|
11278
11121
|
url_tags: creativeSharedFields.url_tags,
|
|
11279
11122
|
enhancements: creativeSharedFields.enhancements
|
|
11280
11123
|
});
|
|
11281
|
-
var creativeContentSchema2 =
|
|
11124
|
+
var creativeContentSchema2 = z9.discriminatedUnion("creativeType", [
|
|
11282
11125
|
singleCreativeSchema,
|
|
11283
11126
|
carouselCreativeSchema2,
|
|
11284
11127
|
dynamicCreativeSchema,
|
|
11285
11128
|
existingPostCreativeSchema
|
|
11286
11129
|
]);
|
|
11287
11130
|
var adCreativeCreateSchema = creativeContentSchema2;
|
|
11288
|
-
var adCreativeUpdateSchema =
|
|
11289
|
-
name:
|
|
11131
|
+
var adCreativeUpdateSchema = z9.object({
|
|
11132
|
+
name: z9.string().max(META_LIMITS.creative.nameMax).optional(),
|
|
11290
11133
|
status: updateStatusSchema.optional(),
|
|
11291
11134
|
/** Content patch — only honored when the target is a staged meta_temp_* creative. */
|
|
11292
|
-
content:
|
|
11135
|
+
content: z9.record(z9.string(), z9.unknown()).optional()
|
|
11293
11136
|
}).refine((p) => Object.values(p).some((val) => val !== void 0), "update needs at least one field");
|
|
11294
|
-
var adCreateSchema2 =
|
|
11295
|
-
name:
|
|
11137
|
+
var adCreateSchema2 = z9.object({
|
|
11138
|
+
name: z9.string().min(1).max(META_LIMITS.ad.nameMax),
|
|
11296
11139
|
adset_id: parentRefSchema2,
|
|
11297
11140
|
status: stageableStatusSchema3.default("PAUSED"),
|
|
11298
|
-
creative:
|
|
11141
|
+
creative: z9.object({ creative_id: parentRefSchema2 }),
|
|
11299
11142
|
/** Conversion pixel / offline event set / view tags — structural passthrough. */
|
|
11300
|
-
tracking_specs:
|
|
11143
|
+
tracking_specs: z9.array(z9.record(z9.string(), z9.unknown())).optional()
|
|
11301
11144
|
});
|
|
11302
|
-
var adUpdateSchema2 =
|
|
11303
|
-
name:
|
|
11145
|
+
var adUpdateSchema2 = z9.object({
|
|
11146
|
+
name: z9.string().min(1).max(META_LIMITS.ad.nameMax).optional(),
|
|
11304
11147
|
status: updateStatusSchema.optional(),
|
|
11305
11148
|
/** Swapping the creative is the Meta way to "edit" an ad's creative. */
|
|
11306
|
-
creative:
|
|
11307
|
-
tracking_specs:
|
|
11149
|
+
creative: z9.object({ creative_id: parentRefSchema2 }).optional(),
|
|
11150
|
+
tracking_specs: z9.array(z9.record(z9.string(), z9.unknown())).optional()
|
|
11308
11151
|
}).refine((p) => Object.values(p).some((val) => val !== void 0), "update needs at least one field");
|
|
11309
|
-
var lookalikeSpecSchema =
|
|
11310
|
-
origin:
|
|
11311
|
-
ratio:
|
|
11312
|
-
country:
|
|
11313
|
-
});
|
|
11314
|
-
var customAudienceCreateSchema =
|
|
11315
|
-
name:
|
|
11316
|
-
subtype:
|
|
11317
|
-
description:
|
|
11318
|
-
customer_file_source:
|
|
11319
|
-
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(),
|
|
11320
11163
|
lookalike_spec: lookalikeSpecSchema.optional(),
|
|
11321
11164
|
/** Website/engagement rule — structural passthrough validated by Meta. */
|
|
11322
|
-
rule:
|
|
11165
|
+
rule: z9.record(z9.string(), z9.unknown()).optional()
|
|
11323
11166
|
}).superRefine((p, ctx) => {
|
|
11324
11167
|
if (p.subtype === "LOOKALIKE" && !p.lookalike_spec) {
|
|
11325
11168
|
ctx.addIssue({ code: "custom", path: ["lookalike_spec"], message: "LOOKALIKE audiences need a lookalike_spec" });
|
|
@@ -11328,16 +11171,16 @@ var customAudienceCreateSchema = z10.object({
|
|
|
11328
11171
|
ctx.addIssue({ code: "custom", path: ["rule"], message: `${p.subtype} audiences need a rule (use --file)` });
|
|
11329
11172
|
}
|
|
11330
11173
|
});
|
|
11331
|
-
var customAudienceUpdateSchema =
|
|
11332
|
-
name:
|
|
11333
|
-
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()
|
|
11334
11177
|
}).refine((p) => Object.values(p).some((val) => val !== void 0), "update needs at least one field");
|
|
11335
|
-
var mediaUploadSchema =
|
|
11336
|
-
kind:
|
|
11178
|
+
var mediaUploadSchema = z9.object({
|
|
11179
|
+
kind: z9.enum(MEDIA_KINDS),
|
|
11337
11180
|
bakerImageId: bakerMediaIdSchema2.optional(),
|
|
11338
11181
|
bakerVideoId: bakerMediaIdSchema2.optional(),
|
|
11339
11182
|
/** Optional display name / filename hint. */
|
|
11340
|
-
name:
|
|
11183
|
+
name: z9.string().max(255).optional()
|
|
11341
11184
|
}).superRefine((p, ctx) => {
|
|
11342
11185
|
if (p.kind === "image" && !p.bakerImageId) {
|
|
11343
11186
|
ctx.addIssue({ code: "custom", path: ["bakerImageId"], message: "image uploads need a bakerImageId" });
|
|
@@ -11359,16 +11202,16 @@ var META_DRAFT_OP_KINDS = [
|
|
|
11359
11202
|
"customAudience.update",
|
|
11360
11203
|
"media.upload"
|
|
11361
11204
|
];
|
|
11362
|
-
var metaDraftOpKindSchema =
|
|
11363
|
-
var accountIdSchema2 =
|
|
11364
|
-
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]);
|
|
11365
11208
|
function createOp3(kind, payload) {
|
|
11366
|
-
return
|
|
11209
|
+
return z9.object({ kind: z9.literal(kind), accountId: accountIdSchema2, payload });
|
|
11367
11210
|
}
|
|
11368
11211
|
function updateOp3(kind, payload) {
|
|
11369
|
-
return
|
|
11212
|
+
return z9.object({ kind: z9.literal(kind), accountId: accountIdSchema2, target: updateTargetSchema2, payload });
|
|
11370
11213
|
}
|
|
11371
|
-
var metaDraftOpInputSchema =
|
|
11214
|
+
var metaDraftOpInputSchema = z9.discriminatedUnion("kind", [
|
|
11372
11215
|
createOp3("campaign.create", campaignCreateSchema3),
|
|
11373
11216
|
updateOp3("campaign.update", campaignUpdateSchema3),
|
|
11374
11217
|
createOp3("adSet.create", adSetCreateSchema),
|
|
@@ -11383,89 +11226,89 @@ var metaDraftOpInputSchema = z10.discriminatedUnion("kind", [
|
|
|
11383
11226
|
]);
|
|
11384
11227
|
|
|
11385
11228
|
// ../api/src/ads-meta/wire.ts
|
|
11386
|
-
import { z as
|
|
11387
|
-
var metaWriteModeSchema =
|
|
11388
|
-
var metaDraftOpResultSchema =
|
|
11389
|
-
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"]),
|
|
11390
11233
|
/** The resulting Meta node id (campaign/adset/creative/ad/audience) or simulated id. */
|
|
11391
|
-
id:
|
|
11234
|
+
id: z10.string().optional(),
|
|
11392
11235
|
/** For media.upload ops: the resulting image hash. */
|
|
11393
|
-
hash:
|
|
11394
|
-
error:
|
|
11395
|
-
skippedBecause:
|
|
11396
|
-
executedAt:
|
|
11236
|
+
hash: z10.string().optional(),
|
|
11237
|
+
error: z10.string().optional(),
|
|
11238
|
+
skippedBecause: z10.string().optional(),
|
|
11239
|
+
executedAt: z10.number().optional()
|
|
11397
11240
|
});
|
|
11398
|
-
var metaDraftStageRequestSchema =
|
|
11399
|
-
chatId:
|
|
11241
|
+
var metaDraftStageRequestSchema = z10.object({
|
|
11242
|
+
chatId: z10.string(),
|
|
11400
11243
|
op: metaDraftOpInputSchema
|
|
11401
11244
|
});
|
|
11402
|
-
var metaDraftStageResponseSchema =
|
|
11403
|
-
staged:
|
|
11404
|
-
ref:
|
|
11245
|
+
var metaDraftStageResponseSchema = z10.object({
|
|
11246
|
+
staged: z10.literal(true),
|
|
11247
|
+
ref: z10.string(),
|
|
11405
11248
|
kind: metaDraftOpKindSchema,
|
|
11406
11249
|
mode: metaWriteModeSchema,
|
|
11407
|
-
dependsOn:
|
|
11408
|
-
summary:
|
|
11409
|
-
warnings:
|
|
11250
|
+
dependsOn: z10.array(z10.string()),
|
|
11251
|
+
summary: z10.string(),
|
|
11252
|
+
warnings: z10.array(z10.string()),
|
|
11410
11253
|
/** True when the op amended an already-staged op in place instead of appending a new one. */
|
|
11411
|
-
amended:
|
|
11412
|
-
});
|
|
11413
|
-
var metaDraftDuplicateRequestSchema =
|
|
11414
|
-
chatId:
|
|
11415
|
-
accountId:
|
|
11416
|
-
entity:
|
|
11417
|
-
sourceId:
|
|
11418
|
-
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(),
|
|
11419
11262
|
/** Pause the original after the copy publishes. */
|
|
11420
|
-
replace:
|
|
11263
|
+
replace: z10.boolean().optional()
|
|
11421
11264
|
});
|
|
11422
|
-
var metaDraftOpViewSchema =
|
|
11423
|
-
ref:
|
|
11265
|
+
var metaDraftOpViewSchema = z10.object({
|
|
11266
|
+
ref: z10.string(),
|
|
11424
11267
|
kind: metaDraftOpKindSchema,
|
|
11425
|
-
accountId:
|
|
11426
|
-
target:
|
|
11427
|
-
dependsOn:
|
|
11428
|
-
summary:
|
|
11429
|
-
stagedAt:
|
|
11268
|
+
accountId: z10.string(),
|
|
11269
|
+
target: z10.string().optional(),
|
|
11270
|
+
dependsOn: z10.array(z10.string()),
|
|
11271
|
+
summary: z10.string(),
|
|
11272
|
+
stagedAt: z10.number(),
|
|
11430
11273
|
result: metaDraftOpResultSchema.optional()
|
|
11431
11274
|
});
|
|
11432
|
-
var metaDraftListRequestSchema =
|
|
11433
|
-
chatId:
|
|
11275
|
+
var metaDraftListRequestSchema = z10.object({
|
|
11276
|
+
chatId: z10.string()
|
|
11434
11277
|
});
|
|
11435
|
-
var metaDraftAdvisorySchema =
|
|
11436
|
-
ref:
|
|
11437
|
-
message:
|
|
11278
|
+
var metaDraftAdvisorySchema = z10.object({
|
|
11279
|
+
ref: z10.string(),
|
|
11280
|
+
message: z10.string()
|
|
11438
11281
|
});
|
|
11439
|
-
var metaDraftListResponseSchema =
|
|
11440
|
-
status:
|
|
11282
|
+
var metaDraftListResponseSchema = z10.object({
|
|
11283
|
+
status: z10.enum(["active", "publishing", "applied", "discarded", "none"]),
|
|
11441
11284
|
mode: metaWriteModeSchema,
|
|
11442
|
-
count:
|
|
11443
|
-
ops:
|
|
11285
|
+
count: z10.number(),
|
|
11286
|
+
ops: z10.array(metaDraftOpViewSchema),
|
|
11444
11287
|
/** Non-blocking cross-op quality advisories — "good campaign, not just valid". */
|
|
11445
|
-
advisories:
|
|
11288
|
+
advisories: z10.array(metaDraftAdvisorySchema)
|
|
11446
11289
|
});
|
|
11447
|
-
var metaDraftRemoveRequestSchema =
|
|
11448
|
-
chatId:
|
|
11449
|
-
ref:
|
|
11290
|
+
var metaDraftRemoveRequestSchema = z10.object({
|
|
11291
|
+
chatId: z10.string(),
|
|
11292
|
+
ref: z10.string()
|
|
11450
11293
|
});
|
|
11451
|
-
var metaDraftRemoveResponseSchema =
|
|
11294
|
+
var metaDraftRemoveResponseSchema = z10.object({
|
|
11452
11295
|
/** The requested ref plus any dependents removed by cascade. */
|
|
11453
|
-
removed:
|
|
11296
|
+
removed: z10.array(z10.string())
|
|
11454
11297
|
});
|
|
11455
|
-
var metaDraftClearRequestSchema =
|
|
11456
|
-
chatId:
|
|
11298
|
+
var metaDraftClearRequestSchema = z10.object({
|
|
11299
|
+
chatId: z10.string()
|
|
11457
11300
|
});
|
|
11458
|
-
var metaDraftClearResponseSchema =
|
|
11459
|
-
cleared:
|
|
11301
|
+
var metaDraftClearResponseSchema = z10.object({
|
|
11302
|
+
cleared: z10.number()
|
|
11460
11303
|
});
|
|
11461
|
-
var metaFieldErrorSchema =
|
|
11462
|
-
path:
|
|
11463
|
-
message:
|
|
11304
|
+
var metaFieldErrorSchema = z10.object({
|
|
11305
|
+
path: z10.string(),
|
|
11306
|
+
message: z10.string()
|
|
11464
11307
|
});
|
|
11465
|
-
var metaDraftErrorResponseSchema =
|
|
11466
|
-
code:
|
|
11467
|
-
error:
|
|
11468
|
-
fields:
|
|
11308
|
+
var metaDraftErrorResponseSchema = z10.object({
|
|
11309
|
+
code: z10.string(),
|
|
11310
|
+
error: z10.string(),
|
|
11311
|
+
fields: z10.array(metaFieldErrorSchema).optional()
|
|
11469
11312
|
});
|
|
11470
11313
|
|
|
11471
11314
|
// src/commands/ads/meta/write-shared.ts
|
|
@@ -11476,19 +11319,19 @@ function failWriteValidation3(message) {
|
|
|
11476
11319
|
writeJsonEnvelope({ ok: false, error: { code: "VALIDATION_ERROR", message } });
|
|
11477
11320
|
process.exit(1);
|
|
11478
11321
|
}
|
|
11479
|
-
function loadJsonFileArg3(
|
|
11480
|
-
if (typeof
|
|
11322
|
+
function loadJsonFileArg3(path14) {
|
|
11323
|
+
if (typeof path14 !== "string" || path14.length === 0) {
|
|
11481
11324
|
return {};
|
|
11482
11325
|
}
|
|
11483
11326
|
try {
|
|
11484
|
-
const parsed = JSON.parse(readFileSync8(
|
|
11327
|
+
const parsed = JSON.parse(readFileSync8(path14, "utf8"));
|
|
11485
11328
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
11486
|
-
failWriteValidation3(`${
|
|
11329
|
+
failWriteValidation3(`${path14} must contain a JSON object`);
|
|
11487
11330
|
}
|
|
11488
11331
|
return parsed;
|
|
11489
11332
|
} catch (err) {
|
|
11490
11333
|
if (err instanceof SyntaxError) {
|
|
11491
|
-
failWriteValidation3(`${
|
|
11334
|
+
failWriteValidation3(`${path14} is not valid JSON: ${err.message}`);
|
|
11492
11335
|
}
|
|
11493
11336
|
throw err;
|
|
11494
11337
|
}
|
|
@@ -14551,7 +14394,7 @@ async function probeDuration(filePath) {
|
|
|
14551
14394
|
|
|
14552
14395
|
// src/commands/canvas/run.ts
|
|
14553
14396
|
import { readFile as readFile2 } from "fs/promises";
|
|
14554
|
-
import
|
|
14397
|
+
import path5 from "path";
|
|
14555
14398
|
import { defineCommand as defineCommand88 } from "citty";
|
|
14556
14399
|
|
|
14557
14400
|
// src/commands/canvas/placeholders.ts
|
|
@@ -14595,9 +14438,102 @@ function isResolvableRelative(value) {
|
|
|
14595
14438
|
return typeof value === "string" && value.length > 0 && !value.includes("[TODO") && !path2.isAbsolute(value);
|
|
14596
14439
|
}
|
|
14597
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
|
+
|
|
14598
14534
|
// src/commands/canvas/run-retention.ts
|
|
14599
14535
|
import { rm } from "fs/promises";
|
|
14600
|
-
import
|
|
14536
|
+
import path4 from "path";
|
|
14601
14537
|
function runDirsToPrune(entries, keep, currentRunId) {
|
|
14602
14538
|
const runs = entries.filter((e) => /^r_[0-9A-Za-z]+$/.test(e) && e !== currentRunId).sort();
|
|
14603
14539
|
if (keep <= 0) return runs;
|
|
@@ -14614,7 +14550,7 @@ async function pruneOldRuns(outputsDir, keep, currentRunId, log) {
|
|
|
14614
14550
|
const toPrune = runDirsToPrune(entries, keep, currentRunId);
|
|
14615
14551
|
if (toPrune.length === 0) return;
|
|
14616
14552
|
for (const dir of toPrune) {
|
|
14617
|
-
await rm(
|
|
14553
|
+
await rm(path4.join(outputsDir, dir), { recursive: true, force: true }).catch(
|
|
14618
14554
|
(e) => log(`[prune ] could not remove ${dir}: ${e.message}`)
|
|
14619
14555
|
);
|
|
14620
14556
|
}
|
|
@@ -14641,10 +14577,22 @@ var runCommand = defineCommand88({
|
|
|
14641
14577
|
"keep-runs": {
|
|
14642
14578
|
type: "string",
|
|
14643
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)"
|
|
14644
14592
|
}
|
|
14645
14593
|
},
|
|
14646
14594
|
async run({ args }) {
|
|
14647
|
-
const filePath =
|
|
14595
|
+
const filePath = path5.resolve(String(args.file));
|
|
14648
14596
|
const raw = await readFile2(filePath, "utf8");
|
|
14649
14597
|
let parsed;
|
|
14650
14598
|
try {
|
|
@@ -14655,7 +14603,7 @@ var runCommand = defineCommand88({
|
|
|
14655
14603
|
`);
|
|
14656
14604
|
process.exit(2);
|
|
14657
14605
|
}
|
|
14658
|
-
parsed = resolveRelativeCanvasPaths(parsed,
|
|
14606
|
+
parsed = resolveRelativeCanvasPaths(parsed, path5.dirname(filePath));
|
|
14659
14607
|
const pending = unsuppliedPlaceholderAssets(parsed);
|
|
14660
14608
|
if (pending.length > 0) {
|
|
14661
14609
|
process.stderr.write(
|
|
@@ -14675,16 +14623,26 @@ var runCommand = defineCommand88({
|
|
|
14675
14623
|
);
|
|
14676
14624
|
process.exit(2);
|
|
14677
14625
|
}
|
|
14626
|
+
const remoteCache = args["remote-cache"] !== void 0 ? String(args["remote-cache"]) !== "off" : void 0;
|
|
14678
14627
|
const engine = createEngineFromEnv({
|
|
14679
14628
|
cacheDir: args["cache-dir"] ? String(args["cache-dir"]) : void 0,
|
|
14680
14629
|
outputsDir: args["outputs-dir"] ? String(args["outputs-dir"]) : void 0,
|
|
14681
14630
|
log: (line) => process.stdout.write(`${line}
|
|
14682
|
-
`)
|
|
14631
|
+
`),
|
|
14632
|
+
remoteCache
|
|
14683
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();
|
|
14684
14642
|
try {
|
|
14685
14643
|
const policy = args["cache-policy"] ?? "read_write";
|
|
14686
14644
|
const result = await engine.run(parsed, {
|
|
14687
|
-
run_id:
|
|
14645
|
+
run_id: runId,
|
|
14688
14646
|
cache_policy: policy,
|
|
14689
14647
|
concurrency: resolveConcurrency(
|
|
14690
14648
|
// --concurrency wins; --parallel is the discoverable alias for the same bound.
|
|
@@ -14692,9 +14650,10 @@ var runCommand = defineCommand88({
|
|
|
14692
14650
|
process.env.BAKER_CANVAS_CONCURRENCY
|
|
14693
14651
|
)
|
|
14694
14652
|
});
|
|
14653
|
+
if (record) await record(buildRunRecord(result, recordMeta));
|
|
14695
14654
|
const keepRuns = args["keep-runs"] !== void 0 ? Number(args["keep-runs"]) : void 0;
|
|
14696
14655
|
if (keepRuns !== void 0 && Number.isFinite(keepRuns)) {
|
|
14697
|
-
const outputsDir = args["outputs-dir"] ?
|
|
14656
|
+
const outputsDir = args["outputs-dir"] ? path5.resolve(String(args["outputs-dir"])) : path5.resolve("canvas");
|
|
14698
14657
|
await pruneOldRuns(outputsDir, keepRuns, result.run_id, (line) => process.stdout.write(`${line}
|
|
14699
14658
|
`));
|
|
14700
14659
|
}
|
|
@@ -14722,6 +14681,7 @@ var runCommand = defineCommand88({
|
|
|
14722
14681
|
}
|
|
14723
14682
|
if (e instanceof LayerExecutionError) {
|
|
14724
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));
|
|
14725
14685
|
process.stderr.write(
|
|
14726
14686
|
`${JSON.stringify({ ok: false, error: { code: "runtime", message: e.message, failures } }, null, 2)}
|
|
14727
14687
|
`
|
|
@@ -14729,40 +14689,54 @@ var runCommand = defineCommand88({
|
|
|
14729
14689
|
process.exit(1);
|
|
14730
14690
|
}
|
|
14731
14691
|
const msg = e instanceof Error ? e.message : String(e);
|
|
14692
|
+
if (record) await record(buildFailedRunRecord(runId, msg, recordMeta));
|
|
14732
14693
|
process.stderr.write(`${JSON.stringify({ ok: false, error: { code: "runtime", message: msg } }, null, 2)}
|
|
14733
14694
|
`);
|
|
14734
14695
|
process.exit(1);
|
|
14735
14696
|
}
|
|
14736
14697
|
}
|
|
14737
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
|
+
}
|
|
14738
14712
|
|
|
14739
14713
|
// src/commands/canvas/scaffold-static-ad.ts
|
|
14740
|
-
import { readFile as readFile3, writeFile } from "fs/promises";
|
|
14741
|
-
import
|
|
14714
|
+
import { access, cp, mkdir, readFile as readFile3, writeFile } from "fs/promises";
|
|
14715
|
+
import path8 from "path";
|
|
14742
14716
|
import { defineCommand as defineCommand89 } from "citty";
|
|
14743
14717
|
|
|
14744
14718
|
// src/engine/scaffold/staticAd.ts
|
|
14745
|
-
import { z as
|
|
14719
|
+
import { z as z11 } from "zod";
|
|
14746
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"]);
|
|
14747
14721
|
var DEFAULT_ASPECT_RATIO = "9:16";
|
|
14748
|
-
var Blueprint =
|
|
14749
|
-
meta:
|
|
14750
|
-
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()
|
|
14751
14725
|
}).loose();
|
|
14752
|
-
var ElementLocator =
|
|
14753
|
-
collection:
|
|
14754
|
-
index:
|
|
14726
|
+
var ElementLocator = z11.object({
|
|
14727
|
+
collection: z11.enum(["subjects", "people", "brands_logos"]),
|
|
14728
|
+
index: z11.number().int().nonnegative()
|
|
14755
14729
|
}).loose();
|
|
14756
|
-
var MainElement =
|
|
14730
|
+
var MainElement = z11.object({
|
|
14757
14731
|
// logo | product | person | animal | badge | other
|
|
14758
|
-
type:
|
|
14759
|
-
label:
|
|
14760
|
-
description:
|
|
14761
|
-
expression:
|
|
14762
|
-
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(),
|
|
14763
14737
|
locator: ElementLocator.optional()
|
|
14764
14738
|
}).loose();
|
|
14765
|
-
var MainElements =
|
|
14739
|
+
var MainElements = z11.array(MainElement);
|
|
14766
14740
|
function sanitizeId(raw, fallback) {
|
|
14767
14741
|
const id = raw.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
14768
14742
|
return /^[a-z]/.test(id) ? id : `${fallback}_${id}`.replace(/_+$/g, "") || fallback;
|
|
@@ -14924,18 +14898,106 @@ function staticAdReport(input, elementsInput, opts) {
|
|
|
14924
14898
|
};
|
|
14925
14899
|
}
|
|
14926
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
|
+
|
|
14927
14960
|
// src/commands/canvas/scaffold-static-ad-paths.ts
|
|
14928
|
-
import
|
|
14929
|
-
function resolveScaffoldStaticAdPaths(rawFile, out, cwd = process.cwd()) {
|
|
14961
|
+
import path7 from "path";
|
|
14962
|
+
function resolveScaffoldStaticAdPaths(rawFile, out, cwd = process.cwd(), slug) {
|
|
14930
14963
|
const file = rawFile.trim();
|
|
14931
14964
|
const imageIsUrl = /^https?:\/\//i.test(file);
|
|
14932
|
-
const imageSource = imageIsUrl ? file :
|
|
14933
|
-
const outPath = out ?
|
|
14934
|
-
const blueprintPath =
|
|
14935
|
-
|
|
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);
|
|
14936
14977
|
}
|
|
14937
14978
|
|
|
14938
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
|
+
}
|
|
14939
15001
|
function resolveModel(kind, preferred) {
|
|
14940
15002
|
const ids = Object.keys(MODEL_REGISTRY[kind]);
|
|
14941
15003
|
return ids.includes(preferred) ? preferred : ids[0] ?? preferred;
|
|
@@ -15095,6 +15157,16 @@ var scaffoldStaticAdCommand = defineCommand89({
|
|
|
15095
15157
|
file: { type: "positional", required: true, description: "Path or http(s) URL to the source/inspiration image" },
|
|
15096
15158
|
context: { type: "string", description: "Known provenance (advertiser, category, market) to ground the describe" },
|
|
15097
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" },
|
|
15098
15170
|
"describe-model": { type: "string", description: "Override the image_describe model id" },
|
|
15099
15171
|
"select-model": { type: "string", description: "Override the text_generate model id for element selection" },
|
|
15100
15172
|
"layout-model": { type: "string", description: "Override the text_generate model id for the layout pass" },
|
|
@@ -15103,10 +15175,21 @@ var scaffoldStaticAdCommand = defineCommand89({
|
|
|
15103
15175
|
"skip-font": { type: "boolean", description: "Skip the brand-font \u2192 type-specimen slot" }
|
|
15104
15176
|
},
|
|
15105
15177
|
async run({ args }) {
|
|
15106
|
-
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(
|
|
15107
15187
|
String(args.file),
|
|
15108
|
-
args.out ? String(args.out) : void 0
|
|
15188
|
+
args.out ? String(args.out) : void 0,
|
|
15189
|
+
process.cwd(),
|
|
15190
|
+
slug
|
|
15109
15191
|
);
|
|
15192
|
+
await mkdir(path8.dirname(outPath), { recursive: true });
|
|
15110
15193
|
const { describeModel, selectModel, layoutModel, genModel } = resolveModels(args);
|
|
15111
15194
|
const describeCanvas = buildDescribeCanvas(
|
|
15112
15195
|
imageSource,
|
|
@@ -15123,11 +15206,21 @@ var scaffoldStaticAdCommand = defineCommand89({
|
|
|
15123
15206
|
}
|
|
15124
15207
|
await writeFile(blueprintPath, `${JSON.stringify(annotated, null, 2)}
|
|
15125
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
|
+
}
|
|
15126
15219
|
const opts = {
|
|
15127
15220
|
genModel,
|
|
15128
|
-
imagePath:
|
|
15129
|
-
imageIsUrl,
|
|
15130
|
-
blueprintPath,
|
|
15221
|
+
imagePath: canvasImagePath,
|
|
15222
|
+
imageIsUrl: canvasImageIsUrl,
|
|
15223
|
+
blueprintPath: canvasBlueprintPath,
|
|
15131
15224
|
aspectRatio: args.aspect ? String(args.aspect) : void 0,
|
|
15132
15225
|
includeFont: !args["skip-font"]
|
|
15133
15226
|
};
|
|
@@ -15149,12 +15242,31 @@ var scaffoldStaticAdCommand = defineCommand89({
|
|
|
15149
15242
|
}
|
|
15150
15243
|
await writeFile(outPath, `${JSON.stringify(canvas, null, 2)}
|
|
15151
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
|
+
}
|
|
15152
15262
|
process.stdout.write(
|
|
15153
15263
|
`${JSON.stringify(
|
|
15154
15264
|
{
|
|
15155
15265
|
ok: true,
|
|
15156
15266
|
canvas_path: outPath,
|
|
15157
15267
|
prompt_path: blueprintPath,
|
|
15268
|
+
definition_path: definitionPath ?? void 0,
|
|
15269
|
+
source_reference: sourceRelPath ?? void 0,
|
|
15158
15270
|
output: canvas.output,
|
|
15159
15271
|
models: { describe: describeModel, select: selectModel, layout: layoutModel, gen: opts.genModel },
|
|
15160
15272
|
aspect_ratio: report.aspect_ratio,
|
|
@@ -15165,7 +15277,7 @@ var scaffoldStaticAdCommand = defineCommand89({
|
|
|
15165
15277
|
run_estimated_credits: validation.estimatedCredits
|
|
15166
15278
|
},
|
|
15167
15279
|
checklist: {
|
|
15168
|
-
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.`,
|
|
15169
15281
|
assets_to_supply: report.elements,
|
|
15170
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)",
|
|
15171
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."
|
|
@@ -15180,8 +15292,8 @@ var scaffoldStaticAdCommand = defineCommand89({
|
|
|
15180
15292
|
});
|
|
15181
15293
|
|
|
15182
15294
|
// src/commands/canvas/scaffold-video.ts
|
|
15183
|
-
import { cp, mkdir, readFile as readFile6, writeFile as writeFile2 } from "fs/promises";
|
|
15184
|
-
import
|
|
15295
|
+
import { cp as cp2, mkdir as mkdir2, readFile as readFile6, writeFile as writeFile2 } from "fs/promises";
|
|
15296
|
+
import path11 from "path";
|
|
15185
15297
|
import { defineCommand as defineCommand90 } from "citty";
|
|
15186
15298
|
|
|
15187
15299
|
// src/engine/nodes/local/lib/sceneDetect.ts
|
|
@@ -15298,7 +15410,7 @@ import { toCardinal as nwKo } from "n2words/ko-KR";
|
|
|
15298
15410
|
import { toCardinal as nwNl } from "n2words/nl-NL";
|
|
15299
15411
|
import { toCardinal as nwPl } from "n2words/pl-PL";
|
|
15300
15412
|
import { toCardinal as nwPt } from "n2words/pt-PT";
|
|
15301
|
-
import { z as
|
|
15413
|
+
import { z as z12 } from "zod";
|
|
15302
15414
|
|
|
15303
15415
|
// src/engine/scaffold/lib/shoot-modes.ts
|
|
15304
15416
|
var SHOOT_MODES = [
|
|
@@ -15611,71 +15723,71 @@ function trimArgs(durationS, offsetS = 0, dims) {
|
|
|
15611
15723
|
"{{out.video}}"
|
|
15612
15724
|
];
|
|
15613
15725
|
}
|
|
15614
|
-
var FrameAsset =
|
|
15615
|
-
var DialogueLine =
|
|
15616
|
-
speaker:
|
|
15617
|
-
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(),
|
|
15618
15730
|
// Absolute seconds on the source timeline (the deconstruct emits both).
|
|
15619
|
-
start_s:
|
|
15620
|
-
end_s:
|
|
15621
|
-
delivery:
|
|
15622
|
-
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(),
|
|
15623
15735
|
// DECON-supplied: is this speaker's FACE visibly speaking in THIS scene? Element
|
|
15624
15736
|
// presence alone can't answer that — a founder pictured in a polaroid close-up is
|
|
15625
15737
|
// "present" yet the line is voiceover, and treating it as on-camera produced a
|
|
15626
15738
|
// native Seedance lip-sync clip of a still photograph. `false` pins the line to
|
|
15627
15739
|
// the VO path; absent keeps the presence-based decision (old blueprints).
|
|
15628
|
-
on_camera:
|
|
15740
|
+
on_camera: z12.boolean().optional()
|
|
15629
15741
|
}).loose();
|
|
15630
|
-
var Sfx =
|
|
15631
|
-
at_s:
|
|
15632
|
-
duration_s:
|
|
15633
|
-
sound_effect_prompt:
|
|
15634
|
-
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()
|
|
15635
15747
|
}).loose();
|
|
15636
|
-
var CompositionRegion =
|
|
15748
|
+
var CompositionRegion = z12.object({
|
|
15637
15749
|
// full | top | bottom | left | right | inset
|
|
15638
|
-
panel:
|
|
15750
|
+
panel: z12.string().optional(),
|
|
15639
15751
|
// 9-grid anchor for an `inset` presenter box.
|
|
15640
|
-
position:
|
|
15641
|
-
is_presenter:
|
|
15752
|
+
position: z12.string().optional(),
|
|
15753
|
+
is_presenter: z12.boolean().optional(),
|
|
15642
15754
|
// The cast id shown/speaking in this region (routes lip-sync + element refs).
|
|
15643
|
-
cast_ref:
|
|
15755
|
+
cast_ref: z12.string().optional(),
|
|
15644
15756
|
// What the region's content IS: camera | screen_capture | static_graphic |
|
|
15645
15757
|
// generated. Authoritative for routing when present (regex-over-prose fallback
|
|
15646
15758
|
// otherwise): screen_capture/static_graphic are rebuilt from REAL surfaces on the
|
|
15647
15759
|
// overlay layer, never AI-generated.
|
|
15648
|
-
kind:
|
|
15760
|
+
kind: z12.string().optional(),
|
|
15649
15761
|
// Opaque id naming the SPECIFIC on-screen document/note/app-state this
|
|
15650
15762
|
// screen_capture region shows. Two scenes share it only when they show the SAME
|
|
15651
15763
|
// recording continuing (scrolling/typing/waiting within it) — a genuinely
|
|
15652
15764
|
// DIFFERENT document/note/recording (a source video splicing two screen captures)
|
|
15653
15765
|
// gets a different id. Breaks a persistent-layout run into separate surface stubs
|
|
15654
15766
|
// instead of asking the operator for one screenshot that can't cover both.
|
|
15655
|
-
surface_id:
|
|
15767
|
+
surface_id: z12.string().optional(),
|
|
15656
15768
|
// Camera bubble(s)/inset(s) embedded INSIDE this region's surface (a Loom-style
|
|
15657
15769
|
// presenter bubble inside a screen recording) — video-in-video the reproduction
|
|
15658
15770
|
// must re-composite, not paint into the surface.
|
|
15659
|
-
nested:
|
|
15660
|
-
summary:
|
|
15661
|
-
frame_prompt:
|
|
15662
|
-
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()
|
|
15663
15775
|
}).loose();
|
|
15664
|
-
var SceneComposition =
|
|
15776
|
+
var SceneComposition = z12.object({
|
|
15665
15777
|
// full_frame (default) | split_screen | pip | keyed_overlay
|
|
15666
|
-
layout:
|
|
15778
|
+
layout: z12.string().optional(),
|
|
15667
15779
|
// split_screen only: vertical (top/bottom) | horizontal (left/right).
|
|
15668
|
-
split_axis:
|
|
15669
|
-
regions:
|
|
15780
|
+
split_axis: z12.string().optional(),
|
|
15781
|
+
regions: z12.array(CompositionRegion).optional()
|
|
15670
15782
|
}).loose();
|
|
15671
|
-
var CameraMotion =
|
|
15672
|
-
var TranscriptWord =
|
|
15673
|
-
var Scene =
|
|
15674
|
-
start_s:
|
|
15675
|
-
end_s:
|
|
15676
|
-
duration_s:
|
|
15677
|
-
summary:
|
|
15678
|
-
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(),
|
|
15679
15791
|
// The scene's spatial layout. Absent/full_frame ⇒ one uncut shot (default path).
|
|
15680
15792
|
// A layered layout (split_screen/pip/keyed_overlay) with regions ⇒ the scaffold
|
|
15681
15793
|
// builds one clip per region and stacks/overlays them into the scene picture.
|
|
@@ -15683,82 +15795,82 @@ var Scene = z13.object({
|
|
|
15683
15795
|
// The capture "look" for this scene — selected from the ad-native shoot-mode
|
|
15684
15796
|
// grammar (see lib/shoot-modes.ts). When absent the scaffold auto-derives a
|
|
15685
15797
|
// UGC/product mode; a human can override per scene by setting this.
|
|
15686
|
-
shoot_mode:
|
|
15798
|
+
shoot_mode: z12.string().optional(),
|
|
15687
15799
|
// Diegetic ambient the clip's native audio should carry (no music). When
|
|
15688
15800
|
// absent the scene falls back to its shoot mode's default ambience.
|
|
15689
|
-
ambient:
|
|
15801
|
+
ambient: z12.string().optional(),
|
|
15690
15802
|
camera_motion: CameraMotion.optional(),
|
|
15691
|
-
start_frame_prompt:
|
|
15692
|
-
end_frame_prompt:
|
|
15693
|
-
motion_prompt:
|
|
15803
|
+
start_frame_prompt: z12.string().optional(),
|
|
15804
|
+
end_frame_prompt: z12.string().optional(),
|
|
15805
|
+
motion_prompt: z12.string().optional(),
|
|
15694
15806
|
// The scene's role in the ad's persuasion arc (DECON-supplied); drives the
|
|
15695
15807
|
// script re-craft checklist. Inferred from position when absent.
|
|
15696
|
-
narrative_role:
|
|
15808
|
+
narrative_role: z12.string().optional(),
|
|
15697
15809
|
// DECON-supplied on the HOOK scene: the engineered physical/emotional state that
|
|
15698
15810
|
// makes the first frame stop the scroll (sweaty/breathless/urgent …). Injected
|
|
15699
15811
|
// into the hook's start-frame description so the generator renders that state,
|
|
15700
15812
|
// not a calm influencer (CCA-11).
|
|
15701
|
-
hook_mechanic:
|
|
15813
|
+
hook_mechanic: z12.object({ mechanic: z12.string().optional(), why_it_stops_scroll: z12.string().optional() }).loose().optional(),
|
|
15702
15814
|
// DECON-supplied per-scene location (so a gym hook isn't flattened to "home").
|
|
15703
|
-
scene_setting:
|
|
15815
|
+
scene_setting: z12.string().optional(),
|
|
15704
15816
|
// How this scene cuts to the next (DECON-supplied). A recognized non-cut type
|
|
15705
15817
|
// (fade/whip/zoom/dissolve/swipe) is reproduced as an ffmpeg xfade at the
|
|
15706
15818
|
// boundary; cut/match_cut/none/other stay hard cuts. The last scene's value is
|
|
15707
15819
|
// ignored (nothing follows it).
|
|
15708
|
-
transition_out:
|
|
15709
|
-
dialogue:
|
|
15710
|
-
sfx:
|
|
15711
|
-
overlays:
|
|
15712
|
-
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(),
|
|
15713
15825
|
// DECON-supplied: how much the picture itself moves within the shot. Gates the
|
|
15714
15826
|
// flash-hold optimization — a sub-2s b-roll flash with REAL subject motion
|
|
15715
15827
|
// (pouring, spreading, hands working) must stay a real clip; freezing it turns
|
|
15716
15828
|
// a montage into a slideshow. Absent (old blueprints) keeps the cheap still.
|
|
15717
|
-
motion_level:
|
|
15718
|
-
transcript_slice:
|
|
15829
|
+
motion_level: z12.enum(["static", "subtle", "dynamic"]).optional(),
|
|
15830
|
+
transcript_slice: z12.array(TranscriptWord).optional(),
|
|
15719
15831
|
start_frame_asset: FrameAsset,
|
|
15720
15832
|
end_frame_asset: FrameAsset,
|
|
15721
15833
|
// DECON-supplied: true when this scene is a length-split CONTINUATION of the
|
|
15722
15834
|
// previous one (the SAME physical shot, broken up only because it exceeded the
|
|
15723
15835
|
// clip ceiling). The scaffold then shares the splice keyframe — this scene's
|
|
15724
15836
|
// start frame IS the previous scene's end frame — so the join is seamless.
|
|
15725
|
-
continues_previous:
|
|
15837
|
+
continues_previous: z12.boolean().optional()
|
|
15726
15838
|
}).loose();
|
|
15727
|
-
var VideoBlueprint =
|
|
15728
|
-
source:
|
|
15729
|
-
global:
|
|
15730
|
-
music:
|
|
15731
|
-
present:
|
|
15732
|
-
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(),
|
|
15733
15845
|
// Absolute second the music enters in the reference (the bed often
|
|
15734
15846
|
// kicks in mid-ad, after the hook). We start the regenerated track here
|
|
15735
15847
|
// instead of at 0 so the timing matches.
|
|
15736
|
-
starts_at_s:
|
|
15848
|
+
starts_at_s: z12.number().optional(),
|
|
15737
15849
|
// Populated by the deconstruct when AudD (Shazam-style) recognizes the
|
|
15738
15850
|
// reference track. We never reuse it — only style the regenerated bed.
|
|
15739
|
-
identified_track:
|
|
15851
|
+
identified_track: z12.object({ title: z12.string().optional(), artist: z12.string().optional() }).loose().nullish()
|
|
15740
15852
|
}).loose().optional(),
|
|
15741
|
-
cast:
|
|
15742
|
-
|
|
15743
|
-
id:
|
|
15744
|
-
description:
|
|
15853
|
+
cast: z12.array(
|
|
15854
|
+
z12.object({
|
|
15855
|
+
id: z12.string().optional(),
|
|
15856
|
+
description: z12.string().optional(),
|
|
15745
15857
|
// The deconstruct's note on the target-market localization (e.g. "native
|
|
15746
15858
|
// French speaker") — read to derive the spoken-track language code.
|
|
15747
|
-
market_localization_note:
|
|
15859
|
+
market_localization_note: z12.string().optional()
|
|
15748
15860
|
}).loose()
|
|
15749
15861
|
).optional(),
|
|
15750
|
-
voiceover:
|
|
15862
|
+
voiceover: z12.object({
|
|
15751
15863
|
// on_camera | mixed → mouths are on screen (lip-sync candidates);
|
|
15752
15864
|
// voiceover | none → narration over the picture (no lip-sync).
|
|
15753
|
-
mode:
|
|
15754
|
-
voice_description:
|
|
15755
|
-
persona:
|
|
15865
|
+
mode: z12.string().optional(),
|
|
15866
|
+
voice_description: z12.string().optional(),
|
|
15867
|
+
persona: z12.string().optional()
|
|
15756
15868
|
}).loose().optional(),
|
|
15757
15869
|
// Visual palette — read only to colour a clean brand-card/CTA plate (the
|
|
15758
15870
|
// first hex is the dominant brand colour); never to drive frame generation.
|
|
15759
|
-
style:
|
|
15871
|
+
style: z12.object({ palette: z12.array(z12.object({ hex: z12.string().optional() }).loose()).optional() }).loose().optional()
|
|
15760
15872
|
}).loose().optional(),
|
|
15761
|
-
scenes:
|
|
15873
|
+
scenes: z12.array(Scene).min(1)
|
|
15762
15874
|
}).loose();
|
|
15763
15875
|
function injectHookPhysicality(blueprint) {
|
|
15764
15876
|
for (const scene of blueprint.scenes) {
|
|
@@ -15768,26 +15880,26 @@ function injectHookPhysicality(blueprint) {
|
|
|
15768
15880
|
scene.start_frame_prompt = `${prompt} The subject's physical state IS the scroll-stopper \u2014 render it explicitly, not a calm pose: ${why}.`;
|
|
15769
15881
|
}
|
|
15770
15882
|
}
|
|
15771
|
-
var AppearsItem =
|
|
15772
|
-
var RecurringElement =
|
|
15883
|
+
var AppearsItem = z12.union([z12.number(), z12.object({ scene: z12.number(), edge: z12.string().optional() }).loose()]);
|
|
15884
|
+
var RecurringElement = z12.object({
|
|
15773
15885
|
// person | animal | product | logo | badge | other
|
|
15774
|
-
type:
|
|
15775
|
-
label:
|
|
15776
|
-
description:
|
|
15777
|
-
expression:
|
|
15886
|
+
type: z12.string(),
|
|
15887
|
+
label: z12.string().optional(),
|
|
15888
|
+
description: z12.string().optional(),
|
|
15889
|
+
expression: z12.string().nullable().optional(),
|
|
15778
15890
|
// When the element maps to a global cast entry, its stable id (for annotation).
|
|
15779
|
-
cast_id:
|
|
15891
|
+
cast_id: z12.string().nullable().optional(),
|
|
15780
15892
|
// The label of another element that is the SAME individual as this one, shown
|
|
15781
15893
|
// in a DIFFERENT wardrobe/persona/state (e.g. one creator playing skeptic in a
|
|
15782
15894
|
// pink shirt and believer in a white shirt). Each look gets its own reference
|
|
15783
15895
|
// slot, but the face/identity must stay identical across them.
|
|
15784
|
-
same_as:
|
|
15896
|
+
same_as: z12.string().nullable().optional(),
|
|
15785
15897
|
// Scenes the element appears in. Either a bare list of scene indices (both
|
|
15786
15898
|
// edges) or per-{scene,edge} entries. Both forms are accepted and merged.
|
|
15787
|
-
scenes:
|
|
15788
|
-
appears_in:
|
|
15899
|
+
scenes: z12.array(z12.number()).optional(),
|
|
15900
|
+
appears_in: z12.array(AppearsItem).optional()
|
|
15789
15901
|
}).loose();
|
|
15790
|
-
var RecurringElements =
|
|
15902
|
+
var RecurringElements = z12.array(RecurringElement);
|
|
15791
15903
|
function sanitizeId2(raw, fallback) {
|
|
15792
15904
|
const id = raw.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
15793
15905
|
return /^[a-z]/.test(id) ? id : `${fallback}_${id}`.replace(/_+$/g, "") || fallback;
|
|
@@ -16205,7 +16317,7 @@ function scrubFloatSentences(text, floatDescs) {
|
|
|
16205
16317
|
return kept;
|
|
16206
16318
|
}
|
|
16207
16319
|
function sceneFloatDescs(scene) {
|
|
16208
|
-
const floats =
|
|
16320
|
+
const floats = z12.array(FloatingElement).safeParse(scene.floating_elements ?? []);
|
|
16209
16321
|
if (!floats.success) return [];
|
|
16210
16322
|
return floats.data.map((f) => f.description?.trim() ?? "").filter(Boolean);
|
|
16211
16323
|
}
|
|
@@ -17545,25 +17657,25 @@ function buildSfxMusic(blueprint, nodes) {
|
|
|
17545
17657
|
}
|
|
17546
17658
|
return tracks;
|
|
17547
17659
|
}
|
|
17548
|
-
var OverlayStyle =
|
|
17549
|
-
var Overlay =
|
|
17550
|
-
text:
|
|
17551
|
-
appears_at_s:
|
|
17552
|
-
duration_s:
|
|
17553
|
-
position:
|
|
17554
|
-
role:
|
|
17555
|
-
animation:
|
|
17556
|
-
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(),
|
|
17557
17669
|
style: OverlayStyle.optional()
|
|
17558
17670
|
}).loose();
|
|
17559
|
-
var FloatingElement =
|
|
17560
|
-
kind:
|
|
17561
|
-
description:
|
|
17562
|
-
brand_name:
|
|
17563
|
-
what_it_represents:
|
|
17564
|
-
appears_at_s:
|
|
17565
|
-
duration_s:
|
|
17566
|
-
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()
|
|
17567
17679
|
}).loose();
|
|
17568
17680
|
function escapeHtml(s) {
|
|
17569
17681
|
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
@@ -17595,7 +17707,7 @@ function positionClass(position) {
|
|
|
17595
17707
|
function collectCaptions(blueprint) {
|
|
17596
17708
|
return blueprint.scenes.flatMap((scene) => {
|
|
17597
17709
|
const sceneStart = scene.start_s ?? 0;
|
|
17598
|
-
const overlays =
|
|
17710
|
+
const overlays = z12.array(Overlay).safeParse(scene.overlays ?? []);
|
|
17599
17711
|
return overlays.success ? overlays.data.filter((ov) => Boolean(ov.text?.trim())).map((ov) => {
|
|
17600
17712
|
const at = ov.appears_at_s ?? sceneStart;
|
|
17601
17713
|
return { text: ov.text.trim(), at, end: at + (ov.duration_s ?? 2.5), ov };
|
|
@@ -17675,7 +17787,7 @@ function collectFloatWindows(blueprint, uiRouted) {
|
|
|
17675
17787
|
const windows = /* @__PURE__ */ new Map();
|
|
17676
17788
|
blueprint.scenes.forEach((scene, i) => {
|
|
17677
17789
|
const sceneStart = scene.start_s ?? 0;
|
|
17678
|
-
const floats =
|
|
17790
|
+
const floats = z12.array(FloatingElement).safeParse(scene.floating_elements ?? []);
|
|
17679
17791
|
if (!floats.success) return;
|
|
17680
17792
|
for (const fe of floats.data) {
|
|
17681
17793
|
const at = fe.appears_at_s ?? sceneStart;
|
|
@@ -18061,8 +18173,8 @@ function buildMotionBoard(blueprint) {
|
|
|
18061
18173
|
const end_s = scene.end_s ?? start_s + sceneDurationS(scene);
|
|
18062
18174
|
cursor = end_s;
|
|
18063
18175
|
const spoken = sceneSpokenText(scene);
|
|
18064
|
-
const overlays =
|
|
18065
|
-
const floats =
|
|
18176
|
+
const overlays = z12.array(Overlay).safeParse(scene.overlays ?? []);
|
|
18177
|
+
const floats = z12.array(FloatingElement).safeParse(scene.floating_elements ?? []);
|
|
18066
18178
|
const graphics = [
|
|
18067
18179
|
...(overlays.success ? overlays.data : []).filter((ov) => ov.text?.trim()).map((ov) => ({
|
|
18068
18180
|
kind: "text",
|
|
@@ -18289,23 +18401,23 @@ function videoReport(input, elementsInput) {
|
|
|
18289
18401
|
|
|
18290
18402
|
// src/commands/canvas/composition-path.ts
|
|
18291
18403
|
import { existsSync as existsSync3 } from "fs";
|
|
18292
|
-
import
|
|
18404
|
+
import path9 from "path";
|
|
18293
18405
|
function resolveShippedCanvasDir(name, startDir, exists = existsSync3, maxDepth = 8) {
|
|
18294
|
-
const rel =
|
|
18406
|
+
const rel = path9.join("canvas", name);
|
|
18295
18407
|
let dir = startDir;
|
|
18296
18408
|
for (let i = 0; i < maxDepth; i++) {
|
|
18297
|
-
const candidate =
|
|
18298
|
-
if (exists(
|
|
18299
|
-
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);
|
|
18300
18412
|
if (parent === dir) break;
|
|
18301
18413
|
dir = parent;
|
|
18302
18414
|
}
|
|
18303
|
-
return
|
|
18415
|
+
return path9.resolve(startDir, "../../../", rel);
|
|
18304
18416
|
}
|
|
18305
18417
|
|
|
18306
18418
|
// src/commands/canvas/gitignore.ts
|
|
18307
18419
|
import { appendFile, readFile as readFile5 } from "fs/promises";
|
|
18308
|
-
import
|
|
18420
|
+
import path10 from "path";
|
|
18309
18421
|
function missingGitignoreEntries(existing, entries) {
|
|
18310
18422
|
const present = new Set(
|
|
18311
18423
|
existing.split("\n").map((l) => l.trim().replace(/\/+$/, "")).filter((l) => l.length > 0 && !l.startsWith("#"))
|
|
@@ -18313,7 +18425,7 @@ function missingGitignoreEntries(existing, entries) {
|
|
|
18313
18425
|
return entries.filter((e) => !present.has(e.trim().replace(/\/+$/, "")));
|
|
18314
18426
|
}
|
|
18315
18427
|
async function ensureGitignore(dir, entries) {
|
|
18316
|
-
const file =
|
|
18428
|
+
const file = path10.join(dir, ".gitignore");
|
|
18317
18429
|
let existing;
|
|
18318
18430
|
try {
|
|
18319
18431
|
existing = await readFile5(file, "utf8");
|
|
@@ -18374,8 +18486,8 @@ async function loadTranscriptBestEffort(ref) {
|
|
|
18374
18486
|
async function stageCaptions(outDir, transcript) {
|
|
18375
18487
|
const text = transcript?.trim();
|
|
18376
18488
|
if (!text || text === "[]") return {};
|
|
18377
|
-
const compositionPath =
|
|
18378
|
-
await
|
|
18489
|
+
const compositionPath = path11.join(outDir, "tiktok-captions-composition");
|
|
18490
|
+
await cp2(SHIPPED_CAPTIONS_DIR, compositionPath, { recursive: true });
|
|
18379
18491
|
return { compositionPath };
|
|
18380
18492
|
}
|
|
18381
18493
|
function patchCompositionMeta(metaJson, dims) {
|
|
@@ -18392,10 +18504,10 @@ function patchCompositionHtml(html, dims) {
|
|
|
18392
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`);
|
|
18393
18505
|
}
|
|
18394
18506
|
async function stampCompositionDims(compositionDir, dims) {
|
|
18395
|
-
const metaPath =
|
|
18507
|
+
const metaPath = path11.join(compositionDir, "meta.json");
|
|
18396
18508
|
const rawMeta = await readFile6(metaPath, "utf8");
|
|
18397
18509
|
await writeFile2(metaPath, patchCompositionMeta(rawMeta, dims), "utf8");
|
|
18398
|
-
const htmlPath =
|
|
18510
|
+
const htmlPath = path11.join(compositionDir, "index.html");
|
|
18399
18511
|
const rawHtml = await readFile6(htmlPath, "utf8");
|
|
18400
18512
|
await writeFile2(htmlPath, patchCompositionHtml(rawHtml, dims), "utf8");
|
|
18401
18513
|
}
|
|
@@ -18535,6 +18647,10 @@ var scaffoldVideoCommand = defineCommand90({
|
|
|
18535
18647
|
args: {
|
|
18536
18648
|
file: { type: "positional", required: true, description: "Path to the reference video" },
|
|
18537
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
|
+
},
|
|
18538
18654
|
frames: { type: "string", description: '"generate" (default, anchored regen) or "reuse" (wire real frames in)' },
|
|
18539
18655
|
ambient: {
|
|
18540
18656
|
type: "boolean",
|
|
@@ -18561,11 +18677,19 @@ var scaffoldVideoCommand = defineCommand90({
|
|
|
18561
18677
|
}
|
|
18562
18678
|
},
|
|
18563
18679
|
async run({ args }) {
|
|
18564
|
-
const videoPath =
|
|
18565
|
-
const base =
|
|
18566
|
-
const
|
|
18567
|
-
|
|
18568
|
-
|
|
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");
|
|
18569
18693
|
const frames = args.frames === "reuse" ? "reuse" : "generate";
|
|
18570
18694
|
const maxScenes = args["max-scenes"] ? Number(args["max-scenes"]) : void 0;
|
|
18571
18695
|
if (Number.isFinite(maxScenes)) {
|
|
@@ -18584,7 +18708,7 @@ var scaffoldVideoCommand = defineCommand90({
|
|
|
18584
18708
|
shotCuts
|
|
18585
18709
|
});
|
|
18586
18710
|
const { blueprint, elements, transcript, creditsSpent } = await runAnalysisPasses(deconstructCanvas, selectModel);
|
|
18587
|
-
await
|
|
18711
|
+
await mkdir2(outDir, { recursive: true });
|
|
18588
18712
|
const annotated = annotateBlueprintWithElements(blueprint, elements);
|
|
18589
18713
|
await writeFile2(blueprintPath, `${JSON.stringify(annotated, null, 2)}
|
|
18590
18714
|
`, "utf8");
|
|
@@ -18605,10 +18729,10 @@ var scaffoldVideoCommand = defineCommand90({
|
|
|
18605
18729
|
`
|
|
18606
18730
|
);
|
|
18607
18731
|
}
|
|
18608
|
-
const compositionDest =
|
|
18609
|
-
await
|
|
18732
|
+
const compositionDest = path11.join(outDir, "video-overlay-composition");
|
|
18733
|
+
await cp2(SHIPPED_COMPOSITION_DIR, compositionDest, { recursive: true });
|
|
18610
18734
|
await stampCompositionDims(compositionDest, outDims);
|
|
18611
|
-
const indexPath =
|
|
18735
|
+
const indexPath = path11.join(compositionDest, "index.html");
|
|
18612
18736
|
const overlayHtml = buildOverlayHtml(blueprint, { captionsActive: Boolean(transcript) });
|
|
18613
18737
|
const indexHtml = await readFile6(indexPath, "utf8");
|
|
18614
18738
|
const injected = indexHtml.replace("<!--OVERLAYS-->", () => overlayHtml);
|
|
@@ -18624,9 +18748,9 @@ var scaffoldVideoCommand = defineCommand90({
|
|
|
18624
18748
|
const opts = {
|
|
18625
18749
|
imageModel,
|
|
18626
18750
|
videoModel,
|
|
18627
|
-
overlayCompositionPath:
|
|
18628
|
-
captionsCompositionPath: captions.compositionPath ?
|
|
18629
|
-
blueprintPath:
|
|
18751
|
+
overlayCompositionPath: path11.relative(outDir, compositionDest),
|
|
18752
|
+
captionsCompositionPath: captions.compositionPath ? path11.relative(outDir, captions.compositionPath) : void 0,
|
|
18753
|
+
blueprintPath: path11.relative(outDir, blueprintPath),
|
|
18630
18754
|
frames,
|
|
18631
18755
|
ambient: Boolean(args.ambient),
|
|
18632
18756
|
...args.aspect ? { aspect: String(args.aspect) } : {},
|
|
@@ -18684,7 +18808,7 @@ var scaffoldVideoCommand = defineCommand90({
|
|
|
18684
18808
|
run_estimated_credits: validation.estimatedCredits
|
|
18685
18809
|
},
|
|
18686
18810
|
checklist: {
|
|
18687
|
-
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.`,
|
|
18688
18812
|
recurring_elements_to_supply: report.elements,
|
|
18689
18813
|
voices_to_confirm: report.dialogue.map((d) => ({
|
|
18690
18814
|
scene: d.scene,
|
|
@@ -18711,7 +18835,7 @@ var scaffoldVideoCommand = defineCommand90({
|
|
|
18711
18835
|
|
|
18712
18836
|
// src/commands/canvas/set-prompt.ts
|
|
18713
18837
|
import { readFile as readFile7, writeFile as writeFile3 } from "fs/promises";
|
|
18714
|
-
import
|
|
18838
|
+
import path12 from "path";
|
|
18715
18839
|
import { defineCommand as defineCommand91 } from "citty";
|
|
18716
18840
|
function setNodePrompt(canvas, nodeId, text) {
|
|
18717
18841
|
const nodes = canvas?.nodes;
|
|
@@ -18739,7 +18863,7 @@ var setPromptCommand = defineCommand91({
|
|
|
18739
18863
|
"text-file": { type: "string", description: "Read the new prompt from a UTF-8 file (preserves accents/newlines)" }
|
|
18740
18864
|
},
|
|
18741
18865
|
async run({ args }) {
|
|
18742
|
-
const filePath =
|
|
18866
|
+
const filePath = path12.resolve(String(args.file));
|
|
18743
18867
|
let canvas;
|
|
18744
18868
|
try {
|
|
18745
18869
|
canvas = JSON.parse(await readFile7(filePath, "utf8"));
|
|
@@ -18749,7 +18873,7 @@ var setPromptCommand = defineCommand91({
|
|
|
18749
18873
|
process.exit(2);
|
|
18750
18874
|
}
|
|
18751
18875
|
let text;
|
|
18752
|
-
if (args["text-file"]) text = await readFile7(
|
|
18876
|
+
if (args["text-file"]) text = await readFile7(path12.resolve(String(args["text-file"])), "utf8");
|
|
18753
18877
|
else if (args.text !== void 0) text = String(args.text);
|
|
18754
18878
|
else {
|
|
18755
18879
|
process.stderr.write(
|
|
@@ -18770,7 +18894,7 @@ var setPromptCommand = defineCommand91({
|
|
|
18770
18894
|
process.exit(2);
|
|
18771
18895
|
return;
|
|
18772
18896
|
}
|
|
18773
|
-
const validation = await validateCanvasDeep(resolveRelativeCanvasPaths(updated,
|
|
18897
|
+
const validation = await validateCanvasDeep(resolveRelativeCanvasPaths(updated, path12.dirname(filePath)), defaultRegistry());
|
|
18774
18898
|
if (!validation.ok) {
|
|
18775
18899
|
process.stderr.write(`${JSON.stringify({ ok: false, error: { code: "validation", issues: validation.issues } }, null, 2)}
|
|
18776
18900
|
`);
|
|
@@ -18786,7 +18910,7 @@ var setPromptCommand = defineCommand91({
|
|
|
18786
18910
|
|
|
18787
18911
|
// src/commands/canvas/validate.ts
|
|
18788
18912
|
import { readFile as readFile8 } from "fs/promises";
|
|
18789
|
-
import
|
|
18913
|
+
import path13 from "path";
|
|
18790
18914
|
import { defineCommand as defineCommand92 } from "citty";
|
|
18791
18915
|
var validateCommand = defineCommand92({
|
|
18792
18916
|
meta: {
|
|
@@ -18795,7 +18919,7 @@ var validateCommand = defineCommand92({
|
|
|
18795
18919
|
},
|
|
18796
18920
|
args: { file: { type: "positional", required: true, description: "Path to canvas JSON" } },
|
|
18797
18921
|
async run({ args }) {
|
|
18798
|
-
const filePath =
|
|
18922
|
+
const filePath = path13.resolve(String(args.file));
|
|
18799
18923
|
const raw = await readFile8(filePath, "utf8");
|
|
18800
18924
|
let parsed;
|
|
18801
18925
|
try {
|
|
@@ -18806,7 +18930,7 @@ var validateCommand = defineCommand92({
|
|
|
18806
18930
|
`);
|
|
18807
18931
|
process.exit(2);
|
|
18808
18932
|
}
|
|
18809
|
-
parsed = resolveRelativeCanvasPaths(parsed,
|
|
18933
|
+
parsed = resolveRelativeCanvasPaths(parsed, path13.dirname(filePath));
|
|
18810
18934
|
const result = await validateCanvasDeep(parsed, defaultRegistry());
|
|
18811
18935
|
if (!result.ok) {
|
|
18812
18936
|
process.stderr.write(`${JSON.stringify({ ok: false, issues: result.issues }, null, 2)}
|
|
@@ -18943,6 +19067,16 @@ registerSchema({
|
|
|
18943
19067
|
type: "string",
|
|
18944
19068
|
description: "Optional URL of the original reference ad",
|
|
18945
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
|
|
18946
19080
|
}
|
|
18947
19081
|
}
|
|
18948
19082
|
});
|
|
@@ -18952,6 +19086,13 @@ function detectCreativeContentType(filePath) {
|
|
|
18952
19086
|
unsupportedMessage: "Unsupported creative image extension. Use PNG, JPG, or WebP."
|
|
18953
19087
|
});
|
|
18954
19088
|
}
|
|
19089
|
+
function chatIdFromEnv() {
|
|
19090
|
+
try {
|
|
19091
|
+
return getEnv().BAKER_CHAT_ID || void 0;
|
|
19092
|
+
} catch {
|
|
19093
|
+
return void 0;
|
|
19094
|
+
}
|
|
19095
|
+
}
|
|
18955
19096
|
function parseOptionalUrl(value) {
|
|
18956
19097
|
if (value === void 0 || value.trim() === "") {
|
|
18957
19098
|
return void 0;
|
|
@@ -18982,7 +19123,11 @@ async function publishCreative(args, deps = defaultImageApiDeps) {
|
|
|
18982
19123
|
return publishImageAsCreative(deps, {
|
|
18983
19124
|
imageId: upload.imageId,
|
|
18984
19125
|
title,
|
|
18985
|
-
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()
|
|
18986
19131
|
});
|
|
18987
19132
|
}
|
|
18988
19133
|
var publishCommand = defineCommand94({
|
|
@@ -18998,6 +19143,16 @@ var publishCommand = defineCommand94({
|
|
|
18998
19143
|
type: "string",
|
|
18999
19144
|
description: "Optional URL of the original reference ad",
|
|
19000
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
|
|
19001
19156
|
}
|
|
19002
19157
|
},
|
|
19003
19158
|
run: async ({ args }) => {
|
|
@@ -19016,7 +19171,9 @@ var publishCommand = defineCommand94({
|
|
|
19016
19171
|
file,
|
|
19017
19172
|
title,
|
|
19018
19173
|
context: args.context,
|
|
19019
|
-
sourceReferenceUrl: args.sourceReferenceUrl
|
|
19174
|
+
sourceReferenceUrl: args.sourceReferenceUrl,
|
|
19175
|
+
slug: args.slug,
|
|
19176
|
+
runId: args.runId
|
|
19020
19177
|
});
|
|
19021
19178
|
writeJson({ ok: true, data });
|
|
19022
19179
|
} catch (err) {
|
|
@@ -19914,9 +20071,9 @@ async function readImageBuffer(pathOrUrl) {
|
|
|
19914
20071
|
}
|
|
19915
20072
|
return readFile10(pathOrUrl);
|
|
19916
20073
|
}
|
|
19917
|
-
async function isDirectory(
|
|
20074
|
+
async function isDirectory(path14) {
|
|
19918
20075
|
try {
|
|
19919
|
-
const s = await stat2(
|
|
20076
|
+
const s = await stat2(path14);
|
|
19920
20077
|
return s.isDirectory();
|
|
19921
20078
|
} catch {
|
|
19922
20079
|
return false;
|
|
@@ -23978,338 +24135,11 @@ var schemaCommand = defineCommand147({
|
|
|
23978
24135
|
}
|
|
23979
24136
|
});
|
|
23980
24137
|
|
|
23981
|
-
// src/commands/tags/index.ts
|
|
23982
|
-
import { defineCommand as defineCommand148 } from "citty";
|
|
23983
|
-
|
|
23984
|
-
// src/commands/tags/shared.ts
|
|
23985
|
-
function failValidation3(message) {
|
|
23986
|
-
writeJson({ ok: false, error: { code: "VALIDATION_ERROR", message } });
|
|
23987
|
-
process.exit(1);
|
|
23988
|
-
}
|
|
23989
|
-
function failApi3(err) {
|
|
23990
|
-
if (err instanceof ApiError) {
|
|
23991
|
-
writeJson({ ok: false, error: { code: err.code, message: err.message } });
|
|
23992
|
-
process.exit(1);
|
|
23993
|
-
}
|
|
23994
|
-
if (err instanceof Error) {
|
|
23995
|
-
writeJson({ ok: false, error: { code: "INTERNAL_ERROR", message: err.message } });
|
|
23996
|
-
process.exit(1);
|
|
23997
|
-
}
|
|
23998
|
-
writeJson({ ok: false, error: { code: "INTERNAL_ERROR", message: "Unexpected error" } });
|
|
23999
|
-
process.exit(1);
|
|
24000
|
-
}
|
|
24001
|
-
function parseTagType(value) {
|
|
24002
|
-
const parsed = tagTypeSchema.safeParse(value);
|
|
24003
|
-
if (!parsed.success) {
|
|
24004
|
-
failValidation3(`Unknown tag type "${value}". Valid types: ${TAG_TYPES.join(", ")}.`);
|
|
24005
|
-
}
|
|
24006
|
-
return parsed.data;
|
|
24007
|
-
}
|
|
24008
|
-
function toArray(value) {
|
|
24009
|
-
if (value === void 0 || typeof value === "boolean") {
|
|
24010
|
-
return [];
|
|
24011
|
-
}
|
|
24012
|
-
return Array.isArray(value) ? value : [value];
|
|
24013
|
-
}
|
|
24014
|
-
function parseSetArgs(value) {
|
|
24015
|
-
const config = {};
|
|
24016
|
-
for (const entry of toArray(value)) {
|
|
24017
|
-
const eq = entry.indexOf("=");
|
|
24018
|
-
if (eq <= 0) {
|
|
24019
|
-
failValidation3(`--set expects key=value, got "${entry}".`);
|
|
24020
|
-
}
|
|
24021
|
-
config[entry.slice(0, eq)] = entry.slice(eq + 1);
|
|
24022
|
-
}
|
|
24023
|
-
return config;
|
|
24024
|
-
}
|
|
24025
|
-
function parseListArg(value) {
|
|
24026
|
-
return toArray(value).flatMap(
|
|
24027
|
-
(entry) => entry.split(",").map((item) => item.trim()).filter((item) => item !== "")
|
|
24028
|
-
);
|
|
24029
|
-
}
|
|
24030
|
-
function rejectSecretSets(type, config) {
|
|
24031
|
-
const secretFields = TAG_SECRET_FIELDS[type];
|
|
24032
|
-
const offending = Object.keys(config).filter((key) => secretFields.includes(key));
|
|
24033
|
-
if (offending.length > 0) {
|
|
24034
|
-
failValidation3(
|
|
24035
|
-
`${offending.join(", ")} ${offending.length === 1 ? "is a secret field" : "are secret fields"} \u2014 never pass secret values on the command line. Re-run with --request-secret ${offending[0]} and the user will provide it via the secure tag form in the chat.`
|
|
24036
|
-
);
|
|
24037
|
-
}
|
|
24038
|
-
}
|
|
24039
|
-
function validateRequestSecrets(type, fields) {
|
|
24040
|
-
const requestable = TAG_REQUESTABLE_SECRET_FIELDS[type];
|
|
24041
|
-
const invalid = fields.filter((field) => !requestable.includes(field));
|
|
24042
|
-
if (invalid.length > 0) {
|
|
24043
|
-
failValidation3(
|
|
24044
|
-
`Cannot request ${invalid.join(", ")} for a ${type} tag. Requestable secret fields: ${requestable.length > 0 ? requestable.join(", ") : "(none \u2014 this type has no secret fields)"}.`
|
|
24045
|
-
);
|
|
24046
|
-
}
|
|
24047
|
-
}
|
|
24048
|
-
function renderEffectiveEntry(entry) {
|
|
24049
|
-
const parts = [entry.ref, entry.type];
|
|
24050
|
-
if (entry.identifier !== void 0) {
|
|
24051
|
-
parts.push(entry.identifier);
|
|
24052
|
-
}
|
|
24053
|
-
if (entry.staged !== void 0) {
|
|
24054
|
-
parts.push(`[staged: ${entry.staged}]`);
|
|
24055
|
-
}
|
|
24056
|
-
const secretBits = [
|
|
24057
|
-
...entry.secretsSet.map((field) => `${field} \u2713 set`),
|
|
24058
|
-
...entry.secretsPending.map((field) => `${field} \u23F3 pending`)
|
|
24059
|
-
];
|
|
24060
|
-
if (secretBits.length > 0) {
|
|
24061
|
-
parts.push(`[secrets: ${secretBits.join(", ")}]`);
|
|
24062
|
-
}
|
|
24063
|
-
return parts.join(" ");
|
|
24064
|
-
}
|
|
24065
|
-
|
|
24066
|
-
// src/commands/tags/index.ts
|
|
24067
|
-
registerSchema({
|
|
24068
|
-
command: "tags.list",
|
|
24069
|
-
description: "Effective marketing tags for this chat: production tags overlaid with the ops staged in this chat's draft. The printed refs (tag ids or tag_temp_*) are exactly what flow side-effect tagIds should reference.",
|
|
24070
|
-
args: {
|
|
24071
|
-
json: { type: "boolean", description: "Print the raw JSON envelope instead of the readable list", required: false }
|
|
24072
|
-
}
|
|
24073
|
-
});
|
|
24074
|
-
registerSchema({
|
|
24075
|
-
command: "tags.add",
|
|
24076
|
-
description: "Stage creation of a marketing tag (applies when the chat publishes). Set every non-secret field with --set; request secret fields (API keys, tokens, OAuth connections) with --request-secret \u2014 the user provides them via the secure tag form in the chat, never through the CLI.",
|
|
24077
|
-
args: {
|
|
24078
|
-
type: {
|
|
24079
|
-
type: "positional",
|
|
24080
|
-
description: "Tag type (see `baker tags list` output / meta, googleAnalytics, clarity, \u2026)",
|
|
24081
|
-
required: true
|
|
24082
|
-
},
|
|
24083
|
-
set: { type: "string", description: "Repeatable key=value for non-secret config fields", required: false },
|
|
24084
|
-
"request-secret": {
|
|
24085
|
-
type: "string",
|
|
24086
|
-
description: "Repeatable secret field name to request from the user",
|
|
24087
|
-
required: false
|
|
24088
|
-
}
|
|
24089
|
-
}
|
|
24090
|
-
});
|
|
24091
|
-
registerSchema({
|
|
24092
|
-
command: "tags.update",
|
|
24093
|
-
description: "Stage an update to a tag by ref (real tag id, or tag_temp_* to amend a create staged in this chat). --set patches fields, --clear removes them, --request-secret asks the user for secret values.",
|
|
24094
|
-
args: {
|
|
24095
|
-
ref: { type: "positional", description: "Tag ref from `baker tags list`", required: true },
|
|
24096
|
-
set: { type: "string", description: "Repeatable key=value for non-secret config fields", required: false },
|
|
24097
|
-
clear: { type: "string", description: "Repeatable field name to clear", required: false },
|
|
24098
|
-
"request-secret": {
|
|
24099
|
-
type: "string",
|
|
24100
|
-
description: "Repeatable secret field name to request from the user",
|
|
24101
|
-
required: false
|
|
24102
|
-
}
|
|
24103
|
-
}
|
|
24104
|
-
});
|
|
24105
|
-
registerSchema({
|
|
24106
|
-
command: "tags.remove",
|
|
24107
|
-
description: "Stage deletion of a tag by ref (applies on publish). Removing a tag_temp_* ref drops the staged create instead.",
|
|
24108
|
-
args: { ref: { type: "positional", description: "Tag ref from `baker tags list`", required: true } }
|
|
24109
|
-
});
|
|
24110
|
-
async function listTags(json) {
|
|
24111
|
-
try {
|
|
24112
|
-
const chatId = requireChatId();
|
|
24113
|
-
const response = await apiPost("/api/tags/list", { chatId });
|
|
24114
|
-
if (json) {
|
|
24115
|
-
writeJson({ ok: true, data: response });
|
|
24116
|
-
return;
|
|
24117
|
-
}
|
|
24118
|
-
if (response.tags.length === 0) {
|
|
24119
|
-
process.stdout.write("No tags configured. Stage one with `baker tags add <type> --set key=value`.\n");
|
|
24120
|
-
return;
|
|
24121
|
-
}
|
|
24122
|
-
process.stdout.write(`${response.tags.map(renderEffectiveEntry).join("\n")}
|
|
24123
|
-
`);
|
|
24124
|
-
} catch (err) {
|
|
24125
|
-
failApi3(err);
|
|
24126
|
-
}
|
|
24127
|
-
}
|
|
24128
|
-
var listCommand7 = defineCommand148({
|
|
24129
|
-
meta: {
|
|
24130
|
-
name: "list",
|
|
24131
|
-
description: "Effective tags for this chat (production + staged). Refs printed here are what flow side-effect tagIds should use. Example: baker tags list"
|
|
24132
|
-
},
|
|
24133
|
-
args: { json: { type: "boolean", description: "Print the raw JSON envelope instead of the readable list" } },
|
|
24134
|
-
run: async ({ args }) => {
|
|
24135
|
-
await listTags(args.json === true);
|
|
24136
|
-
}
|
|
24137
|
-
});
|
|
24138
|
-
async function stage(body) {
|
|
24139
|
-
try {
|
|
24140
|
-
const response = await apiPost("/api/tags/draft/stage", body);
|
|
24141
|
-
writeJson({ ok: true, data: response });
|
|
24142
|
-
} catch (err) {
|
|
24143
|
-
failApi3(err);
|
|
24144
|
-
}
|
|
24145
|
-
}
|
|
24146
|
-
var addCommand2 = defineCommand148({
|
|
24147
|
-
meta: {
|
|
24148
|
-
name: "add",
|
|
24149
|
-
description: "Stage a new tag (applies on publish). Secret fields are never passed here \u2014 use --request-secret and the user fills them in the chat's secure tag form. Example: baker tags add meta --set pixelId=123456 --request-secret accessToken"
|
|
24150
|
-
},
|
|
24151
|
-
args: {
|
|
24152
|
-
type: {
|
|
24153
|
-
type: "positional",
|
|
24154
|
-
description: "Tag type (meta, googleAnalytics, googleAds, clarity, \u2026)",
|
|
24155
|
-
required: true
|
|
24156
|
-
},
|
|
24157
|
-
set: { type: "string", description: "key=value for a non-secret config field (repeatable)" },
|
|
24158
|
-
"request-secret": { type: "string", description: "Secret field name the user should provide (repeatable)" }
|
|
24159
|
-
},
|
|
24160
|
-
run: async ({ args }) => {
|
|
24161
|
-
const type = parseTagType(args.type);
|
|
24162
|
-
const config = parseSetArgs(args.set);
|
|
24163
|
-
const requestSecrets = parseListArg(args["request-secret"]);
|
|
24164
|
-
rejectSecretSets(type, config);
|
|
24165
|
-
validateRequestSecrets(type, requestSecrets);
|
|
24166
|
-
const chatId = requireChatId();
|
|
24167
|
-
await stage({
|
|
24168
|
-
kind: "create",
|
|
24169
|
-
chatId,
|
|
24170
|
-
type,
|
|
24171
|
-
config,
|
|
24172
|
-
...requestSecrets.length > 0 ? { requestSecrets } : {}
|
|
24173
|
-
});
|
|
24174
|
-
}
|
|
24175
|
-
});
|
|
24176
|
-
var updateCommand3 = defineCommand148({
|
|
24177
|
-
meta: {
|
|
24178
|
-
name: "update",
|
|
24179
|
-
description: "Stage an update to a tag. A tag_temp_* ref amends the create staged in this chat. Example: baker tags update <ref> --set pixelId=999 --clear testEventCode"
|
|
24180
|
-
},
|
|
24181
|
-
args: {
|
|
24182
|
-
ref: { type: "positional", description: "Tag ref from `baker tags list`", required: true },
|
|
24183
|
-
set: { type: "string", description: "key=value patch for a non-secret config field (repeatable)" },
|
|
24184
|
-
clear: { type: "string", description: "Field name to clear (repeatable)" },
|
|
24185
|
-
"request-secret": { type: "string", description: "Secret field name the user should provide (repeatable)" }
|
|
24186
|
-
},
|
|
24187
|
-
run: async ({ args }) => {
|
|
24188
|
-
const config = parseSetArgs(args.set);
|
|
24189
|
-
const clearFields = parseListArg(args.clear);
|
|
24190
|
-
const requestSecrets = parseListArg(args["request-secret"]);
|
|
24191
|
-
if (Object.keys(config).length === 0 && clearFields.length === 0 && requestSecrets.length === 0) {
|
|
24192
|
-
failValidation3("Nothing to update \u2014 pass --set, --clear, or --request-secret.");
|
|
24193
|
-
}
|
|
24194
|
-
const chatId = requireChatId();
|
|
24195
|
-
await stage({
|
|
24196
|
-
kind: "update",
|
|
24197
|
-
chatId,
|
|
24198
|
-
ref: args.ref,
|
|
24199
|
-
...Object.keys(config).length > 0 ? { config } : {},
|
|
24200
|
-
...clearFields.length > 0 ? { clearFields } : {},
|
|
24201
|
-
...requestSecrets.length > 0 ? { requestSecrets } : {}
|
|
24202
|
-
});
|
|
24203
|
-
}
|
|
24204
|
-
});
|
|
24205
|
-
var removeCommand5 = defineCommand148({
|
|
24206
|
-
meta: {
|
|
24207
|
-
name: "remove",
|
|
24208
|
-
description: "Stage deletion of a tag (applies on publish). Removing a tag_temp_* ref drops the staged create instead. Example: baker tags remove <ref>"
|
|
24209
|
-
},
|
|
24210
|
-
args: { ref: { type: "positional", description: "Tag ref from `baker tags list`", required: true } },
|
|
24211
|
-
run: async ({ args }) => {
|
|
24212
|
-
const chatId = requireChatId();
|
|
24213
|
-
await stage({ kind: "delete", chatId, ref: args.ref });
|
|
24214
|
-
}
|
|
24215
|
-
});
|
|
24216
|
-
async function listDraft3() {
|
|
24217
|
-
try {
|
|
24218
|
-
const chatId = requireChatId();
|
|
24219
|
-
const response = await apiPost("/api/tags/draft", { chatId });
|
|
24220
|
-
writeJson({ ok: true, data: response });
|
|
24221
|
-
} catch (err) {
|
|
24222
|
-
failApi3(err);
|
|
24223
|
-
}
|
|
24224
|
-
}
|
|
24225
|
-
var draftListCommand = defineCommand148({
|
|
24226
|
-
meta: { name: "list", description: "Review the tag ops staged in this chat. Example: baker tags draft" },
|
|
24227
|
-
run: async () => {
|
|
24228
|
-
await listDraft3();
|
|
24229
|
-
}
|
|
24230
|
-
});
|
|
24231
|
-
var draftRemoveCommand = defineCommand148({
|
|
24232
|
-
meta: {
|
|
24233
|
-
name: "remove",
|
|
24234
|
-
description: "Drop one staged tag op by ref. Example: baker tags draft remove tag_temp_abc123"
|
|
24235
|
-
},
|
|
24236
|
-
args: { ref: { type: "positional", description: "Staged op ref", required: true } },
|
|
24237
|
-
run: async ({ args }) => {
|
|
24238
|
-
try {
|
|
24239
|
-
const chatId = requireChatId();
|
|
24240
|
-
const response = await apiPost("/api/tags/draft/remove", {
|
|
24241
|
-
chatId,
|
|
24242
|
-
ref: args.ref
|
|
24243
|
-
});
|
|
24244
|
-
writeJson({ ok: true, data: response });
|
|
24245
|
-
} catch (err) {
|
|
24246
|
-
failApi3(err);
|
|
24247
|
-
}
|
|
24248
|
-
}
|
|
24249
|
-
});
|
|
24250
|
-
var draftClearCommand = defineCommand148({
|
|
24251
|
-
meta: {
|
|
24252
|
-
name: "clear",
|
|
24253
|
-
description: "Drop ALL tag ops staged in this chat \u2014 nothing will apply on publish. Example: baker tags draft clear"
|
|
24254
|
-
},
|
|
24255
|
-
run: async () => {
|
|
24256
|
-
try {
|
|
24257
|
-
const chatId = requireChatId();
|
|
24258
|
-
const response = await apiPost("/api/tags/draft/clear", { chatId });
|
|
24259
|
-
writeJson({ ok: true, data: response });
|
|
24260
|
-
} catch (err) {
|
|
24261
|
-
failApi3(err);
|
|
24262
|
-
}
|
|
24263
|
-
}
|
|
24264
|
-
});
|
|
24265
|
-
var draftCommand3 = defineCommand148({
|
|
24266
|
-
meta: {
|
|
24267
|
-
name: "draft",
|
|
24268
|
-
description: "Review and edit the tag ops staged in this chat BEFORE publish. Subcommands: list (default), remove, clear. Ops never touch production tags until the chat is published."
|
|
24269
|
-
},
|
|
24270
|
-
subCommands: {
|
|
24271
|
-
list: draftListCommand,
|
|
24272
|
-
remove: draftRemoveCommand,
|
|
24273
|
-
clear: draftClearCommand
|
|
24274
|
-
},
|
|
24275
|
-
run: async () => {
|
|
24276
|
-
await listDraft3();
|
|
24277
|
-
}
|
|
24278
|
-
});
|
|
24279
|
-
var tagsCommand3 = defineCommand148({
|
|
24280
|
-
meta: {
|
|
24281
|
-
name: "tags",
|
|
24282
|
-
description: `Manage the client's marketing/analytics tags (Meta pixel, GA4, Google Ads, GTM, Clarity, Hotjar, \u2026) as per-chat STAGED changes \u2014 nothing touches production until the chat is published.
|
|
24283
|
-
|
|
24284
|
-
Secrets: secret fields (accessToken, apiSecret, authorizationToken, apiKey, conversionToken, oauthProviderId) are NEVER typed into chat or passed to this CLI. Stage with --request-secret <field>, then invoke the request_tag_input tool (baker_ui) so the user fills them in the dashboard's secure tag form.
|
|
24285
|
-
|
|
24286
|
-
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.
|
|
24287
|
-
|
|
24288
|
-
Examples:
|
|
24289
|
-
baker tags list # production + staged, with secret status
|
|
24290
|
-
baker tags add clarity --set projectId=abcde12345 # client-only tag, no secrets needed
|
|
24291
|
-
baker tags add meta --set pixelId=123 --request-secret accessToken
|
|
24292
|
-
baker tags update <ref> --set pixelId=999 --clear testEventCode
|
|
24293
|
-
baker tags remove <ref> # stage deletion (temp ref = drop the create)
|
|
24294
|
-
baker tags draft # review staged ops before finishing`
|
|
24295
|
-
},
|
|
24296
|
-
subCommands: {
|
|
24297
|
-
list: listCommand7,
|
|
24298
|
-
add: addCommand2,
|
|
24299
|
-
update: updateCommand3,
|
|
24300
|
-
remove: removeCommand5,
|
|
24301
|
-
draft: draftCommand3
|
|
24302
|
-
},
|
|
24303
|
-
run: async () => {
|
|
24304
|
-
await listTags(false);
|
|
24305
|
-
}
|
|
24306
|
-
});
|
|
24307
|
-
|
|
24308
24138
|
// src/commands/testimonials/index.ts
|
|
24309
|
-
import { defineCommand as
|
|
24139
|
+
import { defineCommand as defineCommand151 } from "citty";
|
|
24310
24140
|
|
|
24311
24141
|
// src/commands/testimonials/get.ts
|
|
24312
|
-
import { defineCommand as
|
|
24142
|
+
import { defineCommand as defineCommand148 } from "citty";
|
|
24313
24143
|
registerSchema({
|
|
24314
24144
|
command: "testimonials.get",
|
|
24315
24145
|
description: "Get a single testimonial by ID",
|
|
@@ -24317,7 +24147,7 @@ registerSchema({
|
|
|
24317
24147
|
id: { type: "string", description: "Testimonial ID", required: true }
|
|
24318
24148
|
}
|
|
24319
24149
|
});
|
|
24320
|
-
var getCommand4 =
|
|
24150
|
+
var getCommand4 = defineCommand148({
|
|
24321
24151
|
meta: { name: "get", description: "Get a single testimonial by ID. Example: baker testimonials get j571abc123" },
|
|
24322
24152
|
args: {
|
|
24323
24153
|
id: { type: "positional", description: "Testimonial ID", required: false },
|
|
@@ -24354,7 +24184,7 @@ var getCommand4 = defineCommand149({
|
|
|
24354
24184
|
});
|
|
24355
24185
|
|
|
24356
24186
|
// src/commands/testimonials/list.ts
|
|
24357
|
-
import { defineCommand as
|
|
24187
|
+
import { defineCommand as defineCommand149 } from "citty";
|
|
24358
24188
|
registerSchema({
|
|
24359
24189
|
command: "testimonials.list",
|
|
24360
24190
|
description: "List testimonials with optional filters.",
|
|
@@ -24384,7 +24214,7 @@ registerSchema({
|
|
|
24384
24214
|
limit: { type: "number", description: "Max results (default 50)", required: false, default: 50 }
|
|
24385
24215
|
}
|
|
24386
24216
|
});
|
|
24387
|
-
var
|
|
24217
|
+
var listCommand7 = defineCommand149({
|
|
24388
24218
|
meta: {
|
|
24389
24219
|
name: "list",
|
|
24390
24220
|
description: "List testimonials with optional filters. Example: baker testimonials list --source google --sentiment positive"
|
|
@@ -24433,7 +24263,7 @@ var listCommand8 = defineCommand150({
|
|
|
24433
24263
|
});
|
|
24434
24264
|
|
|
24435
24265
|
// src/commands/testimonials/search.ts
|
|
24436
|
-
import { defineCommand as
|
|
24266
|
+
import { defineCommand as defineCommand150 } from "citty";
|
|
24437
24267
|
registerSchema({
|
|
24438
24268
|
command: "testimonials.search",
|
|
24439
24269
|
description: "Search testimonials by text query. Uses hybrid BM25 + vector + reranking.",
|
|
@@ -24464,7 +24294,7 @@ registerSchema({
|
|
|
24464
24294
|
tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
|
|
24465
24295
|
}
|
|
24466
24296
|
});
|
|
24467
|
-
var searchCommand2 =
|
|
24297
|
+
var searchCommand2 = defineCommand150({
|
|
24468
24298
|
meta: {
|
|
24469
24299
|
name: "search",
|
|
24470
24300
|
description: "Semantic search testimonials by text query. Uses hybrid BM25 + vector + reranking. Example: baker testimonials search 'great service' --rating-min 4"
|
|
@@ -24535,10 +24365,10 @@ var searchCommand2 = defineCommand151({
|
|
|
24535
24365
|
});
|
|
24536
24366
|
|
|
24537
24367
|
// src/commands/testimonials/tags.ts
|
|
24538
|
-
var
|
|
24368
|
+
var tagsCommand3 = makeTagsCommand("testimonials", "testimonial", "/api/testimonials/tags");
|
|
24539
24369
|
|
|
24540
24370
|
// src/commands/testimonials/index.ts
|
|
24541
|
-
var testimonialsCommand =
|
|
24371
|
+
var testimonialsCommand = defineCommand151({
|
|
24542
24372
|
meta: {
|
|
24543
24373
|
name: "testimonials",
|
|
24544
24374
|
description: `Find and browse testimonials in Baker. Subcommands: search, get, list, tags.
|
|
@@ -24553,16 +24383,16 @@ Examples:
|
|
|
24553
24383
|
subCommands: {
|
|
24554
24384
|
get: getCommand4,
|
|
24555
24385
|
search: searchCommand2,
|
|
24556
|
-
list:
|
|
24557
|
-
tags:
|
|
24386
|
+
list: listCommand7,
|
|
24387
|
+
tags: tagsCommand3
|
|
24558
24388
|
}
|
|
24559
24389
|
});
|
|
24560
24390
|
|
|
24561
24391
|
// src/commands/videos/index.ts
|
|
24562
|
-
import { defineCommand as
|
|
24392
|
+
import { defineCommand as defineCommand156 } from "citty";
|
|
24563
24393
|
|
|
24564
24394
|
// src/commands/videos/delete.ts
|
|
24565
|
-
import { defineCommand as
|
|
24395
|
+
import { defineCommand as defineCommand152 } from "citty";
|
|
24566
24396
|
registerSchema({
|
|
24567
24397
|
command: "videos.delete",
|
|
24568
24398
|
description: "Delete a video by ID",
|
|
@@ -24576,7 +24406,7 @@ registerSchema({
|
|
|
24576
24406
|
}
|
|
24577
24407
|
}
|
|
24578
24408
|
});
|
|
24579
|
-
var deleteCommand3 =
|
|
24409
|
+
var deleteCommand3 = defineCommand152({
|
|
24580
24410
|
meta: {
|
|
24581
24411
|
name: "delete",
|
|
24582
24412
|
description: "Delete a video by ID. Use --dry-run to preview. Example: baker videos delete j571abc123 --dry-run"
|
|
@@ -24617,7 +24447,7 @@ var deleteCommand3 = defineCommand153({
|
|
|
24617
24447
|
});
|
|
24618
24448
|
|
|
24619
24449
|
// src/commands/videos/get.ts
|
|
24620
|
-
import { defineCommand as
|
|
24450
|
+
import { defineCommand as defineCommand153 } from "citty";
|
|
24621
24451
|
registerSchema({
|
|
24622
24452
|
command: "videos.get",
|
|
24623
24453
|
description: "Get a single video by ID",
|
|
@@ -24625,7 +24455,7 @@ registerSchema({
|
|
|
24625
24455
|
id: { type: "string", description: "Video ID", required: true }
|
|
24626
24456
|
}
|
|
24627
24457
|
});
|
|
24628
|
-
var getCommand5 =
|
|
24458
|
+
var getCommand5 = defineCommand153({
|
|
24629
24459
|
meta: { name: "get", description: "Get a single video by ID. Example: baker videos get j571abc123" },
|
|
24630
24460
|
args: {
|
|
24631
24461
|
id: { type: "positional", description: "Video ID", required: false },
|
|
@@ -24662,7 +24492,7 @@ var getCommand5 = defineCommand154({
|
|
|
24662
24492
|
});
|
|
24663
24493
|
|
|
24664
24494
|
// src/commands/videos/search.ts
|
|
24665
|
-
import { defineCommand as
|
|
24495
|
+
import { defineCommand as defineCommand154 } from "citty";
|
|
24666
24496
|
registerSchema({
|
|
24667
24497
|
command: "videos.search",
|
|
24668
24498
|
description: "Search videos by text query. Only returns ready videos.",
|
|
@@ -24672,7 +24502,7 @@ registerSchema({
|
|
|
24672
24502
|
tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
|
|
24673
24503
|
}
|
|
24674
24504
|
});
|
|
24675
|
-
var searchCommand3 =
|
|
24505
|
+
var searchCommand3 = defineCommand154({
|
|
24676
24506
|
meta: {
|
|
24677
24507
|
name: "search",
|
|
24678
24508
|
description: "Semantic search videos by text query. Uses hybrid BM25 + vector + reranking. Example: baker videos search 'product demo' --tags tutorial"
|
|
@@ -24719,12 +24549,12 @@ var searchCommand3 = defineCommand155({
|
|
|
24719
24549
|
});
|
|
24720
24550
|
|
|
24721
24551
|
// src/commands/videos/tags.ts
|
|
24722
|
-
var
|
|
24552
|
+
var tagsCommand4 = makeTagsCommand("videos", "video", "/api/videos/tags");
|
|
24723
24553
|
|
|
24724
24554
|
// src/commands/videos/upload.ts
|
|
24725
24555
|
import { readFile as readFile12, stat as stat3 } from "fs/promises";
|
|
24726
24556
|
import { extname as extname3 } from "path";
|
|
24727
|
-
import { defineCommand as
|
|
24557
|
+
import { defineCommand as defineCommand155 } from "citty";
|
|
24728
24558
|
var MIME_MAP = {
|
|
24729
24559
|
".mp4": "video/mp4",
|
|
24730
24560
|
".mov": "video/quicktime",
|
|
@@ -24758,7 +24588,7 @@ function detectContentType(filePath) {
|
|
|
24758
24588
|
}
|
|
24759
24589
|
return mime;
|
|
24760
24590
|
}
|
|
24761
|
-
var uploadCommand2 =
|
|
24591
|
+
var uploadCommand2 = defineCommand155({
|
|
24762
24592
|
meta: {
|
|
24763
24593
|
name: "upload",
|
|
24764
24594
|
description: "Upload a video file to Baker via Mux direct upload. Auto-detects content type. Example: baker videos upload ./demo.mp4"
|
|
@@ -24812,7 +24642,7 @@ var uploadCommand2 = defineCommand156({
|
|
|
24812
24642
|
});
|
|
24813
24643
|
|
|
24814
24644
|
// src/commands/videos/index.ts
|
|
24815
|
-
var videosCommand =
|
|
24645
|
+
var videosCommand = defineCommand156({
|
|
24816
24646
|
meta: {
|
|
24817
24647
|
name: "videos",
|
|
24818
24648
|
description: `Find and manage videos in Baker. Subcommands: search, get, upload, delete, tags.
|
|
@@ -24830,15 +24660,15 @@ Examples:
|
|
|
24830
24660
|
search: searchCommand3,
|
|
24831
24661
|
upload: uploadCommand2,
|
|
24832
24662
|
delete: deleteCommand3,
|
|
24833
|
-
tags:
|
|
24663
|
+
tags: tagsCommand4
|
|
24834
24664
|
}
|
|
24835
24665
|
});
|
|
24836
24666
|
|
|
24837
24667
|
// src/commands/winning-ads/index.ts
|
|
24838
|
-
import { defineCommand as
|
|
24668
|
+
import { defineCommand as defineCommand159 } from "citty";
|
|
24839
24669
|
|
|
24840
24670
|
// src/commands/winning-ads/advertisers.ts
|
|
24841
|
-
import { defineCommand as
|
|
24671
|
+
import { defineCommand as defineCommand157 } from "citty";
|
|
24842
24672
|
registerSchema({
|
|
24843
24673
|
command: "winning-ads.advertisers",
|
|
24844
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).",
|
|
@@ -24851,7 +24681,7 @@ registerSchema({
|
|
|
24851
24681
|
function identity(record) {
|
|
24852
24682
|
return record;
|
|
24853
24683
|
}
|
|
24854
|
-
var advertisersCommand2 =
|
|
24684
|
+
var advertisersCommand2 = defineCommand157({
|
|
24855
24685
|
meta: {
|
|
24856
24686
|
name: "advertisers",
|
|
24857
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'
|
|
@@ -24902,7 +24732,7 @@ var advertisersCommand2 = defineCommand158({
|
|
|
24902
24732
|
});
|
|
24903
24733
|
|
|
24904
24734
|
// src/commands/winning-ads/search.ts
|
|
24905
|
-
import { defineCommand as
|
|
24735
|
+
import { defineCommand as defineCommand158 } from "citty";
|
|
24906
24736
|
registerSchema({
|
|
24907
24737
|
command: "winning-ads.search",
|
|
24908
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.",
|
|
@@ -25010,7 +24840,7 @@ function buildSearchBody(args) {
|
|
|
25010
24840
|
}
|
|
25011
24841
|
return body;
|
|
25012
24842
|
}
|
|
25013
|
-
var searchCommand4 =
|
|
24843
|
+
var searchCommand4 = defineCommand158({
|
|
25014
24844
|
meta: {
|
|
25015
24845
|
name: "search",
|
|
25016
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"
|
|
@@ -25122,7 +24952,7 @@ var searchCommand4 = defineCommand159({
|
|
|
25122
24952
|
});
|
|
25123
24953
|
|
|
25124
24954
|
// src/commands/winning-ads/index.ts
|
|
25125
|
-
var winningAdsCommand =
|
|
24955
|
+
var winningAdsCommand = defineCommand159({
|
|
25126
24956
|
meta: {
|
|
25127
24957
|
name: "winning-ads",
|
|
25128
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.
|
|
@@ -25162,11 +24992,11 @@ function getCliVersion() {
|
|
|
25162
24992
|
}
|
|
25163
24993
|
|
|
25164
24994
|
// src/cli.ts
|
|
25165
|
-
var main =
|
|
24995
|
+
var main = defineCommand160({
|
|
25166
24996
|
meta: {
|
|
25167
24997
|
name: "baker",
|
|
25168
24998
|
version: getCliVersion(),
|
|
25169
|
-
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.
|
|
25170
25000
|
|
|
25171
25001
|
Auth: Set BAKER_API_KEY (starts with bk_) and BAKER_API_URL environment variables.
|
|
25172
25002
|
Chat: Set BAKER_CHAT_ID for action and scheduled-action commands that stage changes against a chat.
|
|
@@ -25186,7 +25016,6 @@ Introspection: Run 'baker schema <command>' to inspect argument schemas.`
|
|
|
25186
25016
|
videos: videosCommand,
|
|
25187
25017
|
testimonials: testimonialsCommand,
|
|
25188
25018
|
canvas: canvasCommand,
|
|
25189
|
-
tags: tagsCommand3,
|
|
25190
25019
|
"winning-ads": winningAdsCommand,
|
|
25191
25020
|
mcp: mcpCommand,
|
|
25192
25021
|
schema: schemaCommand
|