@adsuploader/cli 0.1.0 → 0.1.2

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.
Files changed (3) hide show
  1. package/SKILL.md +6 -2
  2. package/dist/cli.cjs +54 -15
  3. package/package.json +2 -2
package/SKILL.md CHANGED
@@ -228,14 +228,18 @@ When using `copyFromAd`, provide the upload batch and optionally campaign/ad set
228
228
 
229
229
  ### Budget / Bid Override
230
230
 
231
- Values in account currency units (e.g. `50` = $50). Only one at a time.
231
+ Values in account currency units (e.g. `50` = $50). `dailyBudget` and `bidAmount` are independent Meta fields.
232
+
233
+ - **ABO** (budget on the ad set): set `dailyBudget`, `bidAmount`, or both. Bid-cap strategies (`COST_CAP`, `LOWEST_COST_WITH_BID_CAP`, `TARGET_COST`) need `bidAmount` alongside the budget.
234
+ - **CBO** (budget on the campaign): don't set `dailyBudget` on the ad set — Meta rejects that since budget comes from the campaign. For bid-cap strategies, set only `bidAmount`.
232
235
 
233
236
  ```json
234
237
  { "adSet": { "dailyBudget": 50 } }
235
238
  { "adSet": { "bidAmount": 5 } }
239
+ { "adSet": { "dailyBudget": 50, "bidAmount": 5 } }
236
240
  ```
237
241
 
238
- Also available as CLI flags: `--daily-budget 50` or `--bid-amount 5`.
242
+ Also available as CLI flags: `--daily-budget 50`, `--bid-amount 5`, or both.
239
243
 
240
244
  ### Text Configuration
241
245
 
package/dist/cli.cjs CHANGED
@@ -4706,6 +4706,10 @@ function adsetCommand() {
4706
4706
 
4707
4707
  // src/commands/ad.js
4708
4708
  var import_picocolors7 = __toESM(require_picocolors(), 1);
4709
+ function truncate(str, max = 120) {
4710
+ if (!str || str.length <= max) return str;
4711
+ return str.slice(0, max) + "...";
4712
+ }
4709
4713
  function adCommand() {
4710
4714
  return new Command("ad").description("View ad details and creative").argument("<id>", "Ad ID").option("--account <id>", "Ad account ID").option("--json", "Output as JSON").action(async (id, opts) => {
4711
4715
  const client = createClient({ accountId: opts.account });
@@ -4722,15 +4726,20 @@ function adCommand() {
4722
4726
  console.log(` ${import_picocolors7.default.bold("Campaign:")} ${ad.campaignId}`);
4723
4727
  console.log(` ${import_picocolors7.default.bold("Ad Set:")} ${ad.adSetId}`);
4724
4728
  if (ad.creative) {
4729
+ const label = (name) => import_picocolors7.default.bold(name.padEnd(15));
4725
4730
  console.log("");
4726
4731
  console.log(` ${import_picocolors7.default.bold("Creative")}`);
4727
- if (ad.creative.title) console.log(` ${import_picocolors7.default.bold(" Title:")} ${ad.creative.title}`);
4728
- if (ad.creative.body) console.log(` ${import_picocolors7.default.bold(" Body:")} ${ad.creative.body}`);
4729
- if (ad.creative.linkUrl) console.log(` ${import_picocolors7.default.bold(" Link:")} ${ad.creative.linkUrl}`);
4730
- if (ad.creative.ctaType) console.log(` ${import_picocolors7.default.bold(" CTA:")} ${ad.creative.ctaType}`);
4731
- if (ad.creative.urlTags) console.log(` ${import_picocolors7.default.bold(" URL Tags:")} ${ad.creative.urlTags}`);
4732
- if (ad.creative.imageHash) console.log(` ${import_picocolors7.default.bold(" Image:")} ${import_picocolors7.default.dim(ad.creative.imageHash)}`);
4733
- if (ad.creative.videoId) console.log(` ${import_picocolors7.default.bold(" Video:")} ${import_picocolors7.default.dim(ad.creative.videoId)}`);
4732
+ if (ad.creative.headline) console.log(` ${label("Headline:")}${truncate(ad.creative.headline)}`);
4733
+ if (ad.creative.headlines) console.log(` ${label("Headlines:")}${ad.creative.headlines.map((h2) => truncate(h2, 60)).join(" | ")}`);
4734
+ if (ad.creative.primaryText) console.log(` ${label("Primary Text:")}${truncate(ad.creative.primaryText)}`);
4735
+ if (ad.creative.primaryTexts) console.log(` ${label("Primary Texts:")}${ad.creative.primaryTexts.map((t) => truncate(t, 60)).join(" | ")}`);
4736
+ if (ad.creative.description) console.log(` ${label("Description:")}${truncate(ad.creative.description)}`);
4737
+ if (ad.creative.descriptions) console.log(` ${label("Descriptions:")}${ad.creative.descriptions.map((d3) => truncate(d3, 60)).join(" | ")}`);
4738
+ if (ad.creative.cta) console.log(` ${label("CTA:")}${ad.creative.cta}`);
4739
+ if (ad.creative.link) console.log(` ${label("Link:")}${ad.creative.link}`);
4740
+ if (ad.creative.displayUrl) console.log(` ${label("Display URL:")}${ad.creative.displayUrl}`);
4741
+ if (ad.creative.urlTags) console.log(` ${label("URL Tags:")}${ad.creative.urlTags}`);
4742
+ if (ad.creative.enhancements) console.log(` ${label("Enhancements:")}${ad.creative.enhancements.join(", ")}`);
4734
4743
  }
4735
4744
  console.log(`
4736
4745
  ${import_picocolors7.default.dim("Use this ad as a template:")} ads create --copy-from ${ad.id}
@@ -5391,10 +5400,13 @@ async function executeCreate(body, opts, { preview = false, test = false } = {})
5391
5400
  else if (Array.isArray(enh)) enhDetail = enh.join(", ");
5392
5401
  if (enhDetail) console.log(` ${import_picocolors11.default.bold("Enhancements:")} ${wrapLine(enhDetail, valCol)}`);
5393
5402
  if (result.budget) {
5394
- const label = result.budget.type === "dailyBudget" ? "Daily Budget" : "Bid Amount";
5395
- const pad = " ".repeat(Math.max(1, 16 - label.length - 1));
5396
5403
  const curr = result.budget.currency ? ` ${result.budget.currency}` : "";
5397
- console.log(` ${import_picocolors11.default.bold(`${label}:`)}${pad}${result.budget.amount}${curr}`);
5404
+ const renderLine = (label, amount) => {
5405
+ const pad = " ".repeat(Math.max(1, 16 - label.length - 1));
5406
+ console.log(` ${import_picocolors11.default.bold(`${label}:`)}${pad}${amount}${curr}`);
5407
+ };
5408
+ if (result.budget.dailyBudget != null) renderLine("Daily Budget", result.budget.dailyBudget);
5409
+ if (result.budget.bidAmount != null) renderLine("Bid Amount", result.budget.bidAmount);
5398
5410
  }
5399
5411
  console.log("");
5400
5412
  } else if (result.plan?.totals) {
@@ -5461,10 +5473,6 @@ function buildBodyFromOpts(specFile, opts) {
5461
5473
  }
5462
5474
  }
5463
5475
  }
5464
- if (opts.dailyBudget != null && opts.bidAmount != null) {
5465
- printError("Cannot set both --daily-budget and --bid-amount. Use one or the other.");
5466
- process.exit(1);
5467
- }
5468
5476
  if (opts.dailyBudget != null) {
5469
5477
  const budget = parseFloat(opts.dailyBudget);
5470
5478
  if (isNaN(budget) || budget <= 0) {
@@ -5909,6 +5917,7 @@ function statusLabel(status) {
5909
5917
  }
5910
5918
 
5911
5919
  // src/cli.js
5920
+ var VERSION = true ? "0.1.2" : "0.0.0";
5912
5921
  var apiUrl = process.env.ADS_API_URL || getBaseUrl();
5913
5922
  if (apiUrl && (apiUrl.includes("localhost") || apiUrl.includes("127.0.0.1"))) {
5914
5923
  process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
@@ -5925,7 +5934,7 @@ var BANNER = [
5925
5934
  " " + import_picocolors13.default.dim("Create Meta ads from the command line"),
5926
5935
  ""
5927
5936
  ].join("\n");
5928
- var program2 = new Command().name("ads").description("Ads Uploader CLI").version("0.1.0").addHelpText("before", BANNER);
5937
+ var program2 = new Command().name("ads").description("Ads Uploader CLI").version(VERSION).addHelpText("before", BANNER);
5929
5938
  program2.addCommand(loginCommand());
5930
5939
  program2.addCommand(logoutCommand());
5931
5940
  program2.addCommand(whoamiCommand());
@@ -5946,6 +5955,35 @@ program2.addCommand(createInteractiveCommand());
5946
5955
  program2.addCommand(createPreviewCommand());
5947
5956
  program2.addCommand(createTestCommand(), { hidden: true });
5948
5957
  program2.addCommand(jobsCommand());
5958
+ async function checkForUpdates() {
5959
+ try {
5960
+ const fs4 = await import("fs");
5961
+ const path3 = await import("path");
5962
+ const os2 = await import("os");
5963
+ const cacheFile = path3.join(os2.default.homedir(), ".config", "adsuploader", ".update-check");
5964
+ try {
5965
+ const stat = fs4.default.statSync(cacheFile);
5966
+ if (Date.now() - stat.mtimeMs < 24 * 60 * 60 * 1e3) return;
5967
+ } catch {
5968
+ }
5969
+ const resp = await fetch("https://registry.npmjs.org/@adsuploader/cli/latest", { signal: AbortSignal.timeout(3e3) });
5970
+ if (!resp.ok) return;
5971
+ const data = await resp.json();
5972
+ const latest = data.version;
5973
+ try {
5974
+ fs4.default.mkdirSync(path3.dirname(cacheFile), { recursive: true });
5975
+ fs4.default.writeFileSync(cacheFile, latest);
5976
+ } catch {
5977
+ }
5978
+ if (latest !== VERSION) {
5979
+ console.error(`
5980
+ ${import_picocolors13.default.yellow("Update available:")} ${import_picocolors13.default.dim(VERSION)} \u2192 ${import_picocolors13.default.green(latest)}`);
5981
+ console.error(` Run ${import_picocolors13.default.cyan("npm update -g @adsuploader/cli")} to update
5982
+ `);
5983
+ }
5984
+ } catch {
5985
+ }
5986
+ }
5949
5987
  program2.exitOverride();
5950
5988
  if (process.argv.length <= 2) {
5951
5989
  program2.outputHelp();
@@ -5954,6 +5992,7 @@ if (process.argv.length <= 2) {
5954
5992
  (async () => {
5955
5993
  try {
5956
5994
  await program2.parseAsync(process.argv);
5995
+ await checkForUpdates();
5957
5996
  } catch (err) {
5958
5997
  if (err.code === "commander.helpDisplayed" || err.code === "commander.help" || err.code === "commander.version") {
5959
5998
  process.exit(0);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adsuploader/cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Create Facebook ads from the command line — bulk upload media, preview configurations, and launch ads at scale",
5
5
  "author": "Ads Uploader <support@adsuploader.com> (https://adsuploader.com)",
6
6
  "license": "UNLICENSED",
@@ -30,7 +30,7 @@
30
30
  "node": ">=18"
31
31
  },
32
32
  "scripts": {
33
- "build": "esbuild src/cli.js --bundle --platform=node --format=cjs --outfile=dist/cli.cjs --banner:js='#!/usr/bin/env node' --external:open",
33
+ "build": "node build.cjs",
34
34
  "dev": "node src/cli.js",
35
35
  "link": "npm link"
36
36
  },