@koda-sl/baker-cli 0.334.0 → 0.336.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -1887,7 +1887,78 @@ var audienceCreateSchema = z3.object({
1887
1887
  message: `${p.audienceType} audiences need a raw source config (use --file)`
1888
1888
  });
1889
1889
  }
1890
- });
1890
+ if (!isList && p.raw) {
1891
+ for (const message of retargetingConfigProblems(p.raw)) {
1892
+ ctx.addIssue({ code: "custom", path: ["raw"], message: `${p.audienceType} source config: ${message}` });
1893
+ }
1894
+ }
1895
+ });
1896
+ var ENGAGEMENT_LOOKBACK_DAYS = [7, 14, 28, 30, 60, 90, 180, 365];
1897
+ var WEBSITE_LOOKBACK_DAYS = ENGAGEMENT_LOOKBACK_DAYS.filter((days) => days >= 14 && days <= 180);
1898
+ var EVENT_LOOKBACK_DAYS = [730];
1899
+ var WEBSITE_SOURCE_PLATFORM = "LINKEDIN_WEBSITE_RETARGETING";
1900
+ var TRIGGER_SOURCE_TYPE_BY_PLATFORM = { [WEBSITE_SOURCE_PLATFORM]: "WEBSITE" };
1901
+ function lookbackDaysFor(sourcePlatform) {
1902
+ if (sourcePlatform === WEBSITE_SOURCE_PLATFORM) {
1903
+ return WEBSITE_LOOKBACK_DAYS;
1904
+ }
1905
+ return sourcePlatform === "EVENT_PAGES" ? EVENT_LOOKBACK_DAYS : ENGAGEMENT_LOOKBACK_DAYS;
1906
+ }
1907
+ var ENGAGEMENT_TRIGGER_URN = /^urn:li:dmpEngagementTrigger:\(urn:li:dmpEngagementSourceType:([A-Z_]+),([A-Z_]+)\)$/;
1908
+ var RETARGETING_EXAMPLE = '{"sourcePlatform":"VIDEO_ADS","type":"USER","engagementRules":[{"engagementSource":"urn:li:sponsoredCampaign:123","engagementTrigger":"urn:li:dmpEngagementTrigger:(urn:li:dmpEngagementSourceType:VIDEO_ADS,FIRST_QUARTILE)","timeFrame":{"timeSpan":{"duration":90,"unit":"DAY"}}}]}';
1909
+ var engagementRuleSchema = z3.object({
1910
+ engagementSource: z3.string().regex(/^urn:li:[A-Za-z]+:\S+$/, "engagementSource must be a URN (urn:li:\u2026)"),
1911
+ engagementTrigger: z3.string().regex(
1912
+ ENGAGEMENT_TRIGGER_URN,
1913
+ "engagementTrigger must be urn:li:dmpEngagementTrigger:(urn:li:dmpEngagementSourceType:<SOURCE>,<TRIGGER>)"
1914
+ ),
1915
+ timeFrame: z3.object({
1916
+ timeSpan: z3.object({ duration: z3.number().int().positive(), unit: z3.literal("DAY") })
1917
+ })
1918
+ }).passthrough();
1919
+ var engagementRulesSchema = z3.array(engagementRuleSchema).min(1);
1920
+ function retargetingConfigProblems(raw) {
1921
+ const problems = [];
1922
+ const sourcePlatform = typeof raw.sourcePlatform === "string" ? raw.sourcePlatform.trim() : "";
1923
+ if (!sourcePlatform) {
1924
+ problems.push("missing sourcePlatform");
1925
+ }
1926
+ if (raw.type !== "USER") {
1927
+ problems.push('type must be "USER" \u2014 LinkedIn only attaches engagement rules to USER segments');
1928
+ }
1929
+ const rules = engagementRulesSchema.safeParse(raw.engagementRules);
1930
+ if (!rules.success) {
1931
+ const detail = rules.error.issues.map((issue) => issue.message).join("; ");
1932
+ problems.push(
1933
+ `engagementRules needs at least one source rule (engagementSource, engagementTrigger, timeFrame) \u2014 ${detail}. e.g. ${RETARGETING_EXAMPLE}`
1934
+ );
1935
+ return problems;
1936
+ }
1937
+ const allowed = lookbackDaysFor(sourcePlatform);
1938
+ const expectedTriggerSource = TRIGGER_SOURCE_TYPE_BY_PLATFORM[sourcePlatform] ?? sourcePlatform;
1939
+ for (const rule of rules.data) {
1940
+ const triggerSource = ENGAGEMENT_TRIGGER_URN.exec(rule.engagementTrigger)?.[1];
1941
+ if (sourcePlatform && triggerSource !== expectedTriggerSource) {
1942
+ problems.push(
1943
+ `engagementTrigger ${rule.engagementTrigger} is a ${triggerSource} trigger, not ${expectedTriggerSource}`
1944
+ );
1945
+ }
1946
+ const days = rule.timeFrame.timeSpan.duration;
1947
+ if (!allowed.includes(days)) {
1948
+ problems.push(`lookback ${days} days is not offered for ${sourcePlatform} \u2014 use ${allowed.join(", ")}`);
1949
+ }
1950
+ }
1951
+ const shapes = new Set(rules.data.map((rule) => `${rule.engagementTrigger}|${rule.timeFrame.timeSpan.duration}`));
1952
+ if (shapes.size > 1) {
1953
+ problems.push("every engagement rule on one audience must use the same trigger and lookback");
1954
+ }
1955
+ const sources = rules.data.map((rule) => rule.engagementSource);
1956
+ const repeated = [...new Set(sources.filter((source, index) => sources.indexOf(source) !== index))];
1957
+ if (repeated.length > 0) {
1958
+ problems.push(`each engagementSource can appear in only one rule: ${repeated.join(", ")}`);
1959
+ }
1960
+ return problems;
1961
+ }
1891
1962
  var audienceUploadListSchema = z3.object({
1892
1963
  segment: parentRefSchema,
1893
1964
  listColumns: z3.array(z3.string().min(1)).optional(),
@@ -3083,12 +3154,12 @@ var budgetCreateSchema = z5.object({
3083
3154
  deliveryMethod: z5.enum(BUDGET_DELIVERY_METHODS).default("STANDARD"),
3084
3155
  explicitlyShared: z5.boolean().default(false)
3085
3156
  });
3086
- var budgetUpdateSchema = z5.object({
3157
+ var budgetUpdateSchema = z5.strictObject({
3087
3158
  name: z5.string().min(1).max(GOOGLE_ADS_LIMITS.budget.nameMax).optional(),
3088
3159
  amountMicros: microsSchema.optional(),
3089
3160
  deliveryMethod: z5.enum(BUDGET_DELIVERY_METHODS).optional()
3090
3161
  }).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
3091
- var biddingConfigSchema = z5.object({
3162
+ var biddingConfigSchema = z5.strictObject({
3092
3163
  type: z5.enum(BIDDING_STRATEGY_TYPES),
3093
3164
  targetCpaMicros: microsSchema.optional(),
3094
3165
  targetRoas: z5.number().positive().optional(),
@@ -3222,7 +3293,7 @@ var keywordAddSchema = z5.object({
3222
3293
  finalUrls: z5.array(httpsUrlSchema2).optional(),
3223
3294
  status: stageableStatusSchema2.default("ENABLED")
3224
3295
  });
3225
- var keywordUpdateSchema = z5.object({
3296
+ var keywordUpdateSchema = z5.strictObject({
3226
3297
  cpcBidMicros: microsSchema.optional(),
3227
3298
  finalUrls: z5.array(httpsUrlSchema2).optional(),
3228
3299
  status: z5.enum(["ENABLED", "PAUSED", "REMOVED"]).optional()
@@ -3246,7 +3317,7 @@ var campaignSharedSetAttachSchema = z5.object({
3246
3317
  campaign: refSchema,
3247
3318
  sharedSet: refSchema
3248
3319
  });
3249
- var adTextAssetSchema = z5.object({
3320
+ var adTextAssetSchema = z5.strictObject({
3250
3321
  text: z5.string().min(1),
3251
3322
  pinnedField: z5.enum(PINNED_FIELDS).optional()
3252
3323
  });
@@ -3270,9 +3341,11 @@ var responsiveSearchAdSchema = z5.strictObject({
3270
3341
  });
3271
3342
  var responsiveDisplayAdSchema = z5.strictObject({
3272
3343
  format: z5.literal("responsiveDisplay"),
3273
- headlines: z5.array(z5.object({ text: z5.string().min(1).max(GOOGLE_ADS_LIMITS.responsiveDisplayAd.headlineTextMax) })).min(1).max(5),
3274
- longHeadline: z5.object({ text: z5.string().min(1).max(GOOGLE_ADS_LIMITS.responsiveDisplayAd.longHeadlineTextMax) }),
3275
- descriptions: z5.array(z5.object({ text: z5.string().min(1).max(GOOGLE_ADS_LIMITS.responsiveDisplayAd.descriptionTextMax) })).min(1).max(5),
3344
+ headlines: z5.array(z5.strictObject({ text: z5.string().min(1).max(GOOGLE_ADS_LIMITS.responsiveDisplayAd.headlineTextMax) })).min(1).max(5),
3345
+ longHeadline: z5.strictObject({
3346
+ text: z5.string().min(1).max(GOOGLE_ADS_LIMITS.responsiveDisplayAd.longHeadlineTextMax)
3347
+ }),
3348
+ descriptions: z5.array(z5.strictObject({ text: z5.string().min(1).max(GOOGLE_ADS_LIMITS.responsiveDisplayAd.descriptionTextMax) })).min(1).max(5),
3276
3349
  businessName: z5.string().min(1).max(GOOGLE_ADS_LIMITS.responsiveDisplayAd.businessNameMax),
3277
3350
  // A Responsive Display Ad's images are fields on the ad's own content (never campaign-level
3278
3351
  // asset links). Google requires ≥1 landscape marketing image (1.91:1) AND ≥1 square marketing
@@ -3295,8 +3368,8 @@ var callAdSchema = z5.strictObject({
3295
3368
  });
3296
3369
  var appAdSchema = z5.strictObject({
3297
3370
  format: z5.literal("app"),
3298
- headlines: z5.array(z5.object({ text: z5.string().min(1).max(GOOGLE_ADS_LIMITS.appAd.headlineTextMax) })).min(GOOGLE_ADS_LIMITS.appAd.headlinesMin).max(GOOGLE_ADS_LIMITS.appAd.headlinesMax),
3299
- descriptions: z5.array(z5.object({ text: z5.string().min(1).max(GOOGLE_ADS_LIMITS.appAd.descriptionTextMax) })).min(GOOGLE_ADS_LIMITS.appAd.descriptionsMin).max(GOOGLE_ADS_LIMITS.appAd.descriptionsMax),
3371
+ headlines: z5.array(z5.strictObject({ text: z5.string().min(1).max(GOOGLE_ADS_LIMITS.appAd.headlineTextMax) })).min(GOOGLE_ADS_LIMITS.appAd.headlinesMin).max(GOOGLE_ADS_LIMITS.appAd.headlinesMax),
3372
+ descriptions: z5.array(z5.strictObject({ text: z5.string().min(1).max(GOOGLE_ADS_LIMITS.appAd.descriptionTextMax) })).min(GOOGLE_ADS_LIMITS.appAd.descriptionsMin).max(GOOGLE_ADS_LIMITS.appAd.descriptionsMax),
3300
3373
  // An App campaign ad carries its images on its own content (`AppAdInfo.images`), not as
3301
3374
  // campaign-level asset links — same shape as a responsive display ad's marketing images.
3302
3375
  images: z5.array(refSchema).max(GOOGLE_ADS_LIMITS.appAd.imagesMax).optional(),
@@ -3319,8 +3392,8 @@ var demandGenAdSchema = z5.strictObject({
3319
3392
  * account with no name was created, and reads back with none. Only the video format requires one.
3320
3393
  */
3321
3394
  name: z5.string().min(1).max(GOOGLE_ADS_LIMITS.demandGenAd.adNameMax).optional(),
3322
- headlines: z5.array(z5.object({ text: z5.string().min(1).max(GOOGLE_ADS_LIMITS.demandGenAd.headlineTextMax) })).min(GOOGLE_ADS_LIMITS.demandGenAd.headlinesMin).max(GOOGLE_ADS_LIMITS.demandGenAd.headlinesMax),
3323
- descriptions: z5.array(z5.object({ text: z5.string().min(1).max(GOOGLE_ADS_LIMITS.demandGenAd.descriptionTextMax) })).min(GOOGLE_ADS_LIMITS.demandGenAd.descriptionsMin).max(GOOGLE_ADS_LIMITS.demandGenAd.descriptionsMax),
3395
+ headlines: z5.array(z5.strictObject({ text: z5.string().min(1).max(GOOGLE_ADS_LIMITS.demandGenAd.headlineTextMax) })).min(GOOGLE_ADS_LIMITS.demandGenAd.headlinesMin).max(GOOGLE_ADS_LIMITS.demandGenAd.headlinesMax),
3396
+ descriptions: z5.array(z5.strictObject({ text: z5.string().min(1).max(GOOGLE_ADS_LIMITS.demandGenAd.descriptionTextMax) })).min(GOOGLE_ADS_LIMITS.demandGenAd.descriptionsMin).max(GOOGLE_ADS_LIMITS.demandGenAd.descriptionsMax),
3324
3397
  businessName: z5.string().min(1).max(GOOGLE_ADS_LIMITS.demandGenAd.businessNameMax),
3325
3398
  finalUrls: z5.array(httpsUrlSchema2).min(1),
3326
3399
  imageAssets: z5.array(refSchema).optional(),
@@ -3338,9 +3411,9 @@ var demandGenVideoAdSchema = z5.strictObject({
3338
3411
  * IMMUTABLE — an update must be able to restate the whole content without renaming the ad.
3339
3412
  */
3340
3413
  name: z5.string().min(1).max(GOOGLE_ADS_LIMITS.demandGenVideoAd.adNameMax).optional(),
3341
- headlines: z5.array(z5.object({ text: z5.string().min(1).max(GOOGLE_ADS_LIMITS.demandGenVideoAd.headlineTextMax) })).min(GOOGLE_ADS_LIMITS.demandGenVideoAd.headlinesMin).max(GOOGLE_ADS_LIMITS.demandGenVideoAd.headlinesMax),
3342
- longHeadlines: z5.array(z5.object({ text: z5.string().min(1).max(GOOGLE_ADS_LIMITS.demandGenVideoAd.longHeadlineTextMax) })).min(GOOGLE_ADS_LIMITS.demandGenVideoAd.longHeadlinesMin).max(GOOGLE_ADS_LIMITS.demandGenVideoAd.longHeadlinesMax),
3343
- descriptions: z5.array(z5.object({ text: z5.string().min(1).max(GOOGLE_ADS_LIMITS.demandGenVideoAd.descriptionTextMax) })).min(GOOGLE_ADS_LIMITS.demandGenVideoAd.descriptionsMin).max(GOOGLE_ADS_LIMITS.demandGenVideoAd.descriptionsMax),
3414
+ headlines: z5.array(z5.strictObject({ text: z5.string().min(1).max(GOOGLE_ADS_LIMITS.demandGenVideoAd.headlineTextMax) })).min(GOOGLE_ADS_LIMITS.demandGenVideoAd.headlinesMin).max(GOOGLE_ADS_LIMITS.demandGenVideoAd.headlinesMax),
3415
+ longHeadlines: z5.array(z5.strictObject({ text: z5.string().min(1).max(GOOGLE_ADS_LIMITS.demandGenVideoAd.longHeadlineTextMax) })).min(GOOGLE_ADS_LIMITS.demandGenVideoAd.longHeadlinesMin).max(GOOGLE_ADS_LIMITS.demandGenVideoAd.longHeadlinesMax),
3416
+ descriptions: z5.array(z5.strictObject({ text: z5.string().min(1).max(GOOGLE_ADS_LIMITS.demandGenVideoAd.descriptionTextMax) })).min(GOOGLE_ADS_LIMITS.demandGenVideoAd.descriptionsMin).max(GOOGLE_ADS_LIMITS.demandGenVideoAd.descriptionsMax),
3344
3417
  businessName: z5.string().min(1).max(GOOGLE_ADS_LIMITS.demandGenVideoAd.businessNameMax),
3345
3418
  finalUrls: z5.array(httpsUrlSchema2).min(1),
3346
3419
  videoAssets: z5.array(refSchema).optional(),
@@ -3366,25 +3439,25 @@ var adUpdateSchema = z5.object({
3366
3439
  /** Whole-content replacement for RSA-like formats; re-validated against adContentSchema. */
3367
3440
  content: z5.record(z5.string(), z5.unknown()).optional()
3368
3441
  }).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
3369
- var textAssetSchema = z5.object({ type: z5.literal("text"), text: z5.string().min(1) });
3370
- var imageAssetSchema = z5.object({
3442
+ var textAssetSchema = z5.strictObject({ type: z5.literal("text"), text: z5.string().min(1) });
3443
+ var imageAssetSchema = z5.strictObject({
3371
3444
  type: z5.literal("image"),
3372
3445
  imageId: z5.string().min(1),
3373
3446
  name: z5.string().optional()
3374
3447
  });
3375
- var youtubeVideoAssetSchema = z5.object({
3448
+ var youtubeVideoAssetSchema = z5.strictObject({
3376
3449
  type: z5.literal("youtubeVideo"),
3377
3450
  youtubeVideoId: z5.string().min(1),
3378
3451
  name: z5.string().optional()
3379
3452
  });
3380
- var sitelinkAssetSchema = z5.object({
3453
+ var sitelinkAssetSchema = z5.strictObject({
3381
3454
  type: z5.literal("sitelink"),
3382
3455
  linkText: z5.string().min(1).max(GOOGLE_ADS_LIMITS.asset.sitelinkLinkTextMax),
3383
3456
  description1: z5.string().max(GOOGLE_ADS_LIMITS.asset.sitelinkDescriptionMax).optional(),
3384
3457
  description2: z5.string().max(GOOGLE_ADS_LIMITS.asset.sitelinkDescriptionMax).optional(),
3385
3458
  finalUrls: z5.array(httpsUrlSchema2).min(1)
3386
3459
  });
3387
- var calloutAssetSchema = z5.object({
3460
+ var calloutAssetSchema = z5.strictObject({
3388
3461
  type: z5.literal("callout"),
3389
3462
  calloutText: z5.string().min(1).max(GOOGLE_ADS_LIMITS.asset.calloutTextMax)
3390
3463
  });
@@ -3399,12 +3472,12 @@ var structuredSnippetHeaderSchema = z5.string().min(1).transform((header, ctx) =
3399
3472
  }
3400
3473
  return canonical2;
3401
3474
  });
3402
- var structuredSnippetAssetSchema = z5.object({
3475
+ var structuredSnippetAssetSchema = z5.strictObject({
3403
3476
  type: z5.literal("structuredSnippet"),
3404
3477
  header: structuredSnippetHeaderSchema,
3405
3478
  values: z5.array(z5.string().min(1).max(GOOGLE_ADS_LIMITS.asset.structuredSnippetValueMax)).min(GOOGLE_ADS_LIMITS.asset.structuredSnippetValuesMin).max(GOOGLE_ADS_LIMITS.asset.structuredSnippetValuesMax)
3406
3479
  });
3407
- var callToActionAssetSchema = z5.object({ type: z5.literal("callToAction"), callToAction: z5.string().min(1) });
3480
+ var callToActionAssetSchema = z5.strictObject({ type: z5.literal("callToAction"), callToAction: z5.string().min(1) });
3408
3481
  var assetCreateSchema = z5.discriminatedUnion("type", [
3409
3482
  textAssetSchema,
3410
3483
  imageAssetSchema,
@@ -3414,7 +3487,7 @@ var assetCreateSchema = z5.discriminatedUnion("type", [
3414
3487
  structuredSnippetAssetSchema,
3415
3488
  callToActionAssetSchema
3416
3489
  ]);
3417
- var assetUpdateSchema = z5.object({
3490
+ var assetUpdateSchema = z5.strictObject({
3418
3491
  name: z5.string().min(1).optional(),
3419
3492
  linkText: z5.string().min(1).max(GOOGLE_ADS_LIMITS.asset.sitelinkLinkTextMax).optional(),
3420
3493
  description1: z5.string().max(GOOGLE_ADS_LIMITS.asset.sitelinkDescriptionMax).optional(),
@@ -3458,9 +3531,9 @@ var assetGroupCreateSchema = z5.object({
3458
3531
  campaign: refSchema,
3459
3532
  name: z5.string().min(1).max(GOOGLE_ADS_LIMITS.assetGroup.nameMax),
3460
3533
  finalUrls: z5.array(httpsUrlSchema2).min(1),
3461
- headlines: z5.array(z5.object({ text: z5.string().min(1).max(GOOGLE_ADS_LIMITS.assetGroup.headlineTextMax) })).min(GOOGLE_ADS_LIMITS.assetGroup.headlinesMin).max(GOOGLE_ADS_LIMITS.assetGroup.headlinesMax),
3462
- longHeadlines: z5.array(z5.object({ text: z5.string().min(1).max(GOOGLE_ADS_LIMITS.assetGroup.longHeadlineTextMax) })).min(GOOGLE_ADS_LIMITS.assetGroup.longHeadlinesMin).max(GOOGLE_ADS_LIMITS.assetGroup.longHeadlinesMax),
3463
- descriptions: z5.array(z5.object({ text: z5.string().min(1).max(GOOGLE_ADS_LIMITS.assetGroup.descriptionTextMax) })).min(GOOGLE_ADS_LIMITS.assetGroup.descriptionsMin).max(GOOGLE_ADS_LIMITS.assetGroup.descriptionsMax),
3534
+ headlines: z5.array(z5.strictObject({ text: z5.string().min(1).max(GOOGLE_ADS_LIMITS.assetGroup.headlineTextMax) })).min(GOOGLE_ADS_LIMITS.assetGroup.headlinesMin).max(GOOGLE_ADS_LIMITS.assetGroup.headlinesMax),
3535
+ longHeadlines: z5.array(z5.strictObject({ text: z5.string().min(1).max(GOOGLE_ADS_LIMITS.assetGroup.longHeadlineTextMax) })).min(GOOGLE_ADS_LIMITS.assetGroup.longHeadlinesMin).max(GOOGLE_ADS_LIMITS.assetGroup.longHeadlinesMax),
3536
+ descriptions: z5.array(z5.strictObject({ text: z5.string().min(1).max(GOOGLE_ADS_LIMITS.assetGroup.descriptionTextMax) })).min(GOOGLE_ADS_LIMITS.assetGroup.descriptionsMin).max(GOOGLE_ADS_LIMITS.assetGroup.descriptionsMax),
3464
3537
  businessName: z5.string().min(1).max(GOOGLE_ADS_LIMITS.assetGroup.businessNameMax),
3465
3538
  imageAssets: z5.array(refSchema).optional(),
3466
3539
  squareImageAssets: z5.array(refSchema).optional(),
@@ -3473,7 +3546,7 @@ var assetGroupAssetAttachSchema = z5.object({
3473
3546
  asset: refSchema,
3474
3547
  fieldType: z5.enum(ASSET_GROUP_ASSET_FIELD_TYPES)
3475
3548
  });
3476
- var assetGroupUpdateSchema = z5.object({
3549
+ var assetGroupUpdateSchema = z5.strictObject({
3477
3550
  name: z5.string().min(1).max(GOOGLE_ADS_LIMITS.assetGroup.nameMax).optional(),
3478
3551
  finalUrls: z5.array(httpsUrlSchema2).min(1).optional(),
3479
3552
  status: z5.enum(["ENABLED", "PAUSED", "REMOVED"]).optional()
@@ -3524,7 +3597,7 @@ var conversionActionCreateSchema = z5.object({
3524
3597
  primaryForGoal: z5.boolean().optional()
3525
3598
  });
3526
3599
  var HIDDEN_CONVERSION_STATUS_ERROR = 'Google rejects status HIDDEN on every conversion action write ("the field\'s value is on a deny-list"), so it is not part of this contract. To stop automated bidding optimizing toward a conversion while it keeps measuring, demote it instead: `baker ads google conversions update --target <id> --no-primary`. To stop it counting altogether, use `status: "REMOVED"`. Pick one of those and carry on with the rest of the job.';
3527
- var conversionActionUpdateSchema = z5.object({
3600
+ var conversionActionUpdateSchema = z5.strictObject({
3528
3601
  name: z5.string().min(1).max(GOOGLE_ADS_LIMITS.conversionAction.nameMax).optional(),
3529
3602
  category: z5.enum(CONVERSION_ACTION_CATEGORIES).optional(),
3530
3603
  countingType: z5.enum(CONVERSION_COUNTING_TYPES).optional(),
@@ -3568,7 +3641,7 @@ var biddingStrategyCreateSchema = z5.object({
3568
3641
  ctx.addIssue({ code: "custom", path: ["config", "type"], message: PORTFOLIO_TARGET_CPC_MESSAGE });
3569
3642
  }
3570
3643
  });
3571
- var biddingStrategyUpdateSchema = z5.object({
3644
+ var biddingStrategyUpdateSchema = z5.strictObject({
3572
3645
  name: z5.string().min(1).max(GOOGLE_ADS_LIMITS.biddingStrategy.nameMax).optional(),
3573
3646
  config: biddingConfigSchema.optional()
3574
3647
  }).superRefine((p, ctx) => {
@@ -3589,15 +3662,15 @@ var labelAttachSchema = z5.object({
3589
3662
  parent: refSchema,
3590
3663
  label: refSchema
3591
3664
  });
3592
- var locationCriterionSchema = z5.object({
3665
+ var locationCriterionSchema = z5.strictObject({
3593
3666
  criterionType: z5.literal("location"),
3594
3667
  geoTargetConstant: z5.union([z5.string().regex(GEO_TARGET_CONSTANT_REGEX), z5.string().regex(NUMERIC_ID_REGEX2)])
3595
3668
  });
3596
- var languageCriterionSchema = z5.object({
3669
+ var languageCriterionSchema = z5.strictObject({
3597
3670
  criterionType: z5.literal("language"),
3598
3671
  languageConstant: z5.union([z5.string().regex(LANGUAGE_CONSTANT_REGEX), z5.string().regex(NUMERIC_ID_REGEX2)])
3599
3672
  });
3600
- var adScheduleCriterionSchema = z5.object({
3673
+ var adScheduleCriterionSchema = z5.strictObject({
3601
3674
  criterionType: z5.literal("adSchedule"),
3602
3675
  dayOfWeek: z5.enum(DAYS_OF_WEEK),
3603
3676
  startHour: z5.number().int().min(0).max(23),
@@ -3608,7 +3681,7 @@ var adScheduleCriterionSchema = z5.object({
3608
3681
  var bidModifierSchema = z5.number().min(0).max(10).refine((v) => v === 0 || v >= 0.1, {
3609
3682
  message: "bid modifier must be 0 (exclude the device) or between 0.1 and 10.0"
3610
3683
  });
3611
- var deviceCriterionSchema = z5.object({
3684
+ var deviceCriterionSchema = z5.strictObject({
3612
3685
  criterionType: z5.literal("device"),
3613
3686
  device: z5.enum(DEVICE_TYPES),
3614
3687
  bidModifier: bidModifierSchema.optional()
@@ -3632,7 +3705,7 @@ var campaignCriterionAddSchema = z5.object({
3632
3705
  });
3633
3706
  }
3634
3707
  });
3635
- var campaignCriterionUpdateSchema = z5.object({
3708
+ var campaignCriterionUpdateSchema = z5.strictObject({
3636
3709
  bidModifier: bidModifierSchema
3637
3710
  });
3638
3711
  var GOOGLE_DRAFT_OP_KINDS = [
@@ -19937,7 +20010,11 @@ registerSchema({
19937
20010
  name: { type: "string", description: "Audience name (\u2264100 chars)", required: true },
19938
20011
  type: { type: "string", description: "company-list|user-list|retargeting|engagement", required: true },
19939
20012
  "list-file": { type: "string", description: "CSV file with the list rows", required: false },
19940
- file: { type: "string", description: "JSON raw source config for retargeting/engagement", required: false }
20013
+ file: {
20014
+ type: "string",
20015
+ description: "JSON raw source config for retargeting/engagement \u2014 sourcePlatform, type USER, and engagementRules (engagementSource, engagementTrigger, timeFrame)",
20016
+ required: false
20017
+ }
19941
20018
  }
19942
20019
  });
19943
20020
  registerSchema({
@@ -20689,7 +20766,10 @@ Example: baker ads linkedin audiences create --name "ABM Tier-1" --type company-
20689
20766
  name: { type: "string", description: "Audience name (\u2264100 chars)" },
20690
20767
  type: { type: "string", description: AUDIENCE_TYPES2.join("|") },
20691
20768
  "list-file": { type: "string", description: "CSV file with the list rows (header row required)" },
20692
- file: { type: "string", description: "JSON file with a raw source config (retargeting/engagement)" }
20769
+ file: {
20770
+ type: "string",
20771
+ description: 'JSON file with a raw source config (retargeting/engagement) \u2014 sourcePlatform, type USER and at least one engagementRules entry, e.g. {"sourcePlatform":"VIDEO_ADS","type":"USER","engagementRules":[{"engagementSource":"urn:li:sponsoredCampaign:123","engagementTrigger":"urn:li:dmpEngagementTrigger:(urn:li:dmpEngagementSourceType:VIDEO_ADS,FIRST_QUARTILE)","timeFrame":{"timeSpan":{"duration":90,"unit":"DAY"}}}]}'
20772
+ }
20693
20773
  },
20694
20774
  run: async ({ args: args5 }) => {
20695
20775
  const accountId = bareAccountId(args5);
@@ -22373,6 +22453,10 @@ function renderOutcome2(data, lines) {
22373
22453
  lines.push(`LinkedIn Ads \u2014 published \xB7 ${summary || `${data.count} op(s)`} \xB7 ${data.mode}`);
22374
22454
  for (const op of data.ops ?? []) {
22375
22455
  const status = op.result?.status;
22456
+ if (status === "applied" && op.result?.error) {
22457
+ lines.push(` \u26A0 ${op.summary} \u2014 applied in part: ${op.result.error}`);
22458
+ continue;
22459
+ }
22376
22460
  if (status !== "failed" && status !== "skipped") {
22377
22461
  continue;
22378
22462
  }