adapty 0.9.2 → 0.9.4

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.
@@ -0,0 +1,102 @@
1
+ import { Command, Flags } from '@oclif/core';
2
+ import { createAsaClient } from '../../../lib/asa-client.js';
3
+ import { asaPaginationFlags, parseDate, periodParams } from '../../../lib/asa-flags.js';
4
+ import { isValidUuid, paginationParams } from '../../../lib/flags.js';
5
+ import { printList } from '../../../lib/output.js';
6
+ const FIELDS_MAX_PAGE_SIZE = 10;
7
+ const MAX_SPAN_DAYS = 14;
8
+ const MS_PER_DAY = 86_400_000;
9
+ export default class AsaChangeHistoryList extends Command {
10
+ static description = 'Apple Ads change history of one organization, read live from Apple (proxied from the Apple Ads Platform API)';
11
+ static enableJsonFlag = true;
12
+ static examples = [
13
+ '<%= config.bin %> asa change-history list --campaign-group <uuid>',
14
+ '<%= config.bin %> asa change-history list --campaign-group <uuid> --date-from 2026-09-01 --entity-type Campaign --event-type UPDATE',
15
+ '<%= config.bin %> asa change-history list --campaign-group <uuid> --fields',
16
+ ];
17
+ static flags = {
18
+ ...asaPaginationFlags,
19
+ 'ad-group': Flags.string({
20
+ description: 'Keep only changes inside these Apple ad group ids (not UUIDs); repeatable',
21
+ multiple: true,
22
+ }),
23
+ 'campaign': Flags.string({
24
+ description: 'Keep only changes inside these Apple campaign ids (not UUIDs); repeatable',
25
+ multiple: true,
26
+ }),
27
+ 'campaign-group': Flags.string({
28
+ description: 'Organization to read (UUID from asa orgs list); one organization per call',
29
+ required: true,
30
+ }),
31
+ 'date-from': Flags.string({
32
+ description: 'Start of the period (YYYY-MM-DD), defaults to 7 days ago; at most 14 days per call, Apple keeps 6 months',
33
+ parse: parseDate,
34
+ }),
35
+ 'date-to': Flags.string({
36
+ description: 'End of the period (YYYY-MM-DD), defaults to today',
37
+ parse: parseDate,
38
+ }),
39
+ 'entity-id': Flags.string({
40
+ description: 'Keep only changes of these Apple entity ids (not UUIDs); repeatable',
41
+ multiple: true,
42
+ }),
43
+ 'entity-type': Flags.string({
44
+ description: 'Keep only changes of this entity type; repeatable. Default is the campaign domain (Campaign, AdGroup, Keyword, NegativeKeyword, Ad, Creative, LocationGroup); Org and AdAccount cannot be mixed with it',
45
+ multiple: true,
46
+ options: ['Ad', 'AdAccount', 'AdGroup', 'Campaign', 'Creative', 'Keyword', 'LocationGroup', 'NegativeKeyword', 'Org'],
47
+ }),
48
+ 'event-type': Flags.string({
49
+ description: 'Keep only this operation; repeatable',
50
+ multiple: true,
51
+ options: ['CREATE', 'DELETE', 'UPDATE'],
52
+ }),
53
+ 'fields': Flags.boolean({
54
+ description: `Expand into flat field-level rows (field, old values, new values); page size defaults to ${FIELDS_MAX_PAGE_SIZE} and may not exceed it`,
55
+ }),
56
+ 'txn': Flags.string({ description: 'Keep only these Apple transaction ids; repeatable', multiple: true }),
57
+ 'user': Flags.string({
58
+ description: 'Keep only changes made by these Apple user ids (not emails); repeatable',
59
+ multiple: true,
60
+ }),
61
+ 'user-type': Flags.string({
62
+ description: 'Keep only changes by this actor category; repeatable',
63
+ multiple: true,
64
+ options: ['APPLE_SUPPORT', 'CUSTOMER', 'CUSTOMER_API'],
65
+ }),
66
+ };
67
+ async run() {
68
+ const { flags } = await this.parse(AsaChangeHistoryList);
69
+ const isPageSizeGiven = this.argv.some(arg => arg === '--page-size' || arg.startsWith('--page-size='));
70
+ if (flags.fields && isPageSizeGiven && flags['page-size'] > FIELDS_MAX_PAGE_SIZE) {
71
+ this.error(`--fields allows --page-size up to ${FIELDS_MAX_PAGE_SIZE}.`, { exit: 2 });
72
+ }
73
+ if (!isValidUuid(flags['campaign-group'])) {
74
+ this.error('Invalid campaign group ID format. Run `adapty asa orgs list` to find it.', { exit: 2 });
75
+ }
76
+ const dateFrom = flags['date-from'];
77
+ const dateTo = flags['date-to'];
78
+ if (dateFrom !== undefined
79
+ && dateTo !== undefined
80
+ && (Date.parse(dateTo) - Date.parse(dateFrom)) / MS_PER_DAY >= MAX_SPAN_DAYS) {
81
+ this.error(`--date-from/--date-to may span at most ${MAX_SPAN_DAYS} days.`, { exit: 2 });
82
+ }
83
+ const client = await createAsaClient(this);
84
+ const result = await client.get('/change-history', {
85
+ ...paginationParams(flags),
86
+ ...(flags.fields && !isPageSizeGiven ? { 'page[size]': String(FIELDS_MAX_PAGE_SIZE) } : {}),
87
+ ...periodParams(flags),
88
+ ad_group_id: flags['ad-group'],
89
+ campaign_group_id: flags['campaign-group'],
90
+ campaign_id: flags.campaign,
91
+ entity_id: flags['entity-id'],
92
+ entity_type: flags['entity-type'],
93
+ event_type: flags['event-type'],
94
+ fields: flags.fields ? 'true' : undefined,
95
+ txn_id: flags.txn,
96
+ user_id: flags.user,
97
+ user_type: flags['user-type'],
98
+ });
99
+ printList(result.data, this.log.bind(this), result.meta.pagination);
100
+ return result;
101
+ }
102
+ }
@@ -0,0 +1 @@
1
+ export { default } from '../../cli/commands/skills/install/index.js';
@@ -0,0 +1,2 @@
1
+ // Implementation lives in the new cli layer; oclif discovers commands only under src/commands.
2
+ export { default } from '../../cli/commands/skills/install/index.js';
@@ -424,3 +424,50 @@ export type AsaCompetitorBrandKeywordPoolDTO = {
424
424
  export type AsaCompetitorBrandKeywordPoolsDTO = {
425
425
  pools: AsaCompetitorBrandKeywordPoolDTO[];
426
426
  };
427
+ export type AsaChangeHistoryEntityRefDTO = {
428
+ detail_id: string;
429
+ entity_id: string;
430
+ entity_name: null | string;
431
+ };
432
+ export type AsaChangeHistoryEventDTO = {
433
+ campaign_group_id: string;
434
+ changes_count: number;
435
+ entities: AsaChangeHistoryEntityRefDTO[];
436
+ entity_type: string;
437
+ event_time: string;
438
+ event_type: string;
439
+ modified_by: null | string;
440
+ transaction_id: string;
441
+ user_type: string;
442
+ };
443
+ export type AsaFieldChangeDTO = {
444
+ field: string;
445
+ new_values: string[];
446
+ old_values: string[];
447
+ };
448
+ export type AsaChangeHistoryDetailDTO = {
449
+ campaign_group_id: string;
450
+ changes: AsaFieldChangeDTO[];
451
+ detail_id: string;
452
+ entity_id: string;
453
+ entity_metadata: Record<string, unknown>;
454
+ entity_type: string;
455
+ event_time: string;
456
+ event_type: string;
457
+ modified_by: null | string;
458
+ user_type: string;
459
+ };
460
+ export type AsaChangeHistoryFieldEventDTO = {
461
+ campaign_group_id: string;
462
+ entity_id: string;
463
+ entity_name: null | string;
464
+ entity_type: string;
465
+ event_time: string;
466
+ event_type: string;
467
+ field: string;
468
+ modified_by: null | string;
469
+ new_values: string[];
470
+ old_values: string[];
471
+ transaction_id: string;
472
+ user_type: string;
473
+ };
@@ -1,5 +1,5 @@
1
1
  export type MigrationState = 'running' | 'action_required' | 'completed' | 'failed' | 'canceled';
2
- export type ActionKind = 'input' | 'upload' | 'external';
2
+ export type ActionKind = 'input' | 'upload' | 'external' | 'agent';
3
3
  export type StepStatus = 'locked' | 'active' | 'done';
4
4
  export type JsonSchema = Record<string, unknown>;
5
5
  export type Envelope<TResult = unknown> = {
@@ -74,6 +74,9 @@ export type Action = ActionBase & ({
74
74
  } | {
75
75
  kind: 'external';
76
76
  href: string;
77
+ } | {
78
+ kind: 'agent';
79
+ input_schema: JsonSchema | null;
77
80
  } | {
78
81
  kind: string;
79
82
  href?: string;