@adkit.so/cli 1.0.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-utils.d.ts +11 -0
- package/dist/cli-utils.js +58 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +841 -0
- package/dist/client.d.ts +13 -0
- package/dist/client.js +84 -0
- package/dist/commands/auth.d.ts +7 -0
- package/dist/commands/auth.js +184 -0
- package/dist/commands/drafts.d.ts +6 -0
- package/dist/commands/drafts.js +36 -0
- package/dist/commands/meta.d.ts +28 -0
- package/dist/commands/meta.js +534 -0
- package/dist/commands/projects.d.ts +25 -0
- package/dist/commands/projects.js +30 -0
- package/dist/commands/status.d.ts +2 -0
- package/dist/commands/status.js +36 -0
- package/dist/config.d.ts +24 -0
- package/dist/config.js +70 -0
- package/dist/errors.d.ts +6 -0
- package/dist/errors.js +9 -0
- package/dist/output.d.ts +6 -0
- package/dist/output.js +48 -0
- package/package.json +20 -0
package/dist/cli.js
ADDED
|
@@ -0,0 +1,841 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { resolveConfig, readConfig } from './config.js';
|
|
3
|
+
import { AdkitClient } from './client.js';
|
|
4
|
+
import { formatOutput } from './output.js';
|
|
5
|
+
import { login, logout } from './commands/auth.js';
|
|
6
|
+
import { listProjects, useProject, currentProject } from './commands/projects.js';
|
|
7
|
+
import { listAccounts, connectAccount, disconnectAccount, listPages, listPixels, listCampaigns, createCampaign, updateCampaign, deleteCampaign, listAdSets, createAdSet, updateAdSet, deleteAdSet, listAds, createAd, updateAd, deleteAd, createCreative, updateCreative, deleteCreative, uploadMedia, listMedia, deleteMedia, searchInterests } from './commands/meta.js';
|
|
8
|
+
import { status } from './commands/status.js';
|
|
9
|
+
import { listDrafts, getDraft, publishDraft, deleteDraft } from './commands/drafts.js';
|
|
10
|
+
import { parseArgs, unwrapList } from './cli-utils.js';
|
|
11
|
+
import { CliError } from './errors.js';
|
|
12
|
+
const DEFAULT_BASE_URL = 'https://app.adkit.so/api/v1';
|
|
13
|
+
const USAGE = `
|
|
14
|
+
Usage: adkit <command> [options]
|
|
15
|
+
|
|
16
|
+
Commands:
|
|
17
|
+
status Show project context and connected accounts
|
|
18
|
+
setup [area...] Set up AdKit (opens browser)
|
|
19
|
+
manage <platform> <entity> <action> Manage ad platforms (meta, google, etc.)
|
|
20
|
+
manage drafts <action> Manage drafts (list, get, publish, delete)
|
|
21
|
+
projects <action> Manage projects (list, use, current)
|
|
22
|
+
|
|
23
|
+
Advanced:
|
|
24
|
+
logout Remove stored API key
|
|
25
|
+
|
|
26
|
+
Global flags:
|
|
27
|
+
--json Force JSON output (default when not a TTY)
|
|
28
|
+
--project <id> Use a specific project (overrides default)
|
|
29
|
+
--fields <list> Comma-separated fields to show (for list commands)
|
|
30
|
+
--help Show help (--help full = complete field reference, but more verbose)
|
|
31
|
+
|
|
32
|
+
Run \`adkit <command> --help\` for details.
|
|
33
|
+
`.trim();
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
// Shared flag descriptions (DRY building blocks for help text)
|
|
36
|
+
// ---------------------------------------------------------------------------
|
|
37
|
+
const FLAG = {
|
|
38
|
+
account: ' --account <id> Ad account ID (auto-resolved if only one)',
|
|
39
|
+
publish: ' --publish Publish immediately (default: draft)',
|
|
40
|
+
overrides: ' --platform-overrides <json> Raw Meta API fields merged onto payload',
|
|
41
|
+
data: ' --data <json> Full JSON body — bypasses named flags',
|
|
42
|
+
status: ' --status <s> active, paused, archived',
|
|
43
|
+
budgetDaily: ' --budget-daily <n> Daily budget in account currency',
|
|
44
|
+
cta: ' --cta <type> sign_up, learn_more, shop_now, download, get_offer, contact_us, subscribe, get_quote, book_now, apply_now',
|
|
45
|
+
};
|
|
46
|
+
// ---------------------------------------------------------------------------
|
|
47
|
+
// Entity-specific help text
|
|
48
|
+
// ---------------------------------------------------------------------------
|
|
49
|
+
// --- Campaigns ---
|
|
50
|
+
const CAMPAIGN_HELP = `adkit manage meta campaigns — Meta ad campaigns
|
|
51
|
+
|
|
52
|
+
list List campaigns
|
|
53
|
+
create Create a campaign
|
|
54
|
+
update <id> Update a campaign
|
|
55
|
+
delete <id> Delete a campaign
|
|
56
|
+
|
|
57
|
+
Flags (create/update):
|
|
58
|
+
--name <name> Campaign name (required for create)
|
|
59
|
+
--objective <type> traffic, awareness, engagement, leads, sales, app_promotion
|
|
60
|
+
${FLAG.status}
|
|
61
|
+
${FLAG.budgetDaily}
|
|
62
|
+
|
|
63
|
+
Examples:
|
|
64
|
+
adkit manage meta campaigns create --name "Spring Sale" --objective sales --budget-daily 50 --publish
|
|
65
|
+
adkit manage meta campaigns update cmp_abc --status paused
|
|
66
|
+
adkit manage meta campaigns delete cmp_abc
|
|
67
|
+
|
|
68
|
+
Run --help full for all fields and advanced options.`;
|
|
69
|
+
const CAMPAIGN_HELP_FULL = `adkit manage meta campaigns — Meta ad campaigns
|
|
70
|
+
|
|
71
|
+
list List campaigns
|
|
72
|
+
create Create a campaign
|
|
73
|
+
update <id> Update a campaign
|
|
74
|
+
delete <id> Delete a campaign
|
|
75
|
+
|
|
76
|
+
Flags (create/update):
|
|
77
|
+
--name <name> Campaign name (required for create)
|
|
78
|
+
--objective <type> traffic, awareness, engagement, leads, sales, app_promotion
|
|
79
|
+
${FLAG.status}
|
|
80
|
+
${FLAG.budgetDaily}
|
|
81
|
+
|
|
82
|
+
Advanced flags:
|
|
83
|
+
--bid-strategy <s> lowest_cost (default), cost_cap, bid_cap, min_roas
|
|
84
|
+
--abo Adset budget optimization (disables campaign-level budget)
|
|
85
|
+
|
|
86
|
+
--data JSON fields:
|
|
87
|
+
budget.lifetime (number) Lifetime budget in account currency
|
|
88
|
+
spendCap (number) Total spend cap
|
|
89
|
+
specialAdCategories (string[]) credit, housing, employment, social_issues
|
|
90
|
+
startDate (string) ISO date, e.g. "2026-04-01T00:00:00+0000"
|
|
91
|
+
endDate (string|null) ISO date or null for no end
|
|
92
|
+
|
|
93
|
+
Examples:
|
|
94
|
+
adkit manage meta campaigns list --account act_123456789
|
|
95
|
+
adkit manage meta campaigns create --name "Spring Sale" --objective sales --budget-daily 50 --publish
|
|
96
|
+
adkit manage meta campaigns update cmp_abc --status paused
|
|
97
|
+
adkit manage meta campaigns update cmp_abc --budget-daily 100
|
|
98
|
+
adkit manage meta campaigns delete cmp_abc
|
|
99
|
+
adkit manage meta campaigns create --data '{
|
|
100
|
+
"name":"Housing Leads","objective":"leads",
|
|
101
|
+
"budget":{"lifetime":500},"specialAdCategories":["housing"],
|
|
102
|
+
"startDate":"2026-04-01T00:00:00+0000","endDate":"2026-04-30T23:59:59+0000"
|
|
103
|
+
}' --publish`;
|
|
104
|
+
// --- Ad Sets ---
|
|
105
|
+
const ADSET_HELP = `adkit manage meta adsets — Meta ad sets
|
|
106
|
+
|
|
107
|
+
list List ad sets
|
|
108
|
+
create Create an ad set
|
|
109
|
+
update <id> Update an ad set
|
|
110
|
+
delete <id> Delete an ad set
|
|
111
|
+
|
|
112
|
+
Flags (create/update):
|
|
113
|
+
--campaign <id> Parent campaign ID (required for create)
|
|
114
|
+
--name <name> Ad set name (required for create)
|
|
115
|
+
${FLAG.status}
|
|
116
|
+
${FLAG.budgetDaily}
|
|
117
|
+
--optimization <t> link_clicks, impressions, reach, conversions, landing_page_views, lead_generation
|
|
118
|
+
--event-type <t> purchase, lead, complete_registration, add_to_cart, subscribe, start_trial, contact, content_view, other
|
|
119
|
+
--pixel <id> Pixel ID (falls back to account default)
|
|
120
|
+
--countries <codes> Comma-separated ISO codes, e.g. US,CA
|
|
121
|
+
--interest <id> Interest ID (repeatable). Find IDs: adkit manage meta interests search <query>
|
|
122
|
+
|
|
123
|
+
Rules:
|
|
124
|
+
- objective=sales → event-type: purchase, add_to_cart, complete_registration, subscribe, start_trial, content_view
|
|
125
|
+
- objective=leads → event-type: lead, contact, complete_registration, subscribe, other
|
|
126
|
+
|
|
127
|
+
Examples:
|
|
128
|
+
adkit manage meta adsets create --campaign cmp_abc --name "US Broad" \\
|
|
129
|
+
--optimization conversions --event-type purchase --countries US --budget-daily 20 --publish
|
|
130
|
+
adkit manage meta adsets create --campaign cmp_abc --name "US SaaS" \\
|
|
131
|
+
--optimization conversions --event-type purchase --countries US \\
|
|
132
|
+
--interest "6003344765839" --interest "6003127206524" --budget-daily 20 --publish
|
|
133
|
+
adkit manage meta adsets update as_xyz --budget-daily 50
|
|
134
|
+
adkit manage meta adsets delete as_xyz
|
|
135
|
+
|
|
136
|
+
Run --help full for all fields and advanced options.`;
|
|
137
|
+
const ADSET_HELP_FULL = `adkit manage meta adsets — Meta ad sets
|
|
138
|
+
|
|
139
|
+
list List ad sets
|
|
140
|
+
create Create an ad set
|
|
141
|
+
update <id> Update an ad set
|
|
142
|
+
delete <id> Delete an ad set
|
|
143
|
+
|
|
144
|
+
Flags (create/update):
|
|
145
|
+
--campaign <id> Parent campaign ID (required for create)
|
|
146
|
+
--name <name> Ad set name (required for create)
|
|
147
|
+
${FLAG.status}
|
|
148
|
+
${FLAG.budgetDaily}
|
|
149
|
+
--optimization <t> link_clicks, impressions, reach, conversions, landing_page_views, lead_generation
|
|
150
|
+
--event-type <t> purchase, lead, complete_registration, add_to_cart, subscribe, start_trial, contact, content_view, other
|
|
151
|
+
--pixel <id> Pixel ID (falls back to account default)
|
|
152
|
+
--countries <codes> Comma-separated ISO codes, e.g. US,CA
|
|
153
|
+
--interest <id> Interest ID (repeatable). Find IDs: adkit manage meta interests search <query>
|
|
154
|
+
|
|
155
|
+
Rules:
|
|
156
|
+
- objective=sales → event-type: purchase, add_to_cart, complete_registration, subscribe, start_trial, content_view
|
|
157
|
+
- objective=leads → event-type: lead, contact, complete_registration, subscribe, other
|
|
158
|
+
|
|
159
|
+
Advanced flags:
|
|
160
|
+
--targeting <json> Complex targeting JSON, merged with simple flags (JSON keys take precedence)
|
|
161
|
+
--genders <list> male, female
|
|
162
|
+
|
|
163
|
+
--data JSON fields:
|
|
164
|
+
budget.lifetime (number) Lifetime budget
|
|
165
|
+
bidAmount (number) Bid amount in account currency
|
|
166
|
+
destinationType (string) website, app, messenger, instagram, whatsapp
|
|
167
|
+
startTime (string) ISO date
|
|
168
|
+
endTime (string) ISO date
|
|
169
|
+
isDynamicCreative (boolean) Enable dynamic creative
|
|
170
|
+
promotedObject.pixelId (string) Meta Pixel ID
|
|
171
|
+
promotedObject.customEventType (string) Custom conversion event
|
|
172
|
+
promotedObject.pageId (string) Facebook Page ID
|
|
173
|
+
targeting.age (object) {"min":25,"max":55}
|
|
174
|
+
targeting.publisherPlatforms (string[]) facebook, instagram, audience_network, messenger
|
|
175
|
+
targeting.devicePlatforms (string[]) mobile, desktop
|
|
176
|
+
targeting.interests (string[]) Interest IDs
|
|
177
|
+
targeting.behaviors (string[]) Behavior IDs
|
|
178
|
+
targeting.customAudiences (string[]) Custom audience IDs
|
|
179
|
+
targeting.excludedCustomAudiences (string[]) Excluded audience IDs
|
|
180
|
+
targeting.expand (object) Advantage+ audience controls
|
|
181
|
+
|
|
182
|
+
Note: Meta defaults to Advantage+ audience (AI-driven targeting).
|
|
183
|
+
With Advantage+, age.min cannot exceed 25 and age.max cannot be below 65.
|
|
184
|
+
To use exact age ranges, disable Advantage+ for age:
|
|
185
|
+
--data '{"targeting":{"age":{"min":25,"max":55},"expand":{"age":false}}}'
|
|
186
|
+
|
|
187
|
+
Examples:
|
|
188
|
+
adkit manage meta adsets create --campaign cmp_abc --name "US Broad" \\
|
|
189
|
+
--optimization conversions --event-type purchase --countries US --budget-daily 20 --publish
|
|
190
|
+
adkit manage meta adsets create --campaign cmp_abc --name "US SaaS" \\
|
|
191
|
+
--optimization conversions --event-type purchase --countries US \\
|
|
192
|
+
--interest "6003344765839" --interest "6003127206524" --budget-daily 20 --publish
|
|
193
|
+
adkit manage meta adsets create --data '{
|
|
194
|
+
"campaignId":"cmp_abc","name":"US SaaS 25-55",
|
|
195
|
+
"budget":{"daily":30},"optimization":"conversions",
|
|
196
|
+
"promotedObject":{"pixelId":"px_123","customEventType":"PURCHASE"},
|
|
197
|
+
"targeting":{"countries":["US"],"age":{"min":25,"max":55},
|
|
198
|
+
"expand":{"age":false},"interests":["6003279598823"]}
|
|
199
|
+
}' --publish
|
|
200
|
+
adkit manage meta adsets update as_xyz --budget-daily 50
|
|
201
|
+
adkit manage meta adsets delete as_xyz`;
|
|
202
|
+
// --- Ads ---
|
|
203
|
+
const ADS_HELP = `adkit manage meta ads — Meta ads
|
|
204
|
+
|
|
205
|
+
list List ads
|
|
206
|
+
create Create an ad
|
|
207
|
+
update <id> Update an ad
|
|
208
|
+
delete <id> Delete an ad
|
|
209
|
+
|
|
210
|
+
Flags (create — new creative from media):
|
|
211
|
+
--adset <id> Ad set ID (required)
|
|
212
|
+
--media <path|url> Media file or URL (repeatable). Handles upload + processing automatically
|
|
213
|
+
--primary-text <t> Ad body text (repeatable)
|
|
214
|
+
--headline <text> Headline text (repeatable)
|
|
215
|
+
--description <t> Description text (repeatable, optional)
|
|
216
|
+
${FLAG.cta}
|
|
217
|
+
--name <name> Ad name
|
|
218
|
+
--url <url> Landing page URL
|
|
219
|
+
--page <id> Facebook Page ID (auto-resolved from account defaults)
|
|
220
|
+
|
|
221
|
+
Flags (create — existing creative):
|
|
222
|
+
--adset <id> Ad set ID (required)
|
|
223
|
+
--creative <id> Existing creative ID
|
|
224
|
+
--name <name> Ad name
|
|
225
|
+
|
|
226
|
+
Flags (list):
|
|
227
|
+
--adset <id> Filter by ad set ID
|
|
228
|
+
|
|
229
|
+
Examples:
|
|
230
|
+
adkit manage meta ads create --adset as_789 \\
|
|
231
|
+
--media ./hero.mp4 --primary-text "Try it free" --headline "Get started" \\
|
|
232
|
+
--cta sign_up --url https://example.com --publish
|
|
233
|
+
adkit manage meta ads create --adset as_789 --creative cr_abc --name "Hero v1" --publish
|
|
234
|
+
adkit manage meta ads list --adset as_xyz
|
|
235
|
+
adkit manage meta ads update ad_123 --data '{"status":"paused"}'
|
|
236
|
+
adkit manage meta ads delete ad_123
|
|
237
|
+
|
|
238
|
+
Run --help full for all fields and advanced options.`;
|
|
239
|
+
const ADS_HELP_FULL = `adkit manage meta ads — Meta ads
|
|
240
|
+
|
|
241
|
+
list List ads
|
|
242
|
+
create Create an ad
|
|
243
|
+
update <id> Update an ad
|
|
244
|
+
delete <id> Delete an ad
|
|
245
|
+
|
|
246
|
+
Flags (create — new creative from media):
|
|
247
|
+
--adset <id> Ad set ID (required)
|
|
248
|
+
--media <path|url> Media file or URL (repeatable). Handles upload + processing automatically
|
|
249
|
+
--primary-text <t> Ad body text (repeatable)
|
|
250
|
+
--headline <text> Headline text (repeatable)
|
|
251
|
+
--description <t> Description text (repeatable, optional)
|
|
252
|
+
${FLAG.cta}
|
|
253
|
+
--name <name> Ad name
|
|
254
|
+
--url <url> Landing page URL
|
|
255
|
+
--page <id> Facebook Page ID (auto-resolved from account defaults)
|
|
256
|
+
|
|
257
|
+
Flags (create — existing creative):
|
|
258
|
+
--adset <id> Ad set ID (required)
|
|
259
|
+
--creative <id> Existing creative ID
|
|
260
|
+
--name <name> Ad name
|
|
261
|
+
|
|
262
|
+
Flags (list):
|
|
263
|
+
--adset <id> Filter by ad set ID
|
|
264
|
+
|
|
265
|
+
--data JSON fields:
|
|
266
|
+
adsetId (required) Parent ad set ID
|
|
267
|
+
name (required) Ad name
|
|
268
|
+
status active, paused, archived, deleted
|
|
269
|
+
creative { creativeId: "cr_..." } — reference existing creative
|
|
270
|
+
platformOverrides Raw Meta API fields merged onto the payload
|
|
271
|
+
|
|
272
|
+
Examples:
|
|
273
|
+
adkit manage meta ads create --adset as_789 \\
|
|
274
|
+
--media ./hero.mp4 --primary-text "Try it free" --headline "Get started" \\
|
|
275
|
+
--cta sign_up --url https://example.com --publish
|
|
276
|
+
adkit manage meta ads create --adset as_789 --creative cr_abc --name "Hero v1" --publish
|
|
277
|
+
adkit manage meta ads create --data '{"adsetId":"as_xyz","creative":{"creativeId":"cr_abc"},"name":"Hero v1"}' --publish
|
|
278
|
+
adkit manage meta ads list --adset as_xyz
|
|
279
|
+
adkit manage meta ads update ad_123 --data '{"status":"paused"}'
|
|
280
|
+
adkit manage meta ads delete ad_123`;
|
|
281
|
+
// --- Creatives ---
|
|
282
|
+
const CREATIVE_HELP = `adkit manage meta creatives — Meta ad creatives
|
|
283
|
+
|
|
284
|
+
Prefer using "ads create --media" which handles creative creation automatically.
|
|
285
|
+
|
|
286
|
+
create Create an ad creative
|
|
287
|
+
update <id> Update an ad creative
|
|
288
|
+
delete <id> Delete an ad creative
|
|
289
|
+
|
|
290
|
+
Flags (create/update):
|
|
291
|
+
--page-id <id> Facebook Page ID (required for create)
|
|
292
|
+
--headline <text> Ad headline (required for create)
|
|
293
|
+
--primary-text <t> Ad body text (required for create, repeatable)
|
|
294
|
+
--link-url <url> Destination URL (required for create)
|
|
295
|
+
${FLAG.cta}
|
|
296
|
+
--name <name> Creative name
|
|
297
|
+
--image-hash <hash> Image hash from media upload
|
|
298
|
+
--image-url <url> Image URL
|
|
299
|
+
--video-id <id> Video ID from media upload
|
|
300
|
+
|
|
301
|
+
Examples:
|
|
302
|
+
adkit manage meta creatives create --page-id pg_123 --headline "Get Started" \\
|
|
303
|
+
--primary-text "Try it free" --link-url https://example.com \\
|
|
304
|
+
--cta sign_up --image-hash abc123 --publish
|
|
305
|
+
adkit manage meta creatives update cr_abc --primary-text "Start free trial"
|
|
306
|
+
adkit manage meta creatives delete cr_abc
|
|
307
|
+
|
|
308
|
+
Run --help full for all fields and advanced options.`;
|
|
309
|
+
const CREATIVE_HELP_FULL = `adkit manage meta creatives — Meta ad creatives
|
|
310
|
+
|
|
311
|
+
Prefer using "ads create --media" which handles creative creation automatically.
|
|
312
|
+
|
|
313
|
+
create Create an ad creative
|
|
314
|
+
update <id> Update an ad creative
|
|
315
|
+
delete <id> Delete an ad creative
|
|
316
|
+
|
|
317
|
+
Flags (create/update):
|
|
318
|
+
--page-id <id> Facebook Page ID (required for create)
|
|
319
|
+
--headline <text> Ad headline (required for create)
|
|
320
|
+
--primary-text <t> Ad body text (required for create, repeatable)
|
|
321
|
+
--link-url <url> Destination URL (required for create)
|
|
322
|
+
${FLAG.cta}
|
|
323
|
+
--name <name> Creative name
|
|
324
|
+
--link-description <t> Link description (repeatable, optional)
|
|
325
|
+
--image-hash <hash> Image hash from media upload
|
|
326
|
+
--image-url <url> Image URL
|
|
327
|
+
--video-id <id> Video ID from media upload
|
|
328
|
+
|
|
329
|
+
--data JSON fields:
|
|
330
|
+
thumbnailUrl (string) Video thumbnail URL
|
|
331
|
+
pixelId (string) Pixel ID for conversion tracking
|
|
332
|
+
variants Multi-variant creative:
|
|
333
|
+
images (string[]), videos (string[]), texts (string[]),
|
|
334
|
+
headlines (string[]), descriptions (string[]),
|
|
335
|
+
ctas (string[]), linkUrls (string[])
|
|
336
|
+
|
|
337
|
+
Examples:
|
|
338
|
+
adkit manage meta creatives create --page-id pg_123 --headline "Get Started" \\
|
|
339
|
+
--primary-text "Try it free" --link-url https://example.com \\
|
|
340
|
+
--cta sign_up --image-hash abc123 --publish
|
|
341
|
+
adkit manage meta creatives create --data '{
|
|
342
|
+
"pageId":"pg_123","name":"Multi-variant test",
|
|
343
|
+
"headline":"Get Started","primaryText":"Try it free",
|
|
344
|
+
"linkUrl":"https://example.com","cta":"sign_up",
|
|
345
|
+
"imageHash":"abc123","pixelId":"px_456"
|
|
346
|
+
}' --publish
|
|
347
|
+
adkit manage meta creatives update cr_abc --primary-text "Start free trial"
|
|
348
|
+
adkit manage meta creatives delete cr_abc`;
|
|
349
|
+
// ---------------------------------------------------------------------------
|
|
350
|
+
// Composed HELP and HELP_FULL
|
|
351
|
+
// ---------------------------------------------------------------------------
|
|
352
|
+
const HELP = {
|
|
353
|
+
'meta accounts': `adkit manage meta accounts — Meta ad accounts
|
|
354
|
+
|
|
355
|
+
list List connected ad accounts
|
|
356
|
+
connect <id> Connect an ad account
|
|
357
|
+
disconnect <id> Disconnect an ad account
|
|
358
|
+
<id> pages List Facebook Pages for an account
|
|
359
|
+
<id> pixels List Meta Pixels for an account
|
|
360
|
+
|
|
361
|
+
Examples:
|
|
362
|
+
adkit manage meta accounts list
|
|
363
|
+
adkit manage meta accounts connect act_123456789
|
|
364
|
+
adkit manage meta accounts act_123456789 pages
|
|
365
|
+
adkit manage meta accounts disconnect act_123456789`.trim(),
|
|
366
|
+
'meta campaigns': CAMPAIGN_HELP,
|
|
367
|
+
'meta adsets': ADSET_HELP,
|
|
368
|
+
'meta ads': ADS_HELP,
|
|
369
|
+
'meta creatives': CREATIVE_HELP,
|
|
370
|
+
'meta media': `adkit manage meta media — Upload media to Meta
|
|
371
|
+
|
|
372
|
+
upload Upload an image or video
|
|
373
|
+
|
|
374
|
+
Flags:
|
|
375
|
+
--file <path> Local file to upload
|
|
376
|
+
--url <url> Image URL to upload
|
|
377
|
+
|
|
378
|
+
Examples:
|
|
379
|
+
adkit manage meta media upload --file ./hero-video.mp4
|
|
380
|
+
adkit manage meta media upload --url https://example.com/hero.png`.trim(),
|
|
381
|
+
'meta interests': `adkit manage meta interests — Search targeting interests
|
|
382
|
+
|
|
383
|
+
search <query> Search for interests (multiple queries supported)
|
|
384
|
+
|
|
385
|
+
Output: Returns id and name for each interest. Use the id with --interest flag.
|
|
386
|
+
|
|
387
|
+
Examples:
|
|
388
|
+
adkit manage meta interests search "yoga"
|
|
389
|
+
adkit manage meta interests search "saas" "marketing" "digital ads"`.trim(),
|
|
390
|
+
manage: `adkit manage — Ad platform management
|
|
391
|
+
|
|
392
|
+
Platforms:
|
|
393
|
+
meta Meta (Facebook/Instagram) ads
|
|
394
|
+
drafts Manage drafts across platforms
|
|
395
|
+
|
|
396
|
+
Run adkit manage <platform> --help for details.`.trim(),
|
|
397
|
+
meta: `adkit manage meta — Meta Ads management
|
|
398
|
+
|
|
399
|
+
Entity groups:
|
|
400
|
+
accounts List connected ad accounts
|
|
401
|
+
campaigns Manage campaigns
|
|
402
|
+
adsets Manage ad sets
|
|
403
|
+
ads Manage ads
|
|
404
|
+
creatives Manage ad creatives (prefer using ads --media directly)
|
|
405
|
+
interests Search targeting interests
|
|
406
|
+
|
|
407
|
+
General flags (all create/update commands):
|
|
408
|
+
${FLAG.account}
|
|
409
|
+
${FLAG.publish}
|
|
410
|
+
${FLAG.data}
|
|
411
|
+
|
|
412
|
+
Mutations are draft-first by default. Use --publish to publish immediately.
|
|
413
|
+
Run adkit manage meta <group> --help for details.`.trim(),
|
|
414
|
+
drafts: `adkit manage drafts — Manage drafts
|
|
415
|
+
|
|
416
|
+
list List all drafts
|
|
417
|
+
get <id> Get a draft by ID
|
|
418
|
+
publish <id> Publish a draft
|
|
419
|
+
delete <id> Delete a draft
|
|
420
|
+
|
|
421
|
+
Flags (list):
|
|
422
|
+
--platform <name> Filter by platform
|
|
423
|
+
--limit <n> Max results
|
|
424
|
+
--offset <n> Pagination offset
|
|
425
|
+
|
|
426
|
+
Examples:
|
|
427
|
+
adkit manage drafts list --platform meta --limit 10
|
|
428
|
+
adkit manage drafts publish dft_abc123
|
|
429
|
+
adkit manage drafts delete dft_abc123`.trim(),
|
|
430
|
+
status: `adkit status — Show project context and connected accounts
|
|
431
|
+
|
|
432
|
+
Displays project name, connected platforms, and ad accounts with defaults.
|
|
433
|
+
AI agents should call this first to understand the context.
|
|
434
|
+
|
|
435
|
+
Examples:
|
|
436
|
+
adkit status
|
|
437
|
+
adkit status --json`.trim(),
|
|
438
|
+
projects: `adkit projects — Manage projects
|
|
439
|
+
|
|
440
|
+
list List all configured projects
|
|
441
|
+
use <id> Switch active project
|
|
442
|
+
current Show active project
|
|
443
|
+
|
|
444
|
+
Examples:
|
|
445
|
+
adkit projects list
|
|
446
|
+
adkit projects use proj_abc123`.trim(),
|
|
447
|
+
};
|
|
448
|
+
const HELP_FULL = {
|
|
449
|
+
'meta campaigns': CAMPAIGN_HELP_FULL,
|
|
450
|
+
'meta adsets': ADSET_HELP_FULL,
|
|
451
|
+
'meta ads': ADS_HELP_FULL,
|
|
452
|
+
'meta creatives': CREATIVE_HELP_FULL,
|
|
453
|
+
};
|
|
454
|
+
function getBaseUrl() {
|
|
455
|
+
return process.env.ADKIT_BASE_URL || DEFAULT_BASE_URL;
|
|
456
|
+
}
|
|
457
|
+
function wantsJson(flags) {
|
|
458
|
+
return flags.json === true || !(process.stdout.isTTY ?? false);
|
|
459
|
+
}
|
|
460
|
+
function requireClient(flags) {
|
|
461
|
+
const projectFlag = typeof flags.project === 'string' ? flags.project : undefined;
|
|
462
|
+
const { apiKey } = resolveConfig({ project: projectFlag });
|
|
463
|
+
if (!apiKey)
|
|
464
|
+
throw new CliError('NOT_AUTHENTICATED', 'No API key found', 'Run: adkit setup');
|
|
465
|
+
return new AdkitClient({ apiKey, baseUrl: getBaseUrl() });
|
|
466
|
+
}
|
|
467
|
+
function printList(data, flags, emptyHint = 'No results.') {
|
|
468
|
+
const rows = unwrapList(data);
|
|
469
|
+
const fields = typeof flags.fields === 'string' ? flags.fields.split(',') : undefined;
|
|
470
|
+
const output = formatOutput(rows, { fields, json: wantsJson(flags) });
|
|
471
|
+
if (output)
|
|
472
|
+
console.log(output);
|
|
473
|
+
else
|
|
474
|
+
console.log(emptyHint);
|
|
475
|
+
}
|
|
476
|
+
function hasArrayValues(v) {
|
|
477
|
+
return v !== null && typeof v === 'object' && !Array.isArray(v) && Object.values(v).some(Array.isArray);
|
|
478
|
+
}
|
|
479
|
+
function printResult(data, flags, emptyHint) {
|
|
480
|
+
if (data === undefined) {
|
|
481
|
+
console.log('Done.');
|
|
482
|
+
return;
|
|
483
|
+
}
|
|
484
|
+
if (wantsJson(flags))
|
|
485
|
+
console.log(JSON.stringify(data));
|
|
486
|
+
else if (Array.isArray(data) || hasArrayValues(data))
|
|
487
|
+
printList(data, flags, emptyHint);
|
|
488
|
+
else
|
|
489
|
+
console.log(JSON.stringify(data, null, 2));
|
|
490
|
+
}
|
|
491
|
+
function showHelp(key, full = false) {
|
|
492
|
+
const text = full ? HELP_FULL[key] || HELP[key] : HELP[key];
|
|
493
|
+
if (text) {
|
|
494
|
+
console.log(text);
|
|
495
|
+
return true;
|
|
496
|
+
}
|
|
497
|
+
return false;
|
|
498
|
+
}
|
|
499
|
+
async function main() {
|
|
500
|
+
const { args, flags } = parseArgs(process.argv.slice(2), {
|
|
501
|
+
multi: ['media', 'primary-text', 'headline', 'description', 'link-description', 'interest'],
|
|
502
|
+
});
|
|
503
|
+
if (args.length === 0) {
|
|
504
|
+
console.log(USAGE);
|
|
505
|
+
process.exit(0);
|
|
506
|
+
}
|
|
507
|
+
// Top-level --help with no command
|
|
508
|
+
if (flags.help && args.length === 0) {
|
|
509
|
+
console.log(USAGE);
|
|
510
|
+
process.exit(0);
|
|
511
|
+
}
|
|
512
|
+
try {
|
|
513
|
+
// --- status ---
|
|
514
|
+
if (args[0] === 'status') {
|
|
515
|
+
const client = requireClient(flags);
|
|
516
|
+
await status(client, wantsJson(flags));
|
|
517
|
+
return;
|
|
518
|
+
}
|
|
519
|
+
// --- manage commands (platform management) ---
|
|
520
|
+
if (args[0] === 'manage') {
|
|
521
|
+
const manageTarget = args[1];
|
|
522
|
+
if (flags.help && !manageTarget) {
|
|
523
|
+
showHelp('manage', flags.help === 'full');
|
|
524
|
+
process.exit(0);
|
|
525
|
+
}
|
|
526
|
+
if (!manageTarget) {
|
|
527
|
+
showHelp('manage', flags.help === 'full');
|
|
528
|
+
process.exit(0);
|
|
529
|
+
}
|
|
530
|
+
// --- manage drafts ---
|
|
531
|
+
if (manageTarget === 'drafts') {
|
|
532
|
+
const action = args[2];
|
|
533
|
+
const restArgs = args.slice(3);
|
|
534
|
+
if (flags.help) {
|
|
535
|
+
showHelp('drafts', flags.help === 'full');
|
|
536
|
+
process.exit(0);
|
|
537
|
+
}
|
|
538
|
+
const client = requireClient(flags);
|
|
539
|
+
let data;
|
|
540
|
+
let emptyHint;
|
|
541
|
+
switch (action) {
|
|
542
|
+
case 'list':
|
|
543
|
+
case undefined:
|
|
544
|
+
data = await listDrafts(client, restArgs, flags);
|
|
545
|
+
emptyHint = 'No drafts found. Drafts are created automatically when you create or update ads without `--publish`.';
|
|
546
|
+
break;
|
|
547
|
+
case 'get':
|
|
548
|
+
data = await getDraft(client, restArgs, flags);
|
|
549
|
+
break;
|
|
550
|
+
case 'publish':
|
|
551
|
+
data = await publishDraft(client, restArgs, flags);
|
|
552
|
+
break;
|
|
553
|
+
case 'delete':
|
|
554
|
+
data = await deleteDraft(client, restArgs, flags);
|
|
555
|
+
break;
|
|
556
|
+
default:
|
|
557
|
+
throw new CliError('UNKNOWN_COMMAND', `Unknown action: manage drafts ${action}`, 'Available: list, get, publish, delete');
|
|
558
|
+
}
|
|
559
|
+
printResult(data, flags, emptyHint);
|
|
560
|
+
return;
|
|
561
|
+
}
|
|
562
|
+
// --- manage <platform> (meta, google, etc.) ---
|
|
563
|
+
const platform = manageTarget;
|
|
564
|
+
if (platform !== 'meta')
|
|
565
|
+
throw new CliError('UNKNOWN_COMMAND', `Unknown platform: ${platform}`, 'Available: meta');
|
|
566
|
+
const entity = args[2];
|
|
567
|
+
const action = args[3];
|
|
568
|
+
const restArgs = args.slice(4);
|
|
569
|
+
// Help routing
|
|
570
|
+
if (flags.help) {
|
|
571
|
+
const helpKey = entity ? `meta ${entity}` : 'meta';
|
|
572
|
+
if (showHelp(helpKey, flags.help === 'full'))
|
|
573
|
+
process.exit(0);
|
|
574
|
+
console.log(USAGE);
|
|
575
|
+
process.exit(0);
|
|
576
|
+
}
|
|
577
|
+
if (!entity) {
|
|
578
|
+
showHelp('meta', flags.help === 'full');
|
|
579
|
+
process.exit(0);
|
|
580
|
+
}
|
|
581
|
+
const client = requireClient(flags);
|
|
582
|
+
let data;
|
|
583
|
+
let emptyHint;
|
|
584
|
+
switch (entity) {
|
|
585
|
+
case 'accounts': {
|
|
586
|
+
// Special case: meta accounts <id> pages/pixels
|
|
587
|
+
if (action && action !== 'list' && action !== 'connect' && action !== 'disconnect') {
|
|
588
|
+
const accountId = action;
|
|
589
|
+
const sub = args[4];
|
|
590
|
+
if (sub === 'pages') {
|
|
591
|
+
data = await listPages(client, [accountId], flags);
|
|
592
|
+
emptyHint = 'No Facebook Pages found for this account.';
|
|
593
|
+
}
|
|
594
|
+
else if (sub === 'pixels') {
|
|
595
|
+
data = await listPixels(client, [accountId], flags);
|
|
596
|
+
emptyHint = 'No Meta Pixels found for this account.';
|
|
597
|
+
}
|
|
598
|
+
else
|
|
599
|
+
throw new CliError('UNKNOWN_COMMAND', `Unknown subcommand: meta accounts ${accountId} ${sub ?? ''}`, 'Expected: pages or pixels');
|
|
600
|
+
break;
|
|
601
|
+
}
|
|
602
|
+
switch (action) {
|
|
603
|
+
case 'list':
|
|
604
|
+
case undefined:
|
|
605
|
+
data = await listAccounts(client, restArgs, flags);
|
|
606
|
+
emptyHint = 'No Meta ad accounts connected. Run `adkit setup manage` or connect via https://app.adkit.so/settings/integrations';
|
|
607
|
+
break;
|
|
608
|
+
case 'connect':
|
|
609
|
+
data = await connectAccount(client, restArgs, flags);
|
|
610
|
+
break;
|
|
611
|
+
case 'disconnect':
|
|
612
|
+
data = await disconnectAccount(client, restArgs, flags);
|
|
613
|
+
break;
|
|
614
|
+
default:
|
|
615
|
+
throw new CliError('UNKNOWN_COMMAND', `Unknown action: meta accounts ${action}`, 'Run: adkit manage meta accounts --help');
|
|
616
|
+
}
|
|
617
|
+
break;
|
|
618
|
+
}
|
|
619
|
+
case 'campaigns': {
|
|
620
|
+
if (!action) {
|
|
621
|
+
showHelp('meta campaigns', flags.help === 'full');
|
|
622
|
+
process.exit(0);
|
|
623
|
+
}
|
|
624
|
+
switch (action) {
|
|
625
|
+
case 'list':
|
|
626
|
+
data = await listCampaigns(client, restArgs, flags);
|
|
627
|
+
emptyHint = 'No campaigns found. Create one with `adkit manage meta campaigns create --name "My Campaign" --objective sales --publish`.';
|
|
628
|
+
break;
|
|
629
|
+
case 'create':
|
|
630
|
+
data = await createCampaign(client, restArgs, flags);
|
|
631
|
+
break;
|
|
632
|
+
case 'update':
|
|
633
|
+
data = await updateCampaign(client, restArgs, flags);
|
|
634
|
+
break;
|
|
635
|
+
case 'delete':
|
|
636
|
+
data = await deleteCampaign(client, restArgs, flags);
|
|
637
|
+
break;
|
|
638
|
+
default:
|
|
639
|
+
throw new CliError('UNKNOWN_COMMAND', `Unknown action: meta campaigns ${action}`, 'Run: adkit manage meta campaigns --help');
|
|
640
|
+
}
|
|
641
|
+
break;
|
|
642
|
+
}
|
|
643
|
+
case 'adsets': {
|
|
644
|
+
if (!action) {
|
|
645
|
+
showHelp('meta adsets', flags.help === 'full');
|
|
646
|
+
process.exit(0);
|
|
647
|
+
}
|
|
648
|
+
switch (action) {
|
|
649
|
+
case 'list':
|
|
650
|
+
data = await listAdSets(client, restArgs, flags);
|
|
651
|
+
emptyHint = 'No ad sets found. Create one with `adkit manage meta adsets create --campaign cmp_123 --name "My AdSet" --publish`.';
|
|
652
|
+
break;
|
|
653
|
+
case 'create':
|
|
654
|
+
data = await createAdSet(client, restArgs, flags);
|
|
655
|
+
break;
|
|
656
|
+
case 'update':
|
|
657
|
+
data = await updateAdSet(client, restArgs, flags);
|
|
658
|
+
break;
|
|
659
|
+
case 'delete':
|
|
660
|
+
data = await deleteAdSet(client, restArgs, flags);
|
|
661
|
+
break;
|
|
662
|
+
default:
|
|
663
|
+
throw new CliError('UNKNOWN_COMMAND', `Unknown action: meta adsets ${action}`, 'Run: adkit manage meta adsets --help');
|
|
664
|
+
}
|
|
665
|
+
break;
|
|
666
|
+
}
|
|
667
|
+
case 'ads': {
|
|
668
|
+
if (!action) {
|
|
669
|
+
showHelp('meta ads', flags.help === 'full');
|
|
670
|
+
process.exit(0);
|
|
671
|
+
}
|
|
672
|
+
switch (action) {
|
|
673
|
+
case 'list':
|
|
674
|
+
data = await listAds(client, restArgs, flags);
|
|
675
|
+
emptyHint = 'No ads found. Create one with `adkit manage meta ads create --data \'{"adsetId":"as_123","creativeId":"cr_123","name":"My Ad"}\'`.';
|
|
676
|
+
break;
|
|
677
|
+
case 'create':
|
|
678
|
+
data = await createAd(client, restArgs, flags);
|
|
679
|
+
break;
|
|
680
|
+
case 'update':
|
|
681
|
+
data = await updateAd(client, restArgs, flags);
|
|
682
|
+
break;
|
|
683
|
+
case 'delete':
|
|
684
|
+
data = await deleteAd(client, restArgs, flags);
|
|
685
|
+
break;
|
|
686
|
+
default:
|
|
687
|
+
throw new CliError('UNKNOWN_COMMAND', `Unknown action: meta ads ${action}`, 'Run: adkit manage meta ads --help');
|
|
688
|
+
}
|
|
689
|
+
break;
|
|
690
|
+
}
|
|
691
|
+
case 'creatives': {
|
|
692
|
+
switch (action) {
|
|
693
|
+
case 'create':
|
|
694
|
+
data = await createCreative(client, restArgs, flags);
|
|
695
|
+
break;
|
|
696
|
+
case 'update':
|
|
697
|
+
data = await updateCreative(client, restArgs, flags);
|
|
698
|
+
break;
|
|
699
|
+
case 'delete':
|
|
700
|
+
data = await deleteCreative(client, restArgs, flags);
|
|
701
|
+
break;
|
|
702
|
+
default:
|
|
703
|
+
throw new CliError('UNKNOWN_COMMAND', `Unknown action: meta creatives ${action ?? 'list'}`, 'Available: create, update, delete');
|
|
704
|
+
}
|
|
705
|
+
break;
|
|
706
|
+
}
|
|
707
|
+
case 'media': {
|
|
708
|
+
switch (action) {
|
|
709
|
+
case 'upload':
|
|
710
|
+
data = await uploadMedia(client, restArgs, flags);
|
|
711
|
+
break;
|
|
712
|
+
case 'list':
|
|
713
|
+
data = await listMedia(client, restArgs, flags);
|
|
714
|
+
emptyHint = 'No media found for this account.';
|
|
715
|
+
break;
|
|
716
|
+
case 'delete':
|
|
717
|
+
data = await deleteMedia(client, restArgs, flags);
|
|
718
|
+
break;
|
|
719
|
+
default:
|
|
720
|
+
throw new CliError('UNKNOWN_COMMAND', `Unknown action: meta media ${action ?? ''}`, 'Available: upload, list, delete');
|
|
721
|
+
}
|
|
722
|
+
break;
|
|
723
|
+
}
|
|
724
|
+
case 'interests': {
|
|
725
|
+
switch (action) {
|
|
726
|
+
case 'search':
|
|
727
|
+
data = await searchInterests(client, restArgs, flags);
|
|
728
|
+
emptyHint = 'No interests found for that query.';
|
|
729
|
+
break;
|
|
730
|
+
default:
|
|
731
|
+
throw new CliError('UNKNOWN_COMMAND', `Unknown action: meta interests ${action ?? ''}`, 'Available: search');
|
|
732
|
+
}
|
|
733
|
+
break;
|
|
734
|
+
}
|
|
735
|
+
default:
|
|
736
|
+
throw new CliError('UNKNOWN_COMMAND', `Unknown entity: meta ${entity}`, 'Available: accounts, campaigns, adsets, ads, creatives, media, interests');
|
|
737
|
+
}
|
|
738
|
+
printResult(data, flags, emptyHint);
|
|
739
|
+
return;
|
|
740
|
+
}
|
|
741
|
+
// --- projects commands ---
|
|
742
|
+
if (args[0] === 'projects') {
|
|
743
|
+
const action = args[1];
|
|
744
|
+
if (flags.help) {
|
|
745
|
+
showHelp('projects', flags.help === 'full');
|
|
746
|
+
process.exit(0);
|
|
747
|
+
}
|
|
748
|
+
switch (action) {
|
|
749
|
+
case 'list':
|
|
750
|
+
case undefined: {
|
|
751
|
+
const config = readConfig() ?? {};
|
|
752
|
+
const projects = listProjects(config);
|
|
753
|
+
if (projects.length === 0)
|
|
754
|
+
console.log('No projects configured. Run `adkit setup` to set up your first project.');
|
|
755
|
+
else {
|
|
756
|
+
for (const p of projects) {
|
|
757
|
+
const marker = p.current ? '* ' : ' ';
|
|
758
|
+
console.log(`${marker}${p.name} (${p.id})`);
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
break;
|
|
762
|
+
}
|
|
763
|
+
case 'current': {
|
|
764
|
+
const config = readConfig() ?? {};
|
|
765
|
+
const project = currentProject(config);
|
|
766
|
+
if (!project)
|
|
767
|
+
console.log('No project selected. Run `adkit projects use <id>`.');
|
|
768
|
+
else
|
|
769
|
+
console.log(`Active project: ${project.name} (${project.id})`);
|
|
770
|
+
break;
|
|
771
|
+
}
|
|
772
|
+
case 'use': {
|
|
773
|
+
const projectId = args[2];
|
|
774
|
+
if (!projectId)
|
|
775
|
+
throw new CliError('MISSING_ARGUMENT', 'Missing required argument: `<project-id>`', 'Run: adkit projects use <project-id>');
|
|
776
|
+
useProject(projectId);
|
|
777
|
+
console.log(`Switched to project: ${projectId}`);
|
|
778
|
+
break;
|
|
779
|
+
}
|
|
780
|
+
default:
|
|
781
|
+
throw new CliError('UNKNOWN_COMMAND', `Unknown action: projects ${action}`, 'Available: list, use, current');
|
|
782
|
+
}
|
|
783
|
+
return;
|
|
784
|
+
}
|
|
785
|
+
// --- logout ---
|
|
786
|
+
if (args[0] === 'logout') {
|
|
787
|
+
logout();
|
|
788
|
+
return;
|
|
789
|
+
}
|
|
790
|
+
// --- setup (auth + onboarding) ---
|
|
791
|
+
if (args[0] === 'setup') {
|
|
792
|
+
const scope = args.slice(1); // e.g. ['manage'], ['manage', 'studio'], or []
|
|
793
|
+
await login({ baseUrl: getBaseUrl(), scope });
|
|
794
|
+
return;
|
|
795
|
+
}
|
|
796
|
+
// --- fallback ---
|
|
797
|
+
throw new CliError('UNKNOWN_COMMAND', `Unknown command: ${args.join(' ')}`, 'Run: adkit --help');
|
|
798
|
+
}
|
|
799
|
+
catch (err) {
|
|
800
|
+
const jsonErrors = wantsJson(flags);
|
|
801
|
+
if (err instanceof CliError) {
|
|
802
|
+
if (!jsonErrors) {
|
|
803
|
+
console.error(`Error: ${err.message}`);
|
|
804
|
+
if (err.suggestion)
|
|
805
|
+
console.error(`Suggestion: ${err.suggestion}`);
|
|
806
|
+
}
|
|
807
|
+
else {
|
|
808
|
+
console.error(JSON.stringify({
|
|
809
|
+
error: true,
|
|
810
|
+
code: err.code,
|
|
811
|
+
message: err.message,
|
|
812
|
+
...(err.suggestion && { suggestion: err.suggestion }),
|
|
813
|
+
}));
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
else {
|
|
817
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
818
|
+
if (!jsonErrors)
|
|
819
|
+
console.error(`Error: ${message}`);
|
|
820
|
+
else {
|
|
821
|
+
console.error(JSON.stringify({
|
|
822
|
+
error: true,
|
|
823
|
+
code: 'UNKNOWN',
|
|
824
|
+
message,
|
|
825
|
+
}));
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
const EXIT_CODES = {
|
|
829
|
+
MISSING_ARGUMENT: 2,
|
|
830
|
+
MISSING_FLAG: 2,
|
|
831
|
+
INVALID_VALUE: 2,
|
|
832
|
+
UNKNOWN_COMMAND: 2,
|
|
833
|
+
UNKNOWN_FLAG: 2,
|
|
834
|
+
NOT_FOUND: 3,
|
|
835
|
+
INVALID_API_KEY: 4,
|
|
836
|
+
NOT_AUTHENTICATED: 4,
|
|
837
|
+
};
|
|
838
|
+
process.exit(err instanceof CliError ? (EXIT_CODES[err.code] ?? 1) : 1);
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
void main();
|