adapty 0.8.1 → 0.8.3-beta.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.
Files changed (34) hide show
  1. package/README.md +4 -0
  2. package/dist/commands/asa/ad-groups/create.d.ts +1 -0
  3. package/dist/commands/asa/ad-groups/create.js +20 -5
  4. package/dist/commands/asa/ad-groups/update.js +1 -1
  5. package/dist/commands/asa/ads/create.js +1 -1
  6. package/dist/commands/asa/ads/update.js +1 -1
  7. package/dist/commands/asa/automations/create.js +1 -1
  8. package/dist/commands/asa/automations/run.js +1 -1
  9. package/dist/commands/asa/automations/update.js +1 -1
  10. package/dist/commands/asa/campaigns/bulk-create.js +1 -1
  11. package/dist/commands/asa/campaigns/create.d.ts +5 -0
  12. package/dist/commands/asa/campaigns/create.js +16 -4
  13. package/dist/commands/asa/campaigns/update.d.ts +5 -0
  14. package/dist/commands/asa/campaigns/update.js +15 -4
  15. package/dist/commands/asa/keywords/add.js +1 -1
  16. package/dist/commands/asa/keywords/update.js +1 -1
  17. package/dist/commands/asa/negative-keywords/add.js +1 -1
  18. package/dist/commands/asa/product-pages/sync.js +1 -1
  19. package/dist/commands/flows/publish.d.ts +15 -0
  20. package/dist/commands/flows/publish.js +34 -0
  21. package/dist/commands/flows/update.d.ts +15 -0
  22. package/dist/commands/flows/update.js +28 -0
  23. package/dist/commands/placements/create.js +18 -3
  24. package/dist/commands/placements/update.js +18 -3
  25. package/dist/lib/api-schemas.d.ts +10 -1
  26. package/dist/lib/asa-flags.d.ts +22 -1
  27. package/dist/lib/asa-flags.js +47 -0
  28. package/dist/lib/asa-schemas.d.ts +19 -0
  29. package/dist/lib/placement-audiences.d.ts +6 -0
  30. package/dist/lib/placement-audiences.js +25 -0
  31. package/oclif.manifest.json +1746 -1555
  32. package/package.json +3 -2
  33. /package/dist/lib/{asa-confirm.d.ts → confirm.d.ts} +0 -0
  34. /package/dist/lib/{asa-confirm.js → confirm.js} +0 -0
@@ -124,6 +124,53 @@ export const idempotencyFlags = {
124
124
  export function money(amount, currency) {
125
125
  return amount === undefined ? undefined : { amount, currency };
126
126
  }
127
+ const INVOICE_FIELDS = {
128
+ 'invoice-advertiser': 'client_name',
129
+ 'invoice-billing-email': 'billing_contact_email',
130
+ 'invoice-contact-email': 'buyer_email',
131
+ 'invoice-contact-name': 'buyer_name',
132
+ 'invoice-order-number': 'order_number',
133
+ };
134
+ const INVOICE_PREFIX = 'Invoicing Options (line-of-credit orgs, see payment_model in asa orgs list)';
135
+ function invoiceFlag(what) {
136
+ return Flags.string({ description: `${INVOICE_PREFIX}: ${what}` });
137
+ }
138
+ export const invoiceFlags = {
139
+ 'invoice-advertiser': invoiceFlag('advertiser name'),
140
+ 'invoice-billing-email': invoiceFlag('billing contact email'),
141
+ 'invoice-contact-email': invoiceFlag('buyer contact email'),
142
+ 'invoice-contact-name': invoiceFlag('buyer contact name'),
143
+ 'invoice-order-number': invoiceFlag('order number'),
144
+ };
145
+ export function locInvoiceDetails(flags) {
146
+ const names = Object.keys(INVOICE_FIELDS);
147
+ const missing = names.filter((name) => flags[name] === undefined);
148
+ if (missing.length === names.length)
149
+ return undefined;
150
+ if (missing.length > 0) {
151
+ throw new Error(`Invoicing Options need all five flags; missing: ${missing.map((name) => `--${name}`).join(', ')}`);
152
+ }
153
+ return Object.fromEntries(names.map((name) => [INVOICE_FIELDS[name], flags[name]]));
154
+ }
155
+ const SERVING_HINTS = {
156
+ AUTOMATED_KEYWORDS_REQUIRED_AD_GROUP_MISSING: (campaignId) => `Max Conversions campaign needs an automated ad group: adapty asa ad-groups create --campaign ${campaignId} --name "Automated Max Conv" --automated`,
157
+ MISSING_BO_OR_INVOICING_FIELDS: (campaignId) => `This organization bills by line of credit — add Invoicing Options: adapty asa campaigns update ${campaignId} --invoice-advertiser ... --invoice-order-number ... --invoice-contact-name ... --invoice-contact-email ... --invoice-billing-email ...`,
158
+ };
159
+ export function reportServingState(campaign, warn) {
160
+ if (campaign?.serving_status !== 'NOT_RUNNING' || !campaign.serving_state_reasons?.length)
161
+ return;
162
+ const reasons = campaign.serving_state_reasons;
163
+ if (reasons.length === 1 && reasons[0] === 'PAUSED_BY_USER')
164
+ return;
165
+ for (const reason of reasons) {
166
+ const hint = SERVING_HINTS[reason];
167
+ if (hint)
168
+ warn(hint(campaign.internal_id));
169
+ }
170
+ const other = reasons.filter((reason) => !SERVING_HINTS[reason]);
171
+ if (other.length > 0)
172
+ warn(`Not serving: ${other.join(', ')}`);
173
+ }
127
174
  export function reportBulkOutcome({ applied, errors, isValidationFailure, kind }, log) {
128
175
  if (isValidationFailure) {
129
176
  log(`Nothing was applied: the batch failed validation before Apple was called.`);
@@ -48,6 +48,13 @@ export interface AsaAppDTO {
48
48
  last_synced_at: string;
49
49
  name: string;
50
50
  }
51
+ export interface AsaLocInvoiceDetails {
52
+ billing_contact_email: null | string;
53
+ buyer_email: null | string;
54
+ buyer_name: null | string;
55
+ client_name: null | string;
56
+ order_number: null | string;
57
+ }
51
58
  export interface AsaCampaignGroupDTO {
52
59
  currency: string;
53
60
  internal_id: string;
@@ -55,6 +62,7 @@ export interface AsaCampaignGroupDTO {
55
62
  org_id: number;
56
63
  org_name: string;
57
64
  parent_org_id: number;
65
+ payment_model: null | string;
58
66
  time_zone: string;
59
67
  }
60
68
  export interface AsaCampaignDTO {
@@ -70,8 +78,12 @@ export interface AsaCampaignDTO {
70
78
  daily_budget_amount: AsaMoney | null;
71
79
  end_time: null | string;
72
80
  internal_id: string;
81
+ loc_invoice_details: AsaLocInvoiceDetails | null;
73
82
  name: string;
74
83
  org_id: number;
84
+ payment_model: null | string;
85
+ serving_state_reasons: null | string[];
86
+ serving_status: null | string;
75
87
  start_time: null | string;
76
88
  status: AsaStatus;
77
89
  supply_sources: string[];
@@ -81,6 +93,7 @@ export interface AsaAdGroupDTO {
81
93
  ad_group_id: number;
82
94
  app_id: string;
83
95
  automated_keywords_opt_in: boolean | null;
96
+ automated_keywords_required: boolean | null;
84
97
  bidding_strategy: null | string;
85
98
  campaign_group_id: string;
86
99
  campaign_id: string;
@@ -91,6 +104,8 @@ export interface AsaAdGroupDTO {
91
104
  name: string;
92
105
  payment_model: null | string;
93
106
  pricing_model: null | string;
107
+ serving_state_reasons: null | string[];
108
+ serving_status: null | string;
94
109
  start_time: null | string;
95
110
  status: AsaStatus | null;
96
111
  target_cpa: AsaMoney | null;
@@ -261,7 +276,11 @@ export interface AsaCampaignMutationEntity {
261
276
  campaign_group_id: string;
262
277
  campaign_id: number;
263
278
  internal_id: string;
279
+ loc_invoice_details: AsaLocInvoiceDetails | null;
264
280
  name: string;
281
+ payment_model: null | string;
282
+ serving_state_reasons: null | string[];
283
+ serving_status: null | string;
265
284
  status: AsaStatus;
266
285
  }
267
286
  export interface AsaAdGroupMutationDTO {
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Returns a human-readable problem string when `entry` is not a valid placement
3
+ * audience entry, or `null` when it is well-formed. Every entry must carry an
4
+ * explicit `content_type` ('paywall' | 'flow'); there is no implicit paywall.
5
+ */
6
+ export declare function audienceEntryProblem(entry: unknown): null | string;
@@ -0,0 +1,25 @@
1
+ // Runtime guard for --audiences entries parsed from user/agent-supplied JSON.
2
+ // The DTO union in api-schemas.ts requires content_type, but a JSON.parse gives
3
+ // back `unknown`, so the type alone cannot enforce it — this does, the same way
4
+ // for humans and agents (no prompting).
5
+ /**
6
+ * Returns a human-readable problem string when `entry` is not a valid placement
7
+ * audience entry, or `null` when it is well-formed. Every entry must carry an
8
+ * explicit `content_type` ('paywall' | 'flow'); there is no implicit paywall.
9
+ */
10
+ export function audienceEntryProblem(entry) {
11
+ if (typeof entry !== 'object' || entry === null) {
12
+ return 'each entry must be a JSON object';
13
+ }
14
+ const { content_type: contentType, flow_id: flowId, paywall_id: paywallId } = entry;
15
+ if (contentType !== 'flow' && contentType !== 'paywall') {
16
+ return 'content_type is required and must be "paywall" or "flow"';
17
+ }
18
+ if (contentType === 'paywall' && typeof paywallId !== 'string') {
19
+ return 'a paywall entry requires paywall_id';
20
+ }
21
+ if (contentType === 'flow' && typeof flowId !== 'string') {
22
+ return 'a flow entry requires flow_id';
23
+ }
24
+ return null;
25
+ }