@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.
- package/SKILL.md +6 -2
- package/dist/cli.cjs +54 -15
- 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).
|
|
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
|
|
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.
|
|
4728
|
-
if (ad.creative.
|
|
4729
|
-
if (ad.creative.
|
|
4730
|
-
if (ad.creative.
|
|
4731
|
-
if (ad.creative.
|
|
4732
|
-
if (ad.creative.
|
|
4733
|
-
if (ad.creative.
|
|
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
|
-
|
|
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(
|
|
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.
|
|
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": "
|
|
33
|
+
"build": "node build.cjs",
|
|
34
34
|
"dev": "node src/cli.js",
|
|
35
35
|
"link": "npm link"
|
|
36
36
|
},
|