adapty 0.8.4-beta.1 → 0.8.5
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/README.md +133 -3
- package/bin/dev.js +2 -2
- package/bin/run.js +2 -2
- package/dist/commands/access-levels/create.js +1 -1
- package/dist/commands/access-levels/list.d.ts +1 -1
- package/dist/commands/apps/create.js +9 -6
- package/dist/commands/apps/list.d.ts +1 -1
- package/dist/commands/apps/update.js +7 -4
- package/dist/commands/asa/ad-groups/create.js +9 -7
- package/dist/commands/asa/ad-groups/get.js +3 -2
- package/dist/commands/asa/ad-groups/list.d.ts +1 -1
- package/dist/commands/asa/ad-groups/list.js +1 -1
- package/dist/commands/asa/ad-groups/update.js +22 -12
- package/dist/commands/asa/ads/create.js +7 -5
- package/dist/commands/asa/ads/get.js +3 -2
- package/dist/commands/asa/ads/list.d.ts +1 -1
- package/dist/commands/asa/ads/list.js +1 -1
- package/dist/commands/asa/ads/update.js +9 -5
- package/dist/commands/asa/apps/list.d.ts +1 -1
- package/dist/commands/asa/apps/list.js +1 -1
- package/dist/commands/asa/automations/create.d.ts +9 -0
- package/dist/commands/asa/automations/create.js +26 -7
- package/dist/commands/asa/automations/get.js +3 -2
- package/dist/commands/asa/automations/list.d.ts +1 -1
- package/dist/commands/asa/automations/list.js +1 -1
- package/dist/commands/asa/automations/run.js +5 -3
- package/dist/commands/asa/automations/runs.d.ts +1 -1
- package/dist/commands/asa/automations/runs.js +4 -4
- package/dist/commands/asa/automations/update.d.ts +9 -0
- package/dist/commands/asa/automations/update.js +36 -12
- package/dist/commands/asa/campaigns/bulk-create.js +31 -18
- package/dist/commands/asa/campaigns/bulk-list.js +7 -5
- package/dist/commands/asa/campaigns/bulk-status.js +3 -2
- package/dist/commands/asa/campaigns/create.js +10 -8
- package/dist/commands/asa/campaigns/get.js +3 -2
- package/dist/commands/asa/campaigns/list.d.ts +1 -1
- package/dist/commands/asa/campaigns/list.js +1 -1
- package/dist/commands/asa/campaigns/update.js +25 -15
- package/dist/commands/asa/competitors/summary.js +5 -5
- package/dist/commands/asa/connect.js +5 -3
- package/dist/commands/asa/creatives/list.d.ts +1 -1
- package/dist/commands/asa/creatives/list.js +1 -1
- package/dist/commands/asa/keywords/add.js +13 -10
- package/dist/commands/asa/keywords/list.d.ts +1 -1
- package/dist/commands/asa/keywords/list.js +1 -1
- package/dist/commands/asa/keywords/update.js +15 -10
- package/dist/commands/asa/metrics/index.d.ts +6 -3
- package/dist/commands/asa/metrics/index.js +38 -14
- package/dist/commands/asa/metrics/overview.js +3 -3
- package/dist/commands/asa/negative-keywords/add.js +10 -7
- package/dist/commands/asa/negative-keywords/list.d.ts +1 -1
- package/dist/commands/asa/negative-keywords/list.js +1 -1
- package/dist/commands/asa/orgs/list.d.ts +1 -1
- package/dist/commands/asa/orgs/list.js +1 -1
- package/dist/commands/asa/product-pages/list.d.ts +1 -1
- package/dist/commands/asa/product-pages/list.js +1 -1
- package/dist/commands/asa/product-pages/sync.js +1 -1
- package/dist/commands/asa/search-terms/list.d.ts +1 -1
- package/dist/commands/asa/search-terms/list.js +1 -1
- package/dist/commands/asa/whoami.js +7 -2
- package/dist/commands/auth/login.js +3 -1
- package/dist/commands/flows/config/get.js +2 -2
- package/dist/commands/flows/config/preview.d.ts +2 -2
- package/dist/commands/flows/config/preview.js +6 -4
- package/dist/commands/flows/config/update.js +5 -3
- package/dist/commands/flows/config/validate.js +5 -3
- package/dist/commands/flows/list.d.ts +1 -1
- package/dist/commands/flows/media/upload.js +1 -1
- package/dist/commands/flows/publish.js +5 -5
- package/dist/commands/paywalls/create.js +1 -1
- package/dist/commands/paywalls/list.d.ts +1 -1
- package/dist/commands/paywalls/placements.d.ts +2 -2
- package/dist/commands/paywalls/update.js +1 -1
- package/dist/commands/placements/create.js +17 -12
- package/dist/commands/placements/list.d.ts +1 -1
- package/dist/commands/placements/update.js +20 -15
- package/dist/commands/products/create.js +20 -13
- package/dist/commands/products/list.d.ts +1 -1
- package/dist/commands/products/update.js +1 -1
- package/dist/commands/segments/list.d.ts +1 -1
- package/dist/lib/api-client.d.ts +10 -6
- package/dist/lib/api-client.js +56 -35
- package/dist/lib/api-schemas.d.ts +56 -56
- package/dist/lib/app-url.js +2 -1
- package/dist/lib/asa-client.d.ts +13 -8
- package/dist/lib/asa-client.js +9 -4
- package/dist/lib/asa-flags.d.ts +37 -13
- package/dist/lib/asa-flags.js +87 -20
- package/dist/lib/asa-keyword-action.d.ts +18 -0
- package/dist/lib/asa-keyword-action.js +175 -0
- package/dist/lib/asa-schemas.d.ts +100 -80
- package/dist/lib/auth.js +2 -1
- package/dist/lib/client-from-config.d.ts +1 -1
- package/dist/lib/client-from-config.js +2 -1
- package/dist/lib/config.d.ts +2 -2
- package/dist/lib/confirm.d.ts +4 -4
- package/dist/lib/confirm.js +12 -7
- package/dist/lib/errors.d.ts +18 -18
- package/dist/lib/errors.js +14 -10
- package/dist/lib/flags.d.ts +3 -3
- package/dist/lib/flags.js +2 -1
- package/dist/lib/flow-help.js +11 -6
- package/dist/lib/output.js +23 -12
- package/dist/lib/preview.d.ts +5 -5
- package/dist/lib/preview.js +2 -1
- package/oclif.manifest.json +372 -200
- package/package.json +10 -8
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { isValidUuid } from './flags.js';
|
|
2
|
+
export const ADD_AS_KEYWORD_ACTION = 'add-as-keyword-to';
|
|
3
|
+
export const CPT_BID_TYPES = ['ad_group_default_bid', 'keyword_current_bid', 'search_term_current_cpt', 'set_to'];
|
|
4
|
+
export const KEYWORD_MATCH_TYPES = ['BROAD', 'EXACT'];
|
|
5
|
+
export const NEGATE_TYPES = ['ad-group', 'campaign'];
|
|
6
|
+
const SEARCH_TERM = 'search-term';
|
|
7
|
+
const TARGETING_KEYWORD = 'targeting-keyword';
|
|
8
|
+
const BID_TYPE_IGNORING_VALUE = 'ad_group_default_bid';
|
|
9
|
+
const BID_TYPES_READING_MARKUP = new Set(['keyword_current_bid', 'search_term_current_cpt']);
|
|
10
|
+
// KeywordMatchType also carries AUTO. --match-type never offers it — an automation creates a
|
|
11
|
+
// keyword, and AUTO is not something a keyword can be — but a rule that already stores AUTO keeps
|
|
12
|
+
// it rather than being pushed onto another match type by an edit that never mentioned match types.
|
|
13
|
+
const STORED_MATCH_TYPES = new Set(['AUTO', ...KEYWORD_MATCH_TYPES]);
|
|
14
|
+
const SHARED_FLAGS = ['target-ad-group', 'match-type', 'cpt-bid-type', 'cpt-bid'];
|
|
15
|
+
const SEARCH_TERM_FLAGS = ['negate', 'no-negate', 'skip-enable-duplicates'];
|
|
16
|
+
const TARGETING_KEYWORD_FLAGS = ['pause-original'];
|
|
17
|
+
const ALL_FLAGS = [...SHARED_FLAGS, ...SEARCH_TERM_FLAGS, ...TARGETING_KEYWORD_FLAGS];
|
|
18
|
+
const MISSING_REASONS = {
|
|
19
|
+
'cpt-bid': 'the bid to set, required by --cpt-bid-type set_to',
|
|
20
|
+
'cpt-bid-type': 'where the bid of the new keyword comes from; the API has no default',
|
|
21
|
+
'match-type': 'BROAD or EXACT; the API has no default',
|
|
22
|
+
'target-ad-group': 'the ad groups the keyword is added to; a rule with none does nothing',
|
|
23
|
+
};
|
|
24
|
+
function dashed(name) {
|
|
25
|
+
return `--${name}`;
|
|
26
|
+
}
|
|
27
|
+
function asRecord(value) {
|
|
28
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value) ? value : {};
|
|
29
|
+
}
|
|
30
|
+
function isFlagSet(flags, name) {
|
|
31
|
+
const value = flags[name];
|
|
32
|
+
if (value === undefined) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
if (Array.isArray(value)) {
|
|
36
|
+
return value.length > 0;
|
|
37
|
+
}
|
|
38
|
+
// --no-negate has no negated form of its own, so only a true means it was passed.
|
|
39
|
+
return name === 'no-negate' ? value === true : true;
|
|
40
|
+
}
|
|
41
|
+
export function hasAddKeywordActionFlags(flags) {
|
|
42
|
+
return ALL_FLAGS.some(name => isFlagSet(flags, name));
|
|
43
|
+
}
|
|
44
|
+
// Params are rebuilt, not patched: a rule may store the add-as-negative-keyword shape
|
|
45
|
+
// ({target_type, ids}) under an add-as-keyword-to action, and the API picks the params variant by
|
|
46
|
+
// shape without a discriminator — so every stray key silently changes which action gets run.
|
|
47
|
+
// Only what fits the expected shape is carried over; the rest has to come from the flags.
|
|
48
|
+
function storedInternalIds(params) {
|
|
49
|
+
const ids = asRecord(params.targets).internal_ids;
|
|
50
|
+
return Array.isArray(ids) ? ids.filter((id) => typeof id === 'string' && isValidUuid(id)) : [];
|
|
51
|
+
}
|
|
52
|
+
function storedMatchType(params) {
|
|
53
|
+
const matchType = params.match_type;
|
|
54
|
+
return typeof matchType === 'string' && STORED_MATCH_TYPES.has(matchType) ? matchType : undefined;
|
|
55
|
+
}
|
|
56
|
+
function storedCptBidType(params) {
|
|
57
|
+
const { type } = asRecord(params.cpt_bid);
|
|
58
|
+
return typeof type === 'string' && CPT_BID_TYPES.includes(type) ? type : undefined;
|
|
59
|
+
}
|
|
60
|
+
function storedCptBidValue(params) {
|
|
61
|
+
const { value } = asRecord(params.cpt_bid);
|
|
62
|
+
return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
|
|
63
|
+
}
|
|
64
|
+
function storedBoolean(value) {
|
|
65
|
+
return typeof value === 'boolean' ? value : undefined;
|
|
66
|
+
}
|
|
67
|
+
function storedNegate(params) {
|
|
68
|
+
const { enabled, type } = asRecord(params.negate);
|
|
69
|
+
if (typeof enabled !== 'boolean') {
|
|
70
|
+
return undefined;
|
|
71
|
+
}
|
|
72
|
+
if (type === null || type === undefined) {
|
|
73
|
+
return { enabled, type: null };
|
|
74
|
+
}
|
|
75
|
+
return typeof type === 'string' && NEGATE_TYPES.includes(type) ? { enabled, type } : undefined;
|
|
76
|
+
}
|
|
77
|
+
function resolveNegate(flags, params) {
|
|
78
|
+
if (flags.negate !== undefined) {
|
|
79
|
+
return { enabled: true, type: flags.negate };
|
|
80
|
+
}
|
|
81
|
+
if (flags['no-negate'] === true) {
|
|
82
|
+
return { enabled: false, type: null };
|
|
83
|
+
}
|
|
84
|
+
return storedNegate(params) ?? { enabled: false, type: null };
|
|
85
|
+
}
|
|
86
|
+
function resolveCptBidValue(cptBidType, bid, params) {
|
|
87
|
+
if (cptBidType === 'set_to') {
|
|
88
|
+
return bid === undefined ? storedCptBidValue(params) : Number(bid);
|
|
89
|
+
}
|
|
90
|
+
if (cptBidType !== undefined && BID_TYPES_READING_MARKUP.has(cptBidType)) {
|
|
91
|
+
return bid === undefined ? (storedCptBidValue(params) ?? null) : Number(bid);
|
|
92
|
+
}
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
function isSearchTermRule(operateWith) {
|
|
96
|
+
if (operateWith === SEARCH_TERM) {
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
if (operateWith === TARGETING_KEYWORD) {
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
const shown = typeof operateWith === 'string' && operateWith.length > 0 ? `"${operateWith}"` : 'missing';
|
|
103
|
+
throw new Error(`${ADD_AS_KEYWORD_ACTION} runs on a "${SEARCH_TERM}" or "${TARGETING_KEYWORD}" rule only; this rule's operate_with is ${shown}.`);
|
|
104
|
+
}
|
|
105
|
+
function rejectForeignFlags(searchTerm, flags) {
|
|
106
|
+
const foreign = (searchTerm ? TARGETING_KEYWORD_FLAGS : SEARCH_TERM_FLAGS).filter(name => isFlagSet(flags, name));
|
|
107
|
+
if (foreign.length === 0) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
const applicable = [...SHARED_FLAGS, ...(searchTerm ? SEARCH_TERM_FLAGS : TARGETING_KEYWORD_FLAGS)];
|
|
111
|
+
throw new Error(`${foreign.map(name => dashed(name)).join(', ')} ${foreign.length === 1 ? 'has' : 'have'} no place in the params of an `
|
|
112
|
+
+ `operate_with "${searchTerm ? SEARCH_TERM : TARGETING_KEYWORD}" rule, and the API drops params it cannot `
|
|
113
|
+
+ `place. Applicable action flags: ${applicable.map(name => dashed(name)).join(', ')}.`);
|
|
114
|
+
}
|
|
115
|
+
function missingFlagsError(missing) {
|
|
116
|
+
const lines = missing.map(name => ` ${dashed(name)} — ${MISSING_REASONS[name]}`);
|
|
117
|
+
return new Error(`The ${ADD_AS_KEYWORD_ACTION} params are incomplete. Pass:\n${lines.join('\n')}`);
|
|
118
|
+
}
|
|
119
|
+
export function buildAddKeywordParams(operateWith, stored, flags) {
|
|
120
|
+
const searchTerm = isSearchTermRule(operateWith);
|
|
121
|
+
rejectForeignFlags(searchTerm, flags);
|
|
122
|
+
const params = asRecord(stored);
|
|
123
|
+
const missing = [];
|
|
124
|
+
const internalIds = flags['target-ad-group'] ?? storedInternalIds(params);
|
|
125
|
+
if (internalIds.length === 0) {
|
|
126
|
+
missing.push('target-ad-group');
|
|
127
|
+
}
|
|
128
|
+
const matchType = flags['match-type'] ?? storedMatchType(params);
|
|
129
|
+
if (matchType === undefined) {
|
|
130
|
+
missing.push('match-type');
|
|
131
|
+
}
|
|
132
|
+
const cptBidType = flags['cpt-bid-type'] ?? storedCptBidType(params);
|
|
133
|
+
if (cptBidType === undefined) {
|
|
134
|
+
missing.push('cpt-bid-type');
|
|
135
|
+
}
|
|
136
|
+
const bid = flags['cpt-bid'];
|
|
137
|
+
if (bid !== undefined && cptBidType === BID_TYPE_IGNORING_VALUE) {
|
|
138
|
+
throw new Error(`--cpt-bid has no meaning with --cpt-bid-type ${BID_TYPE_IGNORING_VALUE}; that type copies the target ad group's default bid.`);
|
|
139
|
+
}
|
|
140
|
+
const cptBidValue = resolveCptBidValue(cptBidType, bid, params);
|
|
141
|
+
if (cptBidValue === undefined) {
|
|
142
|
+
missing.push('cpt-bid');
|
|
143
|
+
}
|
|
144
|
+
if (missing.length > 0) {
|
|
145
|
+
throw missingFlagsError(missing);
|
|
146
|
+
}
|
|
147
|
+
const built = {
|
|
148
|
+
cpt_bid: { type: cptBidType, value: cptBidValue ?? null },
|
|
149
|
+
match_type: matchType,
|
|
150
|
+
targets: { internal_ids: internalIds, type: 'ad-group' },
|
|
151
|
+
};
|
|
152
|
+
if (searchTerm) {
|
|
153
|
+
built.negate = resolveNegate(flags, params);
|
|
154
|
+
built.skip_enable_duplicate_keywords
|
|
155
|
+
= flags['skip-enable-duplicates'] ?? storedBoolean(params.skip_enable_duplicate_keywords) ?? false;
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
built.pause_in_original_ad_group
|
|
159
|
+
= flags['pause-original'] ?? storedBoolean(params.pause_in_original_ad_group) ?? false;
|
|
160
|
+
}
|
|
161
|
+
return built;
|
|
162
|
+
}
|
|
163
|
+
export function requireSingleAction(actions) {
|
|
164
|
+
if (!Array.isArray(actions) || actions.length !== 1) {
|
|
165
|
+
throw new Error('A rule needs exactly one action: the API stores one action and one condition per rule.');
|
|
166
|
+
}
|
|
167
|
+
return asRecord(actions[0]);
|
|
168
|
+
}
|
|
169
|
+
export function rebuildAddKeywordAction(actions, operateWith, flags) {
|
|
170
|
+
const action = requireSingleAction(actions);
|
|
171
|
+
if (action.type !== ADD_AS_KEYWORD_ACTION) {
|
|
172
|
+
throw new Error(`The action flags only apply to an ${ADD_AS_KEYWORD_ACTION} action; this rule's action is "${String(action.type)}".`);
|
|
173
|
+
}
|
|
174
|
+
return [{ ...action, params: buildAddKeywordParams(operateWith, action.params, flags) }];
|
|
175
|
+
}
|
|
@@ -4,11 +4,11 @@ export type AsaKeywordMatchType = 'BROAD' | 'EXACT';
|
|
|
4
4
|
export type AsaKeywordStatus = 'ACTIVE' | 'PAUSED';
|
|
5
5
|
export type AsaStatus = 'ENABLED' | 'PAUSED';
|
|
6
6
|
export type AsaNegativeKeywordScope = 'AD_GROUP' | 'ALL_CAMPAIGN_AD_GROUPS' | 'CAMPAIGN';
|
|
7
|
-
export
|
|
7
|
+
export type AsaMoney = {
|
|
8
8
|
amount: string;
|
|
9
9
|
currency: string;
|
|
10
|
-
}
|
|
11
|
-
export
|
|
10
|
+
};
|
|
11
|
+
export type AsaMetricsDTO = {
|
|
12
12
|
avg_cpm: string;
|
|
13
13
|
avg_cpt: string;
|
|
14
14
|
impressions: number;
|
|
@@ -29,16 +29,36 @@ export interface AsaMetricsDTO {
|
|
|
29
29
|
view_installs: number;
|
|
30
30
|
view_new_downloads: number;
|
|
31
31
|
view_redownloads: number;
|
|
32
|
-
}
|
|
33
|
-
export
|
|
32
|
+
};
|
|
33
|
+
export type AsaMetricsResponse = {
|
|
34
|
+
data: Record<string, unknown>[];
|
|
35
|
+
meta: {
|
|
36
|
+
max_valid_day?: number;
|
|
37
|
+
pagination: {
|
|
38
|
+
count: number;
|
|
39
|
+
page: number;
|
|
40
|
+
pages: number;
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
export type AsaEffectiveLimitsDTO = {
|
|
45
|
+
keywords_read_limit_per_minute: number;
|
|
46
|
+
max_breakdown_rows_per_page: number;
|
|
47
|
+
metrics_burst_limit: number;
|
|
48
|
+
metrics_inflight_limit: number;
|
|
49
|
+
metrics_limit_per_minute: number;
|
|
50
|
+
read_limit_per_minute: number;
|
|
51
|
+
};
|
|
52
|
+
export type AsaMeDTO = {
|
|
34
53
|
access_source: AsaAccessSource;
|
|
35
54
|
apple_credentials_status: AsaAppleCredentialsStatus;
|
|
36
55
|
company_id: string;
|
|
37
|
-
|
|
38
|
-
|
|
56
|
+
limits?: AsaEffectiveLimitsDTO;
|
|
57
|
+
};
|
|
58
|
+
export type AsaAppleOAuthDTO = {
|
|
39
59
|
auth_url: string;
|
|
40
|
-
}
|
|
41
|
-
export
|
|
60
|
+
};
|
|
61
|
+
export type AsaAppDTO = {
|
|
42
62
|
adam_id: number;
|
|
43
63
|
bundle_id: null | string;
|
|
44
64
|
campaign_group_ids: string[];
|
|
@@ -47,15 +67,15 @@ export interface AsaAppDTO {
|
|
|
47
67
|
internal_id: string;
|
|
48
68
|
last_synced_at: string;
|
|
49
69
|
name: string;
|
|
50
|
-
}
|
|
51
|
-
export
|
|
70
|
+
};
|
|
71
|
+
export type AsaLocInvoiceDetails = {
|
|
52
72
|
billing_contact_email: null | string;
|
|
53
73
|
buyer_email: null | string;
|
|
54
74
|
buyer_name: null | string;
|
|
55
75
|
client_name: null | string;
|
|
56
76
|
order_number: null | string;
|
|
57
|
-
}
|
|
58
|
-
export
|
|
77
|
+
};
|
|
78
|
+
export type AsaCampaignGroupDTO = {
|
|
59
79
|
currency: string;
|
|
60
80
|
internal_id: string;
|
|
61
81
|
last_synced_at: string;
|
|
@@ -64,8 +84,8 @@ export interface AsaCampaignGroupDTO {
|
|
|
64
84
|
parent_org_id: number;
|
|
65
85
|
payment_model: null | string;
|
|
66
86
|
time_zone: string;
|
|
67
|
-
}
|
|
68
|
-
export
|
|
87
|
+
};
|
|
88
|
+
export type AsaCampaignDTO = {
|
|
69
89
|
ad_channel_type: string;
|
|
70
90
|
adam_id: number;
|
|
71
91
|
app_id: string;
|
|
@@ -88,8 +108,8 @@ export interface AsaCampaignDTO {
|
|
|
88
108
|
status: AsaStatus;
|
|
89
109
|
supply_sources: string[];
|
|
90
110
|
target_cpa: AsaMoney | null;
|
|
91
|
-
}
|
|
92
|
-
export
|
|
111
|
+
};
|
|
112
|
+
export type AsaAdGroupDTO = {
|
|
93
113
|
ad_group_id: number;
|
|
94
114
|
app_id: string;
|
|
95
115
|
automated_keywords_opt_in: boolean | null;
|
|
@@ -109,8 +129,8 @@ export interface AsaAdGroupDTO {
|
|
|
109
129
|
start_time: null | string;
|
|
110
130
|
status: AsaStatus | null;
|
|
111
131
|
target_cpa: AsaMoney | null;
|
|
112
|
-
}
|
|
113
|
-
export
|
|
132
|
+
};
|
|
133
|
+
export type AsaKeywordDTO = {
|
|
114
134
|
ad_group_id: string;
|
|
115
135
|
app_id: string;
|
|
116
136
|
bid_amount: AsaMoney;
|
|
@@ -122,8 +142,8 @@ export interface AsaKeywordDTO {
|
|
|
122
142
|
match_type: AsaKeywordMatchType;
|
|
123
143
|
status: AsaKeywordStatus | null;
|
|
124
144
|
text: string;
|
|
125
|
-
}
|
|
126
|
-
export
|
|
145
|
+
};
|
|
146
|
+
export type AsaSearchTermDTO = {
|
|
127
147
|
ad_group_id: string;
|
|
128
148
|
app_id: string;
|
|
129
149
|
campaign_group_id: string;
|
|
@@ -136,8 +156,8 @@ export interface AsaSearchTermDTO {
|
|
|
136
156
|
search_popularity: null | number;
|
|
137
157
|
source: null | string;
|
|
138
158
|
text: null | string;
|
|
139
|
-
}
|
|
140
|
-
export
|
|
159
|
+
};
|
|
160
|
+
export type AsaNegativeKeywordDTO = {
|
|
141
161
|
ad_group_id: null | string;
|
|
142
162
|
ad_group_name: null | string;
|
|
143
163
|
campaign_id: string;
|
|
@@ -147,8 +167,8 @@ export interface AsaNegativeKeywordDTO {
|
|
|
147
167
|
match_type: AsaKeywordMatchType;
|
|
148
168
|
status: AsaKeywordStatus;
|
|
149
169
|
text: string;
|
|
150
|
-
}
|
|
151
|
-
export
|
|
170
|
+
};
|
|
171
|
+
export type AsaCreativeDTO = {
|
|
152
172
|
adam_id: number;
|
|
153
173
|
app_id: string;
|
|
154
174
|
campaign_group_id: string;
|
|
@@ -160,8 +180,8 @@ export interface AsaCreativeDTO {
|
|
|
160
180
|
state: string;
|
|
161
181
|
state_reasons: string[];
|
|
162
182
|
type: string;
|
|
163
|
-
}
|
|
164
|
-
export
|
|
183
|
+
};
|
|
184
|
+
export type AsaProductPageDTO = {
|
|
165
185
|
adam_id: number;
|
|
166
186
|
app_id: string;
|
|
167
187
|
deep_link: null | string;
|
|
@@ -172,8 +192,8 @@ export interface AsaProductPageDTO {
|
|
|
172
192
|
last_synced_at: string;
|
|
173
193
|
name: string;
|
|
174
194
|
state: string;
|
|
175
|
-
}
|
|
176
|
-
export
|
|
195
|
+
};
|
|
196
|
+
export type AsaAdDTO = {
|
|
177
197
|
ad_group_id: string;
|
|
178
198
|
ad_group_name: null | string;
|
|
179
199
|
ad_id: number;
|
|
@@ -191,8 +211,8 @@ export interface AsaAdDTO {
|
|
|
191
211
|
serving_state_reasons: string[];
|
|
192
212
|
serving_status: string;
|
|
193
213
|
status: AsaStatus;
|
|
194
|
-
}
|
|
195
|
-
export
|
|
214
|
+
};
|
|
215
|
+
export type AsaAutomationDTO = {
|
|
196
216
|
actions: unknown[];
|
|
197
217
|
apply_to: unknown[];
|
|
198
218
|
conditions: unknown[];
|
|
@@ -206,46 +226,46 @@ export interface AsaAutomationDTO {
|
|
|
206
226
|
run_frequency: Record<string, unknown>;
|
|
207
227
|
status: number;
|
|
208
228
|
updated_at: string;
|
|
209
|
-
}
|
|
210
|
-
export
|
|
229
|
+
};
|
|
230
|
+
export type AsaAutomationRunDTO = {
|
|
211
231
|
[key: string]: unknown;
|
|
212
232
|
id?: string;
|
|
213
|
-
}
|
|
214
|
-
export
|
|
233
|
+
};
|
|
234
|
+
export type AsaAutomationRunEnqueuedDTO = {
|
|
215
235
|
automation_id: string;
|
|
216
236
|
dry_run: boolean;
|
|
217
237
|
run_id: null | string;
|
|
218
|
-
}
|
|
219
|
-
export
|
|
238
|
+
};
|
|
239
|
+
export type AsaProductPageSyncDTO = {
|
|
220
240
|
accepted_at: string;
|
|
221
241
|
message: string;
|
|
222
242
|
org_targets: number;
|
|
223
243
|
replayed: boolean;
|
|
224
244
|
state: string;
|
|
225
245
|
sync_id: string;
|
|
226
|
-
}
|
|
227
|
-
export
|
|
246
|
+
};
|
|
247
|
+
export type AsaCompetitorTopAppDTO = {
|
|
228
248
|
adamId: number;
|
|
229
249
|
avgSov: string;
|
|
230
250
|
countries: string[];
|
|
231
251
|
iconUrl: null | string;
|
|
232
252
|
name: null | string;
|
|
233
253
|
termsCount: number;
|
|
234
|
-
}
|
|
235
|
-
export
|
|
254
|
+
};
|
|
255
|
+
export type AsaCompetitorContestedTermDTO = {
|
|
236
256
|
competitorCount: number;
|
|
237
257
|
maxSov: string;
|
|
238
258
|
term: string;
|
|
239
|
-
}
|
|
240
|
-
export
|
|
259
|
+
};
|
|
260
|
+
export type AsaCompetitorsSummaryTotalDTO = {
|
|
241
261
|
competitorsCount: number;
|
|
242
262
|
countriesAsaCount: number;
|
|
243
263
|
countriesWithAsaTerms: number;
|
|
244
264
|
mostContestedTerms: AsaCompetitorContestedTermDTO[];
|
|
245
265
|
topAppsByPerformance: AsaCompetitorTopAppDTO[];
|
|
246
266
|
totalUniqueTerms: number;
|
|
247
|
-
}
|
|
248
|
-
export
|
|
267
|
+
};
|
|
268
|
+
export type AsaCompetitorAppTermsDTO = {
|
|
249
269
|
adamId: number;
|
|
250
270
|
countries: Record<string, {
|
|
251
271
|
sov: string;
|
|
@@ -253,12 +273,12 @@ export interface AsaCompetitorAppTermsDTO {
|
|
|
253
273
|
}[]>;
|
|
254
274
|
iconUrl: null | string;
|
|
255
275
|
name: null | string;
|
|
256
|
-
}
|
|
257
|
-
export
|
|
276
|
+
};
|
|
277
|
+
export type AsaCompetitorsSummaryDTO = {
|
|
258
278
|
byApps: AsaCompetitorAppTermsDTO[];
|
|
259
279
|
total: AsaCompetitorsSummaryTotalDTO;
|
|
260
|
-
}
|
|
261
|
-
export
|
|
280
|
+
};
|
|
281
|
+
export type AsaMutationError = {
|
|
262
282
|
apple_error_code?: null | string;
|
|
263
283
|
apple_error_message?: null | string;
|
|
264
284
|
entity_type?: string;
|
|
@@ -267,12 +287,12 @@ export interface AsaMutationError {
|
|
|
267
287
|
retryable?: boolean;
|
|
268
288
|
validation_error_code?: string;
|
|
269
289
|
validation_error_message?: string;
|
|
270
|
-
}
|
|
271
|
-
export
|
|
290
|
+
};
|
|
291
|
+
export type AsaCampaignMutationDTO = {
|
|
272
292
|
campaign: AsaCampaignMutationEntity | null;
|
|
273
293
|
errors: AsaMutationError[];
|
|
274
|
-
}
|
|
275
|
-
export
|
|
294
|
+
};
|
|
295
|
+
export type AsaCampaignMutationEntity = {
|
|
276
296
|
campaign_group_id: string;
|
|
277
297
|
campaign_id: number;
|
|
278
298
|
internal_id: string;
|
|
@@ -282,39 +302,39 @@ export interface AsaCampaignMutationEntity {
|
|
|
282
302
|
serving_state_reasons: null | string[];
|
|
283
303
|
serving_status: null | string;
|
|
284
304
|
status: AsaStatus;
|
|
285
|
-
}
|
|
286
|
-
export
|
|
305
|
+
};
|
|
306
|
+
export type AsaAdGroupMutationDTO = {
|
|
287
307
|
ad_group: null | Record<string, unknown>;
|
|
288
308
|
errors: AsaMutationError[];
|
|
289
|
-
}
|
|
290
|
-
export
|
|
309
|
+
};
|
|
310
|
+
export type AsaAdMutationDTO = {
|
|
291
311
|
ad: AsaAdDTO | null;
|
|
292
312
|
errors: AsaMutationError[];
|
|
293
|
-
}
|
|
294
|
-
export
|
|
313
|
+
};
|
|
314
|
+
export type AsaKeywordMutationDTO = {
|
|
295
315
|
errors: AsaMutationError[];
|
|
296
316
|
is_validation_failure: boolean;
|
|
297
317
|
keywords: Record<string, unknown>[];
|
|
298
|
-
}
|
|
299
|
-
export
|
|
318
|
+
};
|
|
319
|
+
export type AsaNegativeKeywordMutationDTO = {
|
|
300
320
|
errors: AsaMutationError[];
|
|
301
321
|
is_validation_failure: boolean;
|
|
302
322
|
negative_keywords: Record<string, unknown>[];
|
|
303
|
-
}
|
|
304
|
-
export
|
|
323
|
+
};
|
|
324
|
+
export type AsaAutomationMutationDTO = {
|
|
305
325
|
automation: AsaAutomationDTO | null;
|
|
306
|
-
}
|
|
326
|
+
};
|
|
307
327
|
export type AsaBulkOperationStatus = 'failed' | 'partial' | 'pending' | 'running' | 'success';
|
|
308
|
-
export
|
|
328
|
+
export type AsaBulkOperationAcceptedDTO = {
|
|
309
329
|
operation_id: string;
|
|
310
|
-
}
|
|
311
|
-
export
|
|
330
|
+
};
|
|
331
|
+
export type AsaBulkOperationCountsDTO = {
|
|
312
332
|
applied: number;
|
|
313
333
|
failed: number;
|
|
314
334
|
pending: number;
|
|
315
335
|
total: number;
|
|
316
|
-
}
|
|
317
|
-
export
|
|
336
|
+
};
|
|
337
|
+
export type AsaBulkOperationObjectDTO = {
|
|
318
338
|
apple_error_code: null | string;
|
|
319
339
|
apple_error_message: null | string;
|
|
320
340
|
entity_kind: string;
|
|
@@ -322,8 +342,8 @@ export interface AsaBulkOperationObjectDTO {
|
|
|
322
342
|
item_ref: string;
|
|
323
343
|
status: string;
|
|
324
344
|
step_type: string;
|
|
325
|
-
}
|
|
326
|
-
export
|
|
345
|
+
};
|
|
346
|
+
export type AsaBulkOperationStateDTO = {
|
|
327
347
|
counts: AsaBulkOperationCountsDTO;
|
|
328
348
|
created_at: string;
|
|
329
349
|
finished_at: null | string;
|
|
@@ -332,8 +352,8 @@ export interface AsaBulkOperationStateDTO {
|
|
|
332
352
|
pipelines: Record<string, unknown>[];
|
|
333
353
|
started_at: null | string;
|
|
334
354
|
status: AsaBulkOperationStatus;
|
|
335
|
-
}
|
|
336
|
-
export
|
|
355
|
+
};
|
|
356
|
+
export type AsaBulkOperationListItemDTO = {
|
|
337
357
|
app_id: string;
|
|
338
358
|
created_at: string;
|
|
339
359
|
error: null | string;
|
|
@@ -341,21 +361,21 @@ export interface AsaBulkOperationListItemDTO {
|
|
|
341
361
|
operation_id: string;
|
|
342
362
|
started_at: null | string;
|
|
343
363
|
status: AsaBulkOperationStatus;
|
|
344
|
-
}
|
|
345
|
-
export
|
|
364
|
+
};
|
|
365
|
+
export type AsaBulkOperationListDTO = {
|
|
346
366
|
items: AsaBulkOperationListItemDTO[];
|
|
347
367
|
limit: number;
|
|
348
368
|
offset: number;
|
|
349
369
|
total: number;
|
|
350
|
-
}
|
|
351
|
-
export
|
|
370
|
+
};
|
|
371
|
+
export type AsaTemplateIssueDTO = {
|
|
352
372
|
column: null | string;
|
|
353
373
|
message: string;
|
|
354
374
|
row: null | number;
|
|
355
375
|
sheet: null | string;
|
|
356
|
-
}
|
|
357
|
-
export
|
|
376
|
+
};
|
|
377
|
+
export type AsaBulkConvertResultDTO = {
|
|
358
378
|
errors: AsaTemplateIssueDTO[];
|
|
359
379
|
request: null | Record<string, unknown>;
|
|
360
380
|
warnings: AsaTemplateIssueDTO[];
|
|
361
|
-
}
|
|
381
|
+
};
|
package/dist/lib/auth.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { readConfig } from './config.js';
|
|
2
2
|
export async function resolveToken(configDir) {
|
|
3
3
|
const envToken = process.env.ADAPTY_TOKEN;
|
|
4
|
-
if (envToken)
|
|
4
|
+
if (envToken) {
|
|
5
5
|
return envToken;
|
|
6
|
+
}
|
|
6
7
|
const config = await readConfig(configDir);
|
|
7
8
|
return config.access_token ?? null;
|
|
8
9
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Config } from '@oclif/core';
|
|
2
1
|
import { ApiClient } from './api-client.js';
|
|
2
|
+
import type { Config } from '@oclif/core';
|
|
3
3
|
export declare function buildUserAgent(config: Config): string;
|
|
4
4
|
export declare function createAuthenticatedClient(config: Config): Promise<ApiClient>;
|
|
@@ -6,8 +6,9 @@ export function buildUserAgent(config) {
|
|
|
6
6
|
}
|
|
7
7
|
export async function createAuthenticatedClient(config) {
|
|
8
8
|
const token = await resolveToken(config.configDir);
|
|
9
|
-
if (!token)
|
|
9
|
+
if (!token) {
|
|
10
10
|
throw new AuthRequiredError();
|
|
11
|
+
}
|
|
11
12
|
return new ApiClient({
|
|
12
13
|
token,
|
|
13
14
|
userAgent: buildUserAgent(config),
|
package/dist/lib/config.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export
|
|
1
|
+
export type AdaptyConfig = {
|
|
2
2
|
access_token?: string;
|
|
3
3
|
user?: {
|
|
4
4
|
email: string;
|
|
5
5
|
name: string;
|
|
6
6
|
};
|
|
7
|
-
}
|
|
7
|
+
};
|
|
8
8
|
export declare function readConfig(configDir?: string): Promise<AdaptyConfig>;
|
|
9
9
|
export declare function writeConfig(config: AdaptyConfig, configDir?: string): Promise<void>;
|
package/dist/lib/confirm.d.ts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import { Command } from '@oclif/core';
|
|
1
|
+
import type { Command } from '@oclif/core';
|
|
2
2
|
export declare const confirmFlags: {
|
|
3
3
|
yes: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
4
4
|
};
|
|
5
5
|
export type ConfirmDecision = 'ask' | 'proceed' | 'refuse';
|
|
6
6
|
export declare function decideConfirmation(opts: {
|
|
7
|
-
isTty: boolean;
|
|
7
|
+
isTty: boolean | undefined;
|
|
8
8
|
json: boolean;
|
|
9
9
|
yes: boolean;
|
|
10
10
|
}): ConfirmDecision;
|
|
11
|
-
export
|
|
11
|
+
export type MutationPreview = {
|
|
12
12
|
body?: unknown;
|
|
13
13
|
method: string;
|
|
14
14
|
path: string;
|
|
15
15
|
summary: string;
|
|
16
|
-
}
|
|
16
|
+
};
|
|
17
17
|
export declare function renderPreview(preview: MutationPreview): string;
|
|
18
18
|
export declare function confirmMutation(command: Command, preview: MutationPreview, yes: boolean): Promise<void>;
|
package/dist/lib/confirm.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Flags } from '@oclif/core';
|
|
2
1
|
import { createInterface } from 'node:readline/promises';
|
|
2
|
+
import { Flags } from '@oclif/core';
|
|
3
3
|
export const confirmFlags = {
|
|
4
4
|
yes: Flags.boolean({
|
|
5
5
|
char: 'y',
|
|
@@ -7,22 +7,26 @@ export const confirmFlags = {
|
|
|
7
7
|
}),
|
|
8
8
|
};
|
|
9
9
|
export function decideConfirmation(opts) {
|
|
10
|
-
if (opts.yes)
|
|
10
|
+
if (opts.yes) {
|
|
11
11
|
return 'proceed';
|
|
12
|
-
|
|
12
|
+
}
|
|
13
|
+
if (opts.json || !opts.isTty) {
|
|
13
14
|
return 'refuse';
|
|
15
|
+
}
|
|
14
16
|
return 'ask';
|
|
15
17
|
}
|
|
16
18
|
export function renderPreview(preview) {
|
|
17
19
|
const lines = [preview.summary, `${preview.method} ${preview.path}`];
|
|
18
|
-
if (preview.body !== undefined)
|
|
20
|
+
if (preview.body !== undefined) {
|
|
19
21
|
lines.push(JSON.stringify(preview.body, null, 2));
|
|
22
|
+
}
|
|
20
23
|
return lines.join('\n');
|
|
21
24
|
}
|
|
22
25
|
export async function confirmMutation(command, preview, yes) {
|
|
23
|
-
const decision = decideConfirmation({ isTty: process.stdin.isTTY
|
|
24
|
-
if (decision === 'proceed')
|
|
26
|
+
const decision = decideConfirmation({ isTty: process.stdin.isTTY, json: command.jsonEnabled(), yes });
|
|
27
|
+
if (decision === 'proceed') {
|
|
25
28
|
return;
|
|
29
|
+
}
|
|
26
30
|
if (decision === 'refuse') {
|
|
27
31
|
const reason = `${preview.summary} changes your account. Re-run with --yes to apply it without a prompt.`;
|
|
28
32
|
process.stderr.write(`${reason}\n${renderPreview(preview)}\n`);
|
|
@@ -32,8 +36,9 @@ export async function confirmMutation(command, preview, yes) {
|
|
|
32
36
|
const reader = createInterface({ input: process.stdin, output: process.stderr });
|
|
33
37
|
try {
|
|
34
38
|
const answer = await reader.question('Apply? [y/N] ');
|
|
35
|
-
if (!/^y(es)?$/i.test(answer.trim()))
|
|
39
|
+
if (!/^y(es)?$/i.test(answer.trim())) {
|
|
36
40
|
command.error('Cancelled, nothing was sent.', { exit: 1 });
|
|
41
|
+
}
|
|
37
42
|
}
|
|
38
43
|
finally {
|
|
39
44
|
reader.close();
|