adapty 0.8.4 → 0.8.6

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 (209) hide show
  1. package/README.md +7 -2
  2. package/bin/dev.js +2 -2
  3. package/bin/run.js +2 -2
  4. package/dist/cli/base/adapty/adapty-command.d.ts +21 -0
  5. package/dist/cli/base/adapty/adapty-command.js +47 -0
  6. package/dist/cli/base/adapty/build.d.ts +11 -0
  7. package/dist/cli/base/adapty/build.js +13 -0
  8. package/dist/cli/base/adapty/index.d.ts +5 -0
  9. package/dist/cli/base/adapty/index.js +3 -0
  10. package/dist/cli/base/adapty/openSession.d.ts +22 -0
  11. package/dist/cli/base/adapty/openSession.js +25 -0
  12. package/dist/cli/base/base-command.d.ts +30 -0
  13. package/dist/cli/base/base-command.js +64 -0
  14. package/dist/cli/commands/apps/create.d.ts +19 -0
  15. package/dist/cli/commands/apps/create.js +68 -0
  16. package/dist/cli/commands/apps/get.d.ts +10 -0
  17. package/dist/cli/commands/apps/get.js +14 -0
  18. package/dist/cli/commands/apps/list.d.ts +11 -0
  19. package/dist/cli/commands/apps/list.js +14 -0
  20. package/dist/cli/commands/apps/update.d.ts +15 -0
  21. package/dist/cli/commands/apps/update.js +30 -0
  22. package/dist/cli/commands/auth/login.d.ts +11 -0
  23. package/dist/cli/commands/auth/login.js +68 -0
  24. package/dist/cli/commands/auth/logout.d.ts +12 -0
  25. package/dist/cli/commands/auth/logout.js +28 -0
  26. package/dist/cli/commands/auth/revoke.d.ts +13 -0
  27. package/dist/cli/commands/auth/revoke.js +32 -0
  28. package/dist/cli/commands/auth/status/index.d.ts +7 -0
  29. package/dist/cli/commands/auth/status/index.js +22 -0
  30. package/dist/cli/commands/auth/status/lib/render.d.ts +3 -0
  31. package/dist/cli/commands/auth/status/lib/render.js +14 -0
  32. package/dist/cli/commands/auth/status/lib/result.d.ts +15 -0
  33. package/dist/cli/commands/auth/status/lib/result.js +1 -0
  34. package/dist/cli/commands/auth/whoami.d.ts +10 -0
  35. package/dist/cli/commands/auth/whoami.js +16 -0
  36. package/dist/cli/errors.d.ts +39 -0
  37. package/dist/cli/errors.js +92 -0
  38. package/dist/cli/flags.d.ts +16 -0
  39. package/dist/cli/flags.js +27 -0
  40. package/dist/cli/views/list.d.ts +6 -0
  41. package/dist/cli/views/list.js +10 -0
  42. package/dist/cli/views/record.d.ts +9 -0
  43. package/dist/cli/views/record.js +14 -0
  44. package/dist/commands/access-levels/create.js +1 -1
  45. package/dist/commands/access-levels/list.d.ts +1 -1
  46. package/dist/commands/apps/create.d.ts +1 -14
  47. package/dist/commands/apps/create.js +2 -54
  48. package/dist/commands/apps/get.d.ts +1 -11
  49. package/dist/commands/apps/get.js +2 -22
  50. package/dist/commands/apps/list.d.ts +1 -13
  51. package/dist/commands/apps/list.js +2 -19
  52. package/dist/commands/apps/update.d.ts +1 -16
  53. package/dist/commands/apps/update.js +2 -38
  54. package/dist/commands/asa/ad-groups/create.js +9 -7
  55. package/dist/commands/asa/ad-groups/get.js +3 -2
  56. package/dist/commands/asa/ad-groups/list.d.ts +1 -1
  57. package/dist/commands/asa/ad-groups/list.js +1 -1
  58. package/dist/commands/asa/ad-groups/update.js +22 -12
  59. package/dist/commands/asa/ads/create.js +7 -5
  60. package/dist/commands/asa/ads/get.js +3 -2
  61. package/dist/commands/asa/ads/list.d.ts +1 -1
  62. package/dist/commands/asa/ads/list.js +1 -1
  63. package/dist/commands/asa/ads/update.js +9 -5
  64. package/dist/commands/asa/apps/list.d.ts +1 -1
  65. package/dist/commands/asa/apps/list.js +1 -1
  66. package/dist/commands/asa/automations/create.js +9 -6
  67. package/dist/commands/asa/automations/get.js +3 -2
  68. package/dist/commands/asa/automations/list.d.ts +1 -1
  69. package/dist/commands/asa/automations/list.js +1 -1
  70. package/dist/commands/asa/automations/run.js +5 -3
  71. package/dist/commands/asa/automations/runs.d.ts +1 -1
  72. package/dist/commands/asa/automations/runs.js +4 -4
  73. package/dist/commands/asa/automations/update.js +17 -9
  74. package/dist/commands/asa/campaigns/bulk-create.js +31 -18
  75. package/dist/commands/asa/campaigns/bulk-list.js +7 -5
  76. package/dist/commands/asa/campaigns/bulk-status.js +3 -2
  77. package/dist/commands/asa/campaigns/create.js +10 -8
  78. package/dist/commands/asa/campaigns/get.js +3 -2
  79. package/dist/commands/asa/campaigns/list.d.ts +1 -1
  80. package/dist/commands/asa/campaigns/list.js +1 -1
  81. package/dist/commands/asa/campaigns/update.js +25 -15
  82. package/dist/commands/asa/competitors/summary.js +5 -5
  83. package/dist/commands/asa/connect.js +5 -3
  84. package/dist/commands/asa/creatives/list.d.ts +1 -1
  85. package/dist/commands/asa/creatives/list.js +1 -1
  86. package/dist/commands/asa/keywords/add.js +13 -10
  87. package/dist/commands/asa/keywords/list.d.ts +1 -1
  88. package/dist/commands/asa/keywords/list.js +1 -1
  89. package/dist/commands/asa/keywords/update.js +15 -10
  90. package/dist/commands/asa/metrics/index.d.ts +2 -2
  91. package/dist/commands/asa/metrics/index.js +22 -8
  92. package/dist/commands/asa/metrics/overview.js +3 -3
  93. package/dist/commands/asa/negative-keywords/add.js +10 -7
  94. package/dist/commands/asa/negative-keywords/list.d.ts +1 -1
  95. package/dist/commands/asa/negative-keywords/list.js +1 -1
  96. package/dist/commands/asa/orgs/list.d.ts +1 -1
  97. package/dist/commands/asa/orgs/list.js +1 -1
  98. package/dist/commands/asa/product-pages/list.d.ts +1 -1
  99. package/dist/commands/asa/product-pages/list.js +1 -1
  100. package/dist/commands/asa/product-pages/sync.js +1 -1
  101. package/dist/commands/asa/search-terms/list.d.ts +1 -1
  102. package/dist/commands/asa/search-terms/list.js +1 -1
  103. package/dist/commands/asa/whoami.js +13 -4
  104. package/dist/commands/auth/login.d.ts +1 -8
  105. package/dist/commands/auth/login.js +2 -120
  106. package/dist/commands/auth/logout.d.ts +1 -9
  107. package/dist/commands/auth/logout.js +2 -18
  108. package/dist/commands/auth/revoke.d.ts +1 -9
  109. package/dist/commands/auth/revoke.js +2 -21
  110. package/dist/commands/auth/status.d.ts +1 -7
  111. package/dist/commands/auth/status.js +2 -26
  112. package/dist/commands/auth/whoami.d.ts +1 -7
  113. package/dist/commands/auth/whoami.js +2 -15
  114. package/dist/commands/flows/config/get.js +2 -2
  115. package/dist/commands/flows/config/preview.d.ts +2 -2
  116. package/dist/commands/flows/config/preview.js +6 -4
  117. package/dist/commands/flows/config/update.js +5 -3
  118. package/dist/commands/flows/config/validate.js +5 -3
  119. package/dist/commands/flows/list.d.ts +1 -1
  120. package/dist/commands/flows/media/upload.js +1 -1
  121. package/dist/commands/flows/publish.js +5 -5
  122. package/dist/commands/paywalls/create.js +1 -1
  123. package/dist/commands/paywalls/list.d.ts +1 -1
  124. package/dist/commands/paywalls/placements.d.ts +2 -2
  125. package/dist/commands/paywalls/update.js +1 -1
  126. package/dist/commands/placements/create.js +17 -12
  127. package/dist/commands/placements/list.d.ts +1 -1
  128. package/dist/commands/placements/update.js +20 -15
  129. package/dist/commands/products/create.js +20 -13
  130. package/dist/commands/products/list.d.ts +1 -1
  131. package/dist/commands/products/update.js +1 -1
  132. package/dist/commands/segments/list.d.ts +1 -1
  133. package/dist/lib/api-client.d.ts +10 -6
  134. package/dist/lib/api-client.js +56 -35
  135. package/dist/lib/api-schemas.d.ts +63 -59
  136. package/dist/lib/app-url.js +2 -1
  137. package/dist/lib/asa-client.d.ts +13 -8
  138. package/dist/lib/asa-client.js +9 -4
  139. package/dist/lib/asa-flags.d.ts +19 -19
  140. package/dist/lib/asa-flags.js +38 -25
  141. package/dist/lib/asa-keyword-action.d.ts +10 -10
  142. package/dist/lib/asa-keyword-action.js +40 -25
  143. package/dist/lib/asa-schemas.d.ts +101 -81
  144. package/dist/lib/auth.js +2 -1
  145. package/dist/lib/client-from-config.d.ts +1 -1
  146. package/dist/lib/client-from-config.js +2 -1
  147. package/dist/lib/config.d.ts +2 -2
  148. package/dist/lib/confirm.d.ts +4 -4
  149. package/dist/lib/confirm.js +12 -7
  150. package/dist/lib/errors.d.ts +18 -18
  151. package/dist/lib/errors.js +12 -9
  152. package/dist/lib/flags.d.ts +3 -3
  153. package/dist/lib/flags.js +2 -1
  154. package/dist/lib/flow-help.js +11 -6
  155. package/dist/lib/output.js +23 -12
  156. package/dist/lib/preview.d.ts +5 -5
  157. package/dist/lib/preview.js +2 -1
  158. package/dist/sdk/adapty/access-levels.d.ts +15 -0
  159. package/dist/sdk/adapty/access-levels.js +4 -0
  160. package/dist/sdk/adapty/apps/create.d.ts +26 -0
  161. package/dist/sdk/adapty/apps/create.js +36 -0
  162. package/dist/sdk/adapty/apps/index.d.ts +13 -0
  163. package/dist/sdk/adapty/apps/index.js +9 -0
  164. package/dist/sdk/adapty/apps/model.d.ts +24 -0
  165. package/dist/sdk/adapty/apps/model.js +10 -0
  166. package/dist/sdk/adapty/apps/resource.d.ts +19 -0
  167. package/dist/sdk/adapty/apps/resource.js +23 -0
  168. package/dist/sdk/adapty/apps/update.d.ts +16 -0
  169. package/dist/sdk/adapty/apps/update.js +25 -0
  170. package/dist/sdk/adapty/auth/device-code.d.ts +8 -0
  171. package/dist/sdk/adapty/auth/device-code.js +19 -0
  172. package/dist/sdk/adapty/auth/index.d.ts +7 -0
  173. package/dist/sdk/adapty/auth/index.js +5 -0
  174. package/dist/sdk/adapty/auth/model.d.ts +15 -0
  175. package/dist/sdk/adapty/auth/model.js +6 -0
  176. package/dist/sdk/adapty/auth/poll-token.d.ts +8 -0
  177. package/dist/sdk/adapty/auth/poll-token.js +58 -0
  178. package/dist/sdk/adapty/auth/resource.d.ts +17 -0
  179. package/dist/sdk/adapty/auth/resource.js +21 -0
  180. package/dist/sdk/adapty/errors.d.ts +10 -0
  181. package/dist/sdk/adapty/errors.js +38 -0
  182. package/dist/sdk/adapty/index.d.ts +36 -0
  183. package/dist/sdk/adapty/index.js +27 -0
  184. package/dist/sdk/adapty/pagination.d.ts +23 -0
  185. package/dist/sdk/adapty/pagination.js +1 -0
  186. package/dist/sdk/core/auth/device-flow.d.ts +46 -0
  187. package/dist/sdk/core/auth/device-flow.js +62 -0
  188. package/dist/sdk/core/clock.d.ts +7 -0
  189. package/dist/sdk/core/clock.js +21 -0
  190. package/dist/sdk/core/errors.d.ts +81 -0
  191. package/dist/sdk/core/errors.js +84 -0
  192. package/dist/sdk/core/http/client.d.ts +46 -0
  193. package/dist/sdk/core/http/client.js +127 -0
  194. package/dist/sdk/core/http/index.d.ts +11 -0
  195. package/dist/sdk/core/http/index.js +7 -0
  196. package/dist/sdk/core/http/policies.d.ts +14 -0
  197. package/dist/sdk/core/http/policies.js +29 -0
  198. package/dist/sdk/core/http/retry.d.ts +27 -0
  199. package/dist/sdk/core/http/retry.js +22 -0
  200. package/dist/sdk/core/http/url.d.ts +3 -0
  201. package/dist/sdk/core/http/url.js +19 -0
  202. package/dist/sdk/core/session.d.ts +20 -0
  203. package/dist/sdk/core/session.js +69 -0
  204. package/dist/sdk/core/testing.d.ts +25 -0
  205. package/dist/sdk/core/testing.js +46 -0
  206. package/dist/sdk/core/validation.d.ts +10 -0
  207. package/dist/sdk/core/validation.js +14 -0
  208. package/oclif.manifest.json +766 -766
  209. package/package.json +19 -9
@@ -11,9 +11,10 @@ export default class AsaAdGroupsGet extends Command {
11
11
  static examples = ['<%= config.bin %> asa ad-groups get 550e8400-e29b-41d4-a716-446655440000'];
12
12
  async run() {
13
13
  const { args } = await this.parse(AsaAdGroupsGet);
14
- if (!isValidUuid(args.ad_group_id))
14
+ if (!isValidUuid(args.ad_group_id)) {
15
15
  this.error('Invalid ad group ID format.', { exit: 2 });
16
- const client = await createAsaClient(this.config);
16
+ }
17
+ const client = await createAsaClient(this);
17
18
  const result = await client.get(`/ad-groups/${args.ad_group_id}`);
18
19
  printResponse(result, this.log.bind(this));
19
20
  return result;
@@ -1,6 +1,6 @@
1
1
  import { Command } from '@oclif/core';
2
2
  import type { AsaAdGroupDTO } from '../../../lib/asa-schemas.js';
3
- import { type PaginatedResponse } from '../../../lib/flags.js';
3
+ import type { PaginatedResponse } from '../../../lib/flags.js';
4
4
  export default class AsaAdGroupsList extends Command {
5
5
  static description: string;
6
6
  static enableJsonFlag: boolean;
@@ -13,7 +13,7 @@ export default class AsaAdGroupsList extends Command {
13
13
  static flags = { ...asaPaginationFlags, ...campaignScopeFlags, ...statusFilter(['ENABLED', 'PAUSED']) };
14
14
  async run() {
15
15
  const { flags } = await this.parse(AsaAdGroupsList);
16
- const client = await createAsaClient(this.config);
16
+ const client = await createAsaClient(this);
17
17
  const result = await client.get('/ad-groups', {
18
18
  ...paginationParams(flags),
19
19
  ...scopeParams(flags),
@@ -22,40 +22,50 @@ export default class AsaAdGroupsUpdate extends Command {
22
22
  'automated-keywords': Flags.boolean({ allowNo: true, description: 'Let Apple add keywords automatically' }),
23
23
  'cpa-goal': moneyFlag('CPA goal'),
24
24
  'default-bid': moneyFlag('Default bid'),
25
- name: Flags.string({ description: 'Ad group name' }),
26
- status: Flags.string({ description: 'Ad group status', options: ['ENABLED', 'PAUSED'] }),
25
+ 'name': Flags.string({ description: 'Ad group name' }),
26
+ 'status': Flags.string({ description: 'Ad group status', options: ['ENABLED', 'PAUSED'] }),
27
27
  };
28
28
  async run() {
29
29
  const { args, flags } = await this.parse(AsaAdGroupsUpdate);
30
- if (!isValidUuid(args.ad_group_id))
30
+ if (!isValidUuid(args.ad_group_id)) {
31
31
  this.error('Invalid ad group ID format.', { exit: 2 });
32
+ }
32
33
  const body = {};
33
- if (flags.name !== undefined)
34
+ if (flags.name !== undefined) {
34
35
  body.name = flags.name;
35
- if (flags.status !== undefined)
36
+ }
37
+ if (flags.status !== undefined) {
36
38
  body.status = flags.status;
37
- if (flags['default-bid'] !== undefined)
39
+ }
40
+ if (flags['default-bid'] !== undefined) {
38
41
  body.default_bid_amount = money(flags['default-bid'], flags.currency);
39
- if (flags['cpa-goal'] !== undefined)
42
+ }
43
+ if (flags['cpa-goal'] !== undefined) {
40
44
  body.cpa_goal = money(flags['cpa-goal'], flags.currency);
41
- if (flags['automated-keywords'] !== undefined)
45
+ }
46
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- FIXME if you see this
47
+ if (flags['automated-keywords'] !== undefined) {
42
48
  body.automated_keywords_opt_in = flags['automated-keywords'];
43
- if (flags['start-time'] !== undefined)
49
+ }
50
+ if (flags['start-time'] !== undefined) {
44
51
  body.start_time = startOfDayUtc(flags['start-time']);
45
- if (flags['end-time'] !== undefined)
52
+ }
53
+ if (flags['end-time'] !== undefined) {
46
54
  body.end_time = startOfDayUtc(flags['end-time']);
55
+ }
47
56
  if (Object.keys(body).length === 0) {
48
57
  this.error('Nothing to change. Pass at least one field, e.g. --status PAUSED.', { exit: 2 });
49
58
  }
50
59
  await confirmMutation(this, { body, method: 'PUT', path: `/ad-groups/${args.ad_group_id}/`, summary: 'Update ad group' }, flags.yes);
51
- const client = await createAsaClient(this.config);
60
+ const client = await createAsaClient(this);
52
61
  const { replayed, result } = await asaWrite(client, 'put', `/ad-groups/${args.ad_group_id}`, {
53
62
  body,
54
63
  idempotencyKey: flags['idempotency-key'],
55
64
  });
56
65
  noteReplay(replayed, this.log.bind(this));
57
- if (result.ad_group && !replayed)
66
+ if (result.ad_group && !replayed) {
58
67
  this.log('Ad group updated!');
68
+ }
59
69
  printResponse(result, this.log.bind(this));
60
70
  return result;
61
71
  }
@@ -13,13 +13,14 @@ export default class AsaAdsCreate extends Command {
13
13
  ...idempotencyFlags,
14
14
  'ad-group': Flags.string({ description: 'Ad group ID (UUID) — the campaign is resolved from it', required: true }),
15
15
  'creative-id': Flags.integer({ description: 'Apple creative ID from a product page or the default set', required: true }),
16
- name: Flags.string({ description: 'Ad name', required: true }),
17
- status: Flags.string({ description: 'Initial status', options: ['ENABLED', 'PAUSED'] }),
16
+ 'name': Flags.string({ description: 'Ad name', required: true }),
17
+ 'status': Flags.string({ description: 'Initial status', options: ['ENABLED', 'PAUSED'] }),
18
18
  };
19
19
  async run() {
20
20
  const { flags } = await this.parse(AsaAdsCreate);
21
- if (!isValidUuid(flags['ad-group']))
21
+ if (!isValidUuid(flags['ad-group'])) {
22
22
  this.error('Invalid ad group ID format.', { exit: 2 });
23
+ }
23
24
  const body = {
24
25
  ad_group_id: flags['ad-group'],
25
26
  creative_id: flags['creative-id'],
@@ -27,14 +28,15 @@ export default class AsaAdsCreate extends Command {
27
28
  ...(flags.status === undefined ? {} : { status: flags.status }),
28
29
  };
29
30
  await confirmMutation(this, { body, method: 'POST', path: '/ads/', summary: `Create ad ${flags.name}` }, flags.yes);
30
- const client = await createAsaClient(this.config);
31
+ const client = await createAsaClient(this);
31
32
  const { replayed, result } = await asaWrite(client, 'post', '/ads', {
32
33
  body,
33
34
  idempotencyKey: flags['idempotency-key'],
34
35
  });
35
36
  noteReplay(replayed, this.log.bind(this));
36
- if (result.ad && !replayed)
37
+ if (result.ad && !replayed) {
37
38
  this.log('Ad created!');
39
+ }
38
40
  printResponse(result, this.log.bind(this));
39
41
  return result;
40
42
  }
@@ -11,9 +11,10 @@ export default class AsaAdsGet extends Command {
11
11
  static examples = ['<%= config.bin %> asa ads get 550e8400-e29b-41d4-a716-446655440000'];
12
12
  async run() {
13
13
  const { args } = await this.parse(AsaAdsGet);
14
- if (!isValidUuid(args.ad_id))
14
+ if (!isValidUuid(args.ad_id)) {
15
15
  this.error('Invalid ad ID format.', { exit: 2 });
16
- const client = await createAsaClient(this.config);
16
+ }
17
+ const client = await createAsaClient(this);
17
18
  const result = await client.get(`/ads/${args.ad_id}`);
18
19
  printResponse(result, this.log.bind(this));
19
20
  return result;
@@ -1,6 +1,6 @@
1
1
  import { Command } from '@oclif/core';
2
2
  import type { AsaAdDTO } from '../../../lib/asa-schemas.js';
3
- import { type PaginatedResponse } from '../../../lib/flags.js';
3
+ import type { PaginatedResponse } from '../../../lib/flags.js';
4
4
  export default class AsaAdsList extends Command {
5
5
  static description: string;
6
6
  static enableJsonFlag: boolean;
@@ -13,7 +13,7 @@ export default class AsaAdsList extends Command {
13
13
  static flags = { ...asaPaginationFlags, ...adScopeFlags, ...statusFilter(['ENABLED', 'PAUSED']) };
14
14
  async run() {
15
15
  const { flags } = await this.parse(AsaAdsList);
16
- const client = await createAsaClient(this.config);
16
+ const client = await createAsaClient(this);
17
17
  const result = await client.get('/ads', {
18
18
  ...paginationParams(flags),
19
19
  ...scopeParams(flags),
@@ -19,25 +19,29 @@ export default class AsaAdsUpdate extends Command {
19
19
  };
20
20
  async run() {
21
21
  const { args, flags } = await this.parse(AsaAdsUpdate);
22
- if (!isValidUuid(args.ad_id))
22
+ if (!isValidUuid(args.ad_id)) {
23
23
  this.error('Invalid ad ID format.', { exit: 2 });
24
+ }
24
25
  const body = {};
25
- if (flags.name !== undefined)
26
+ if (flags.name !== undefined) {
26
27
  body.name = flags.name;
27
- if (flags.status !== undefined)
28
+ }
29
+ if (flags.status !== undefined) {
28
30
  body.status = flags.status;
31
+ }
29
32
  if (Object.keys(body).length === 0) {
30
33
  this.error('Nothing to change. Pass --name or --status.', { exit: 2 });
31
34
  }
32
35
  await confirmMutation(this, { body, method: 'PUT', path: `/ads/${args.ad_id}/`, summary: 'Update ad' }, flags.yes);
33
- const client = await createAsaClient(this.config);
36
+ const client = await createAsaClient(this);
34
37
  const { replayed, result } = await asaWrite(client, 'put', `/ads/${args.ad_id}`, {
35
38
  body,
36
39
  idempotencyKey: flags['idempotency-key'],
37
40
  });
38
41
  noteReplay(replayed, this.log.bind(this));
39
- if (result.ad && !replayed)
42
+ if (result.ad && !replayed) {
40
43
  this.log('Ad updated!');
44
+ }
41
45
  printResponse(result, this.log.bind(this));
42
46
  return result;
43
47
  }
@@ -1,6 +1,6 @@
1
1
  import { Command } from '@oclif/core';
2
2
  import type { AsaAppDTO } from '../../../lib/asa-schemas.js';
3
- import { type PaginatedResponse } from '../../../lib/flags.js';
3
+ import type { PaginatedResponse } from '../../../lib/flags.js';
4
4
  export default class AsaAppsList extends Command {
5
5
  static description: string;
6
6
  static enableJsonFlag: boolean;
@@ -10,7 +10,7 @@ export default class AsaAppsList extends Command {
10
10
  static flags = { ...asaPaginationFlags };
11
11
  async run() {
12
12
  const { flags } = await this.parse(AsaAppsList);
13
- const client = await createAsaClient(this.config);
13
+ const client = await createAsaClient(this);
14
14
  const result = await client.get('/apps', paginationParams(flags));
15
15
  printList(result.data, this.log.bind(this), result.meta.pagination);
16
16
  return result;
@@ -1,5 +1,5 @@
1
- import { Command, Flags } from '@oclif/core';
2
1
  import { readFile } from 'node:fs/promises';
2
+ import { Command, Flags } from '@oclif/core';
3
3
  import { asaWrite, createAsaClient, noteReplay } from '../../../lib/asa-client.js';
4
4
  import { addKeywordActionFlags, idempotencyFlags } from '../../../lib/asa-flags.js';
5
5
  import { hasAddKeywordActionFlags, rebuildAddKeywordAction, requireSingleAction, } from '../../../lib/asa-keyword-action.js';
@@ -18,18 +18,19 @@ export default class AsaAutomationsCreate extends Command {
18
18
  ...addKeywordActionFlags,
19
19
  ...confirmFlags,
20
20
  ...idempotencyFlags,
21
- file: Flags.string({ description: 'JSON file with the rule body, or - to read stdin', required: true }),
21
+ 'file': Flags.string({ description: 'JSON file with the rule body, or - to read stdin', required: true }),
22
22
  'run-now': Flags.boolean({ description: 'Queue the first run right after the rule is stored' }),
23
23
  };
24
24
  async run() {
25
25
  const { flags } = await this.parse(AsaAutomationsCreate);
26
26
  const body = await this.readRule(flags.file);
27
- if (flags['run-now'])
27
+ if (flags['run-now']) {
28
28
  body.run_immediately = true;
29
+ }
29
30
  this.applyActionFlags(body, flags);
30
31
  const summary = flags['run-now'] ? 'Create automation rule and run it immediately' : 'Create automation rule';
31
32
  await confirmMutation(this, { body, method: 'POST', path: '/automations/', summary }, flags.yes);
32
- const client = await createAsaClient(this.config);
33
+ const client = await createAsaClient(this);
33
34
  const { replayed, result } = await asaWrite(client, 'post', '/automations', {
34
35
  body,
35
36
  idempotencyKey: flags['idempotency-key'],
@@ -44,8 +45,9 @@ export default class AsaAutomationsCreate extends Command {
44
45
  applyActionFlags(body, flags) {
45
46
  try {
46
47
  requireSingleAction(body.actions);
47
- if (!hasAddKeywordActionFlags(flags))
48
+ if (!hasAddKeywordActionFlags(flags)) {
48
49
  return;
50
+ }
49
51
  body.actions = rebuildAddKeywordAction(body.actions, body.operate_with, flags);
50
52
  }
51
53
  catch (error) {
@@ -69,8 +71,9 @@ export default class AsaAutomationsCreate extends Command {
69
71
  }
70
72
  async readStdin() {
71
73
  const chunks = [];
72
- for await (const chunk of process.stdin)
74
+ for await (const chunk of process.stdin) {
73
75
  chunks.push(chunk);
76
+ }
74
77
  return Buffer.concat(chunks).toString('utf8');
75
78
  }
76
79
  }
@@ -11,9 +11,10 @@ export default class AsaAutomationsGet extends Command {
11
11
  static examples = ['<%= config.bin %> asa automations get 550e8400-e29b-41d4-a716-446655440000'];
12
12
  async run() {
13
13
  const { args } = await this.parse(AsaAutomationsGet);
14
- if (!isValidUuid(args.automation_id))
14
+ if (!isValidUuid(args.automation_id)) {
15
15
  this.error('Invalid automation ID format.', { exit: 2 });
16
- const client = await createAsaClient(this.config);
16
+ }
17
+ const client = await createAsaClient(this);
17
18
  const result = await client.get(`/automations/${args.automation_id}`);
18
19
  printResponse(result, this.log.bind(this));
19
20
  return result;
@@ -1,6 +1,6 @@
1
1
  import { Command } from '@oclif/core';
2
2
  import type { AsaAutomationDTO } from '../../../lib/asa-schemas.js';
3
- import { type PaginatedResponse } from '../../../lib/flags.js';
3
+ import type { PaginatedResponse } from '../../../lib/flags.js';
4
4
  export default class AsaAutomationsList extends Command {
5
5
  static description: string;
6
6
  static enableJsonFlag: boolean;
@@ -10,7 +10,7 @@ export default class AsaAutomationsList extends Command {
10
10
  static flags = { ...asaPaginationFlags };
11
11
  async run() {
12
12
  const { flags } = await this.parse(AsaAutomationsList);
13
- const client = await createAsaClient(this.config);
13
+ const client = await createAsaClient(this);
14
14
  const result = await client.get('/automations', paginationParams(flags));
15
15
  printList(result.data, this.log.bind(this), result.meta.pagination);
16
16
  return result;
@@ -20,8 +20,9 @@ export default class AsaAutomationsRun extends Command {
20
20
  };
21
21
  async run() {
22
22
  const { args, flags } = await this.parse(AsaAutomationsRun);
23
- if (!isValidUuid(args.automation_id))
23
+ if (!isValidUuid(args.automation_id)) {
24
24
  this.error('Invalid automation ID format.', { exit: 2 });
25
+ }
25
26
  if (!flags['dry-run']) {
26
27
  await confirmMutation(this, {
27
28
  method: 'POST',
@@ -29,11 +30,12 @@ export default class AsaAutomationsRun extends Command {
29
30
  summary: 'Run the rule for real — it applies its actions to Apple',
30
31
  }, flags.yes);
31
32
  }
32
- const client = await createAsaClient(this.config);
33
+ const client = await createAsaClient(this);
33
34
  const { replayed, result } = await asaWrite(client, 'post', `/automations/${args.automation_id}/run`, { idempotencyKey: flags['idempotency-key'], params: flags['dry-run'] ? { dry_run: 'true' } : undefined });
34
35
  noteReplay(replayed, this.log.bind(this));
35
- if (!replayed)
36
+ if (!replayed) {
36
37
  this.log(flags['dry-run'] ? 'Dry run queued.' : 'Run queued.');
38
+ }
37
39
  this.log(`Run ID: ${result.run_id ?? 'unknown'}`);
38
40
  this.log(`Follow it with: ${this.config.bin} asa automations runs ${args.automation_id}`);
39
41
  return result;
@@ -1,6 +1,6 @@
1
1
  import { Command } from '@oclif/core';
2
2
  import type { AsaAutomationRunDTO } from '../../../lib/asa-schemas.js';
3
- import { type PaginatedResponse } from '../../../lib/flags.js';
3
+ import type { PaginatedResponse } from '../../../lib/flags.js';
4
4
  export default class AsaAutomationsRuns extends Command {
5
5
  static args: {
6
6
  automation_id: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
@@ -1,8 +1,7 @@
1
1
  import { Args, Command } from '@oclif/core';
2
2
  import { createAsaClient } from '../../../lib/asa-client.js';
3
3
  import { asaPaginationFlags } from '../../../lib/asa-flags.js';
4
- import { isValidUuid } from '../../../lib/flags.js';
5
- import { paginationParams } from '../../../lib/flags.js';
4
+ import { isValidUuid, paginationParams } from '../../../lib/flags.js';
6
5
  import { printList } from '../../../lib/output.js';
7
6
  export default class AsaAutomationsRuns extends Command {
8
7
  static args = {
@@ -14,9 +13,10 @@ export default class AsaAutomationsRuns extends Command {
14
13
  static flags = { ...asaPaginationFlags };
15
14
  async run() {
16
15
  const { args, flags } = await this.parse(AsaAutomationsRuns);
17
- if (!isValidUuid(args.automation_id))
16
+ if (!isValidUuid(args.automation_id)) {
18
17
  this.error('Invalid automation ID format.', { exit: 2 });
19
- const client = await createAsaClient(this.config);
18
+ }
19
+ const client = await createAsaClient(this);
20
20
  const result = await client.get(`/automations/${args.automation_id}/runs`, paginationParams(flags));
21
21
  printList(result.data, this.log.bind(this), result.meta.pagination);
22
22
  return result;
@@ -1,5 +1,5 @@
1
- import { Args, Command, Flags } from '@oclif/core';
2
1
  import { readFile } from 'node:fs/promises';
2
+ import { Args, Command, Flags } from '@oclif/core';
3
3
  import { asaWrite, createAsaClient, noteReplay } from '../../../lib/asa-client.js';
4
4
  import { addKeywordActionFlags, idempotencyFlags } from '../../../lib/asa-flags.js';
5
5
  import { hasAddKeywordActionFlags, rebuildAddKeywordAction, } from '../../../lib/asa-keyword-action.js';
@@ -28,15 +28,19 @@ export default class AsaAutomationsUpdate extends Command {
28
28
  };
29
29
  async run() {
30
30
  const { args, flags } = await this.parse(AsaAutomationsUpdate);
31
- if (!isValidUuid(args.automation_id))
31
+ if (!isValidUuid(args.automation_id)) {
32
32
  this.error('Invalid automation ID format.', { exit: 2 });
33
+ }
33
34
  const body = flags.file ? await this.readRule(flags.file) : {};
34
- if (flags.name !== undefined)
35
+ if (flags.name !== undefined) {
35
36
  body.name = flags.name;
36
- if (flags.start)
37
+ }
38
+ if (flags.start) {
37
39
  body.status = 1;
38
- if (flags.stop)
40
+ }
41
+ if (flags.stop) {
39
42
  body.status = 0;
43
+ }
40
44
  const actionFlags = hasAddKeywordActionFlags(flags);
41
45
  if (Object.keys(body).length === 0 && !actionFlags) {
42
46
  this.error('Nothing to change. Pass --stop, --start, --name, --file or an action flag.', { exit: 2 });
@@ -44,14 +48,16 @@ export default class AsaAutomationsUpdate extends Command {
44
48
  if ('internal_id' in body) {
45
49
  this.error('Remove internal_id from the file: the rule ID comes from the command line.', { exit: 2 });
46
50
  }
47
- const client = await createAsaClient(this.config);
48
- if (actionFlags)
51
+ const client = await createAsaClient(this);
52
+ if (actionFlags) {
49
53
  await this.rebuildAction(client, args.automation_id, body, flags);
54
+ }
50
55
  await confirmMutation(this, { body, method: 'PUT', path: `/automations/${args.automation_id}/`, summary: 'Update automation rule' }, flags.yes);
51
56
  const { replayed, result } = await asaWrite(client, 'put', `/automations/${args.automation_id}`, { body, idempotencyKey: flags['idempotency-key'] });
52
57
  noteReplay(replayed, this.log.bind(this));
53
- if (result.automation && !replayed)
58
+ if (result.automation && !replayed) {
54
59
  this.log('Automation updated!');
60
+ }
55
61
  printResponse(result, this.log.bind(this));
56
62
  return result;
57
63
  }
@@ -72,14 +78,16 @@ export default class AsaAutomationsUpdate extends Command {
72
78
  }
73
79
  async readStdin() {
74
80
  const chunks = [];
75
- for await (const chunk of process.stdin)
81
+ for await (const chunk of process.stdin) {
76
82
  chunks.push(chunk);
83
+ }
77
84
  return Buffer.concat(chunks).toString('utf8');
78
85
  }
79
86
  // Read-modify-write: the API replaces `actions` wholesale, so the whole list has to be sent back.
80
87
  async rebuildAction(client, automationId, body, flags) {
81
88
  const rule = await client.get(`/automations/${automationId}`);
82
89
  try {
90
+ // eslint-disable-next-line @stylistic/max-len -- FIXME if you see this
83
91
  body.actions = rebuildAddKeywordAction(body.actions ?? rule.actions, body.operate_with ?? rule.operate_with, flags);
84
92
  }
85
93
  catch (error) {
@@ -1,6 +1,6 @@
1
- import { Command, Flags } from '@oclif/core';
2
1
  import { readFile } from 'node:fs/promises';
3
2
  import { basename } from 'node:path';
3
+ import { Command, Flags } from '@oclif/core';
4
4
  import { asaWrite, createAsaClient, noteReplay } from '../../../lib/asa-client.js';
5
5
  import { idempotencyFlags } from '../../../lib/asa-flags.js';
6
6
  import { confirmFlags, confirmMutation } from '../../../lib/confirm.js';
@@ -18,7 +18,7 @@ export default class AsaCampaignsBulkCreate extends Command {
18
18
  static flags = {
19
19
  ...confirmFlags,
20
20
  ...idempotencyFlags,
21
- file: Flags.string({
21
+ 'file': Flags.string({
22
22
  description: 'JSON file with the campaign structure (the POST /bulk-operations/ body); use "-" for stdin',
23
23
  exactlyOne: ['file', 'from-file'],
24
24
  }),
@@ -29,11 +29,11 @@ export default class AsaCampaignsBulkCreate extends Command {
29
29
  description: 'Apple org id (campaign_group_id) the converted template will target; required with --from-file',
30
30
  }),
31
31
  'poll-interval': Flags.integer({ default: 5, description: 'Seconds between progress polls' }),
32
- preview: Flags.boolean({
32
+ 'preview': Flags.boolean({
33
33
  description: 'With --from-file: print the converted request and stop, nothing is created',
34
34
  }),
35
- timeout: Flags.integer({ default: 900, description: 'Max seconds to wait for the operation to finish' }),
36
- wait: Flags.boolean({
35
+ 'timeout': Flags.integer({ default: 900, description: 'Max seconds to wait for the operation to finish' }),
36
+ 'wait': Flags.boolean({
37
37
  allowNo: true,
38
38
  default: true,
39
39
  description: 'Poll the operation until it finishes; --no-wait returns the operation id immediately',
@@ -41,15 +41,16 @@ export default class AsaCampaignsBulkCreate extends Command {
41
41
  };
42
42
  async run() {
43
43
  const { flags } = await this.parse(AsaCampaignsBulkCreate);
44
- const client = await createAsaClient(this.config);
44
+ const client = await createAsaClient(this);
45
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- FIXME if you see this
45
46
  const body = flags['from-file'] ? await this.convertTemplate(client, flags) : await this.readStructure(flags.file);
46
47
  if (flags.preview) {
47
48
  this.log(JSON.stringify(body, null, 2));
48
49
  return body;
49
50
  }
50
51
  const counts = this.countStructure(body);
51
- const summary = `Bulk-create: ${counts.campaigns} campaign node(s), ${counts.adGroups} ad group(s), ` +
52
- `${counts.keywords} keyword(s), ${counts.negativeKeywords} negative keyword(s), ${counts.ads} ad(s)`;
52
+ const summary = `Bulk-create: ${counts.campaigns} campaign node(s), ${counts.adGroups} ad group(s), `
53
+ + `${counts.keywords} keyword(s), ${counts.negativeKeywords} negative keyword(s), ${counts.ads} ad(s)`;
53
54
  await confirmMutation(this, { body, method: 'POST', path: '/bulk-operations/', summary }, flags.yes);
54
55
  const { replayed, result } = await asaWrite(client, 'post', '/bulk-operations', {
55
56
  body,
@@ -66,8 +67,10 @@ export default class AsaCampaignsBulkCreate extends Command {
66
67
  return state;
67
68
  }
68
69
  async convertTemplate(client, flags) {
69
- if (flags['org-id'] === undefined)
70
+ if (flags['org-id'] === undefined) {
70
71
  this.error('--org-id is required with --from-file.', { exit: 2 });
72
+ }
73
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- FIXME if you see this
71
74
  const path = flags['from-file'];
72
75
  let content;
73
76
  try {
@@ -80,11 +83,13 @@ export default class AsaCampaignsBulkCreate extends Command {
80
83
  form.append('file', new Blob([new Uint8Array(content)]), basename(path));
81
84
  form.append('campaign_group_id', String(flags['org-id']));
82
85
  const result = await client.postForm('/bulk-operations/convert', form);
83
- for (const warning of result.warnings)
86
+ for (const warning of result.warnings) {
84
87
  this.warn(this.formatIssue(warning));
88
+ }
85
89
  if (result.errors.length > 0 || result.request === null) {
86
- for (const issue of result.errors)
90
+ for (const issue of result.errors) {
87
91
  this.log(this.formatIssue(issue));
92
+ }
88
93
  this.error(`Template conversion failed with ${result.errors.length} error(s); nothing was created.`, { exit: 2 });
89
94
  }
90
95
  return result.request;
@@ -94,17 +99,21 @@ export default class AsaCampaignsBulkCreate extends Command {
94
99
  const campaigns = Array.isArray(body.campaigns) ? body.campaigns : [];
95
100
  counts.campaigns = campaigns.length;
96
101
  for (const campaign of campaigns) {
97
- if (typeof campaign !== 'object' || campaign === null)
102
+ if (typeof campaign !== 'object' || campaign === null) {
98
103
  continue;
104
+ }
99
105
  const campaignNode = campaign;
106
+ // eslint-disable-next-line @stylistic/max-len -- FIXME if you see this
100
107
  counts.negativeKeywords += Array.isArray(campaignNode.negative_keywords) ? campaignNode.negative_keywords.length : 0;
101
108
  const adGroups = Array.isArray(campaignNode.ad_groups) ? campaignNode.ad_groups : [];
102
109
  counts.adGroups += adGroups.length;
103
110
  for (const adGroup of adGroups) {
104
- if (typeof adGroup !== 'object' || adGroup === null)
111
+ if (typeof adGroup !== 'object' || adGroup === null) {
105
112
  continue;
113
+ }
106
114
  const adGroupNode = adGroup;
107
115
  counts.keywords += Array.isArray(adGroupNode.keywords) ? adGroupNode.keywords.length : 0;
116
+ // eslint-disable-next-line @stylistic/max-len -- FIXME if you see this
108
117
  counts.negativeKeywords += Array.isArray(adGroupNode.negative_keywords) ? adGroupNode.negative_keywords.length : 0;
109
118
  counts.ads += Array.isArray(adGroupNode.ads) ? adGroupNode.ads.length : 0;
110
119
  }
@@ -121,8 +130,9 @@ export default class AsaCampaignsBulkCreate extends Command {
121
130
  let raw;
122
131
  if (source === '-') {
123
132
  const chunks = [];
124
- for await (const chunk of process.stdin)
133
+ for await (const chunk of process.stdin) {
125
134
  chunks.push(chunk);
135
+ }
126
136
  raw = Buffer.concat(chunks).toString('utf8');
127
137
  }
128
138
  else {
@@ -143,15 +153,17 @@ export default class AsaCampaignsBulkCreate extends Command {
143
153
  report(state) {
144
154
  const { counts } = state;
145
155
  this.log(`Finished: ${state.status} — ${counts.applied}/${counts.total} applied, ${counts.failed} failed`);
146
- const failedObjects = state.objects.filter((object) => object.status === 'failed');
156
+ const failedObjects = state.objects.filter(object => object.status === 'failed');
147
157
  for (const object of failedObjects) {
148
158
  printResponse(object, this.log.bind(this));
149
159
  this.log('---');
150
160
  }
151
- if (state.status === 'failed')
161
+ if (state.status === 'failed') {
152
162
  this.error('Bulk operation failed.', { exit: 1 });
153
- if (state.status === 'partial')
163
+ }
164
+ if (state.status === 'partial') {
154
165
  this.warn('Some objects were not created — see the failures above.');
166
+ }
155
167
  }
156
168
  async waitForCompletion(client, operationId, pollIntervalSeconds, timeoutSeconds) {
157
169
  const startedAt = Date.now();
@@ -163,8 +175,9 @@ export default class AsaCampaignsBulkCreate extends Command {
163
175
  this.log(progress);
164
176
  lastProgress = progress;
165
177
  }
166
- if (TERMINAL_STATUSES.has(state.status))
178
+ if (TERMINAL_STATUSES.has(state.status)) {
167
179
  return state;
180
+ }
168
181
  if ((Date.now() - startedAt) / 1000 >= timeoutSeconds) {
169
182
  this.warn(`Still ${state.status} after ${timeoutSeconds}s — check later with: adapty asa campaigns bulk-status ${operationId}`);
170
183
  return state;
@@ -3,13 +3,15 @@ import { createAsaClient } from '../../../lib/asa-client.js';
3
3
  import { asaPaginationFlags, parseDate } from '../../../lib/asa-flags.js';
4
4
  import { isValidUuid, paginationParams } from '../../../lib/flags.js';
5
5
  import { printList } from '../../../lib/output.js';
6
+ // eslint-disable-next-line @typescript-eslint/require-await -- FIXME if you see this
6
7
  async function parseAppId(input) {
7
- if (!isValidUuid(input))
8
+ if (!isValidUuid(input)) {
8
9
  throw new Error('Invalid app ID format. Run `adapty asa apps list` to find your app ID.');
10
+ }
9
11
  return input;
10
12
  }
11
13
  export default class AsaCampaignsBulkList extends Command {
12
- static description = "This company's bulk operations, newest first; inspect one with bulk-status";
14
+ static description = 'This company\'s bulk operations, newest first; inspect one with bulk-status';
13
15
  static enableJsonFlag = true;
14
16
  static examples = [
15
17
  '<%= config.bin %> asa campaigns bulk-list',
@@ -18,7 +20,7 @@ export default class AsaCampaignsBulkList extends Command {
18
20
  ];
19
21
  static flags = {
20
22
  ...asaPaginationFlags,
21
- app: Flags.string({ description: 'Keep only operations of this app (UUID)', parse: parseAppId }),
23
+ 'app': Flags.string({ description: 'Keep only operations of this app (UUID)', parse: parseAppId }),
22
24
  'created-from': Flags.string({
23
25
  description: 'Keep only operations created on or after this date (YYYY-MM-DD)',
24
26
  parse: parseDate,
@@ -27,7 +29,7 @@ export default class AsaCampaignsBulkList extends Command {
27
29
  description: 'Keep only operations created on or before this date (YYYY-MM-DD)',
28
30
  parse: parseDate,
29
31
  }),
30
- status: Flags.string({
32
+ 'status': Flags.string({
31
33
  description: 'Keep only operations in this state; repeatable',
32
34
  multiple: true,
33
35
  options: ['failed', 'partial', 'pending', 'running', 'success'],
@@ -35,7 +37,7 @@ export default class AsaCampaignsBulkList extends Command {
35
37
  };
36
38
  async run() {
37
39
  const { flags } = await this.parse(AsaCampaignsBulkList);
38
- const client = await createAsaClient(this.config);
40
+ const client = await createAsaClient(this);
39
41
  const result = await client.get('/bulk-operations', {
40
42
  ...paginationParams(flags),
41
43
  app_id: flags.app,
@@ -16,9 +16,10 @@ export default class AsaCampaignsBulkStatus extends Command {
16
16
  async run() {
17
17
  const { args, flags } = await this.parse(AsaCampaignsBulkStatus);
18
18
  const operationId = args['operation-id'];
19
- if (!isValidUuid(operationId))
19
+ if (!isValidUuid(operationId)) {
20
20
  this.error('Invalid operation ID format.', { exit: 2 });
21
- const client = await createAsaClient(this.config);
21
+ }
22
+ const client = await createAsaClient(this);
22
23
  const state = await client.get(`/bulk-operations/${operationId}`, paginationParams(flags));
23
24
  printResponse(state, this.log.bind(this));
24
25
  return state;