@automate.ax/integration-contracts 0.139.2 → 0.142.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 (50) hide show
  1. package/dist/clickup/api.d.ts +76 -0
  2. package/dist/clickup/api.js +195 -0
  3. package/dist/clickup/index.d.ts +1921 -0
  4. package/dist/clickup/index.js +91 -0
  5. package/dist/clickup/schemas.d.ts +477 -0
  6. package/dist/clickup/schemas.js +286 -0
  7. package/dist/closebot/api.d.ts +39 -0
  8. package/dist/closebot/api.js +117 -0
  9. package/dist/closebot/index.d.ts +2 -0
  10. package/dist/closebot/index.js +2 -0
  11. package/dist/closebot/schemas.d.ts +775 -0
  12. package/dist/closebot/schemas.js +469 -0
  13. package/dist/google-ads/api.d.ts +40 -0
  14. package/dist/google-ads/api.js +109 -0
  15. package/dist/google-ads/events.d.ts +1155 -0
  16. package/dist/google-ads/events.js +96 -0
  17. package/dist/google-ads/index.d.ts +3 -0
  18. package/dist/google-ads/index.js +3 -0
  19. package/dist/google-ads/schemas.d.ts +756 -0
  20. package/dist/google-ads/schemas.js +249 -0
  21. package/dist/google-drive/index.d.ts +6 -6
  22. package/dist/linear/schemas.d.ts +3 -3
  23. package/dist/meta-ads/api.d.ts +90 -0
  24. package/dist/meta-ads/api.js +260 -0
  25. package/dist/meta-ads/events.d.ts +391 -0
  26. package/dist/meta-ads/events.js +193 -0
  27. package/dist/meta-ads/index.d.ts +3 -0
  28. package/dist/meta-ads/index.js +3 -0
  29. package/dist/meta-ads/schemas.d.ts +184 -0
  30. package/dist/meta-ads/schemas.js +181 -0
  31. package/dist/notion/schemas.d.ts +84 -84
  32. package/dist/teams/index.d.ts +20 -20
  33. package/dist/teams/schemas.d.ts +5 -5
  34. package/dist/triggers.d.ts +4 -1
  35. package/package.json +27 -3
  36. package/src/clickup/api.ts +270 -0
  37. package/src/clickup/index.ts +108 -0
  38. package/src/clickup/schemas.ts +324 -0
  39. package/src/closebot/api.ts +157 -0
  40. package/src/closebot/index.ts +2 -0
  41. package/src/closebot/schemas.ts +521 -0
  42. package/src/google-ads/api.ts +151 -0
  43. package/src/google-ads/events.ts +131 -0
  44. package/src/google-ads/index.ts +3 -0
  45. package/src/google-ads/schemas.ts +270 -0
  46. package/src/meta-ads/api.ts +327 -0
  47. package/src/meta-ads/events.ts +218 -0
  48. package/src/meta-ads/index.ts +3 -0
  49. package/src/meta-ads/schemas.ts +206 -0
  50. package/src/triggers.ts +6 -0
@@ -0,0 +1,249 @@
1
+ import * as z from "zod";
2
+ import { GOOGLE_ADS_CUSTOMER_ID_SCHEMA } from "./api.js";
3
+ const DECIMAL_STRING_SCHEMA = z.string().regex(/^\d+$/);
4
+ const GOOGLE_ADS_STATUS_SCHEMA = z.enum([
5
+ "UNSPECIFIED",
6
+ "UNKNOWN",
7
+ "ENABLED",
8
+ "PAUSED",
9
+ "REMOVED",
10
+ ]);
11
+ export const GOOGLE_ADS_CUSTOMER_SCHEMA = z
12
+ .object({
13
+ autoTaggingEnabled: z.boolean().optional(),
14
+ currencyCode: z.string().optional(),
15
+ descriptiveName: z.string().optional(),
16
+ id: DECIMAL_STRING_SCHEMA.optional(),
17
+ manager: z.boolean().optional(),
18
+ resourceName: z.string(),
19
+ testAccount: z.boolean().optional(),
20
+ timeZone: z.string().optional(),
21
+ })
22
+ .catchall(z.json());
23
+ export const GOOGLE_ADS_CUSTOMER_CLIENT_SCHEMA = z
24
+ .object({
25
+ clientCustomer: z.string(),
26
+ currencyCode: z.string().optional(),
27
+ descriptiveName: z.string().optional(),
28
+ hidden: z.boolean().optional(),
29
+ id: DECIMAL_STRING_SCHEMA.optional(),
30
+ level: z.string().optional(),
31
+ manager: z.boolean().optional(),
32
+ resourceName: z.string(),
33
+ testAccount: z.boolean().optional(),
34
+ timeZone: z.string().optional(),
35
+ })
36
+ .catchall(z.json());
37
+ export const GOOGLE_ADS_CAMPAIGN_SCHEMA = z
38
+ .object({
39
+ advertisingChannelSubType: z.string().optional(),
40
+ advertisingChannelType: z.string().optional(),
41
+ campaignBudget: z.string().optional(),
42
+ endDateTime: z.string().optional(),
43
+ id: DECIMAL_STRING_SCHEMA.optional(),
44
+ name: z.string().optional(),
45
+ resourceName: z.string(),
46
+ servingStatus: z.string().optional(),
47
+ startDateTime: z.string().optional(),
48
+ status: GOOGLE_ADS_STATUS_SCHEMA.optional(),
49
+ })
50
+ .catchall(z.json());
51
+ export const GOOGLE_ADS_CAMPAIGN_BUDGET_SCHEMA = z
52
+ .object({
53
+ amountMicros: DECIMAL_STRING_SCHEMA.optional(),
54
+ deliveryMethod: z.string().optional(),
55
+ explicitlyShared: z.boolean().optional(),
56
+ id: DECIMAL_STRING_SCHEMA.optional(),
57
+ name: z.string().optional(),
58
+ resourceName: z.string(),
59
+ status: z.string().optional(),
60
+ totalAmountMicros: DECIMAL_STRING_SCHEMA.optional(),
61
+ })
62
+ .catchall(z.json());
63
+ export const GOOGLE_ADS_AD_GROUP_SCHEMA = z
64
+ .object({
65
+ campaign: z.string().optional(),
66
+ cpcBidMicros: DECIMAL_STRING_SCHEMA.optional(),
67
+ id: DECIMAL_STRING_SCHEMA.optional(),
68
+ name: z.string().optional(),
69
+ resourceName: z.string(),
70
+ status: GOOGLE_ADS_STATUS_SCHEMA.optional(),
71
+ targetCpaMicros: DECIMAL_STRING_SCHEMA.optional(),
72
+ type: z.string().optional(),
73
+ })
74
+ .catchall(z.json());
75
+ export const GOOGLE_ADS_AD_SCHEMA = z
76
+ .object({
77
+ finalUrls: z.string().array().optional(),
78
+ id: DECIMAL_STRING_SCHEMA.optional(),
79
+ name: z.string().optional(),
80
+ resourceName: z.string(),
81
+ responsiveSearchAd: z
82
+ .object({
83
+ descriptions: z
84
+ .object({ text: z.string() })
85
+ .catchall(z.json())
86
+ .array()
87
+ .optional(),
88
+ headlines: z
89
+ .object({ text: z.string() })
90
+ .catchall(z.json())
91
+ .array()
92
+ .optional(),
93
+ path1: z.string().optional(),
94
+ path2: z.string().optional(),
95
+ })
96
+ .catchall(z.json())
97
+ .optional(),
98
+ type: z.string().optional(),
99
+ })
100
+ .catchall(z.json());
101
+ export const GOOGLE_ADS_AD_GROUP_AD_SCHEMA = z
102
+ .object({
103
+ ad: GOOGLE_ADS_AD_SCHEMA.optional(),
104
+ adGroup: z.string().optional(),
105
+ policySummary: z.record(z.string(), z.json()).optional(),
106
+ resourceName: z.string(),
107
+ status: GOOGLE_ADS_STATUS_SCHEMA.optional(),
108
+ })
109
+ .catchall(z.json());
110
+ export const GOOGLE_ADS_ASSET_SCHEMA = z
111
+ .object({
112
+ id: DECIMAL_STRING_SCHEMA.optional(),
113
+ name: z.string().optional(),
114
+ resourceName: z.string(),
115
+ type: z.string().optional(),
116
+ })
117
+ .catchall(z.json());
118
+ export const GOOGLE_ADS_CONVERSION_ACTION_SCHEMA = z
119
+ .object({
120
+ category: z.string().optional(),
121
+ clickThroughLookbackWindowDays: z.string().optional(),
122
+ countingType: z.string().optional(),
123
+ id: DECIMAL_STRING_SCHEMA.optional(),
124
+ name: z.string().optional(),
125
+ primaryForGoal: z.boolean().optional(),
126
+ resourceName: z.string(),
127
+ status: z
128
+ .enum(["UNSPECIFIED", "UNKNOWN", "ENABLED", "REMOVED", "HIDDEN"])
129
+ .optional(),
130
+ type: z.string().optional(),
131
+ valueSettings: z
132
+ .object({
133
+ alwaysUseDefaultValue: z.boolean().optional(),
134
+ defaultCurrencyCode: z.string().optional(),
135
+ defaultValue: z.number().optional(),
136
+ })
137
+ .catchall(z.json())
138
+ .optional(),
139
+ })
140
+ .catchall(z.json());
141
+ export const GOOGLE_ADS_AUDIENCE_SCHEMA = z
142
+ .object({
143
+ description: z.string().optional(),
144
+ dimensions: z.json().array().optional(),
145
+ id: DECIMAL_STRING_SCHEMA.optional(),
146
+ name: z.string().optional(),
147
+ resourceName: z.string(),
148
+ status: GOOGLE_ADS_STATUS_SCHEMA.optional(),
149
+ })
150
+ .catchall(z.json());
151
+ export const GOOGLE_ADS_USER_LIST_SCHEMA = z
152
+ .object({
153
+ description: z.string().optional(),
154
+ id: DECIMAL_STRING_SCHEMA.optional(),
155
+ membershipLifeSpan: z.string().optional(),
156
+ membershipStatus: z.string().optional(),
157
+ name: z.string().optional(),
158
+ resourceName: z.string(),
159
+ sizeForDisplay: DECIMAL_STRING_SCHEMA.optional(),
160
+ sizeForSearch: DECIMAL_STRING_SCHEMA.optional(),
161
+ type: z.string().optional(),
162
+ })
163
+ .catchall(z.json());
164
+ export const GOOGLE_ADS_SEARCH_ROW_SCHEMA = z
165
+ .object({
166
+ adGroup: GOOGLE_ADS_AD_GROUP_SCHEMA.optional(),
167
+ adGroupAd: GOOGLE_ADS_AD_GROUP_AD_SCHEMA.optional(),
168
+ asset: GOOGLE_ADS_ASSET_SCHEMA.optional(),
169
+ audience: GOOGLE_ADS_AUDIENCE_SCHEMA.optional(),
170
+ campaign: GOOGLE_ADS_CAMPAIGN_SCHEMA.optional(),
171
+ campaignBudget: GOOGLE_ADS_CAMPAIGN_BUDGET_SCHEMA.optional(),
172
+ conversionAction: GOOGLE_ADS_CONVERSION_ACTION_SCHEMA.optional(),
173
+ customer: GOOGLE_ADS_CUSTOMER_SCHEMA.optional(),
174
+ customerClient: GOOGLE_ADS_CUSTOMER_CLIENT_SCHEMA.optional(),
175
+ metrics: z.record(z.string(), z.json()).optional(),
176
+ segments: z.record(z.string(), z.json()).optional(),
177
+ userList: GOOGLE_ADS_USER_LIST_SCHEMA.optional(),
178
+ })
179
+ .catchall(z.json());
180
+ export const GOOGLE_ADS_SEARCH_PAGE_SCHEMA = z.object({
181
+ fieldMask: z.string().optional(),
182
+ nextPageToken: z.string().optional(),
183
+ queryResourceConsumption: z.string().optional(),
184
+ results: GOOGLE_ADS_SEARCH_ROW_SCHEMA.array().prefault([]),
185
+ summaryRow: GOOGLE_ADS_SEARCH_ROW_SCHEMA.optional(),
186
+ totalResultsCount: DECIMAL_STRING_SCHEMA.optional(),
187
+ });
188
+ export const GOOGLE_ADS_MUTATE_RESULT_SCHEMA = z.object({
189
+ resourceName: z.string(),
190
+ });
191
+ export const GOOGLE_ADS_MUTATE_RESPONSE_SCHEMA = z.object({
192
+ results: GOOGLE_ADS_MUTATE_RESULT_SCHEMA.array(),
193
+ });
194
+ export const GOOGLE_ADS_CUSTOMER_CONTEXT_SCHEMA = z.object({
195
+ customerId: GOOGLE_ADS_CUSTOMER_ID_SCHEMA,
196
+ loginCustomerId: GOOGLE_ADS_CUSTOMER_ID_SCHEMA.optional(),
197
+ });
198
+ export const GOOGLE_ADS_CHANGE_RESOURCE_TYPE_SCHEMA = z.enum([
199
+ "UNSPECIFIED",
200
+ "UNKNOWN",
201
+ "AD",
202
+ "AD_GROUP",
203
+ "AD_GROUP_AD",
204
+ "AD_GROUP_ASSET",
205
+ "AD_GROUP_BID_MODIFIER",
206
+ "AD_GROUP_CRITERION",
207
+ "AD_GROUP_FEED",
208
+ "ASSET",
209
+ "ASSET_SET",
210
+ "ASSET_SET_ASSET",
211
+ "CAMPAIGN",
212
+ "CAMPAIGN_ASSET",
213
+ "CAMPAIGN_ASSET_SET",
214
+ "CAMPAIGN_BUDGET",
215
+ "CAMPAIGN_CRITERION",
216
+ "CAMPAIGN_FEED",
217
+ "CUSTOMER_ASSET",
218
+ "FEED",
219
+ "FEED_ITEM",
220
+ ]);
221
+ export const GOOGLE_ADS_CHANGE_EVENT_SCHEMA = z.object({
222
+ adGroup: z.string().optional(),
223
+ asset: z.string().optional(),
224
+ campaign: z.string().optional(),
225
+ changeDateTime: z.string(),
226
+ changeResourceName: z.string(),
227
+ changeResourceType: GOOGLE_ADS_CHANGE_RESOURCE_TYPE_SCHEMA,
228
+ changedFields: z.string().optional(),
229
+ clientType: z.string().optional(),
230
+ newResource: z.record(z.string(), z.json()).optional(),
231
+ oldResource: z.record(z.string(), z.json()).optional(),
232
+ resourceChangeOperation: z.enum([
233
+ "UNSPECIFIED",
234
+ "UNKNOWN",
235
+ "CREATE",
236
+ "UPDATE",
237
+ "REMOVE",
238
+ ]),
239
+ resourceName: z.string(),
240
+ userEmail: z.string().optional(),
241
+ });
242
+ export const GOOGLE_ADS_CHANGE_TRIGGER_CONFIG_SCHEMA = z.object({
243
+ customerId: GOOGLE_ADS_CUSTOMER_ID_SCHEMA,
244
+ loginCustomerId: GOOGLE_ADS_CUSTOMER_ID_SCHEMA.optional(),
245
+ });
246
+ export const GOOGLE_ADS_CHANGE_EVENT_PAYLOAD_SCHEMA = z.object({
247
+ customerId: GOOGLE_ADS_CUSTOMER_ID_SCHEMA,
248
+ event: GOOGLE_ADS_CHANGE_EVENT_SCHEMA,
249
+ });
@@ -44,13 +44,13 @@ export declare const GOOGLE_DRIVE_EVENT_SCHEMA: z.ZodObject<{
44
44
  cancelled: "cancelled";
45
45
  completed: "completed";
46
46
  deleted: "deleted";
47
+ resolved: "resolved";
47
48
  moved: "moved";
48
49
  contentChanged: "contentChanged";
49
50
  edited: "edited";
50
51
  reopened: "reopened";
51
52
  renamed: "renamed";
52
53
  reset: "reset";
53
- resolved: "resolved";
54
54
  responded: "responded";
55
55
  reviewersChanged: "reviewersChanged";
56
56
  trashed: "trashed";
@@ -71,8 +71,8 @@ export declare const GOOGLE_DRIVE_EVENT_SCHEMA: z.ZodObject<{
71
71
  resourceIds: z.ZodArray<z.ZodString>;
72
72
  resourceType: z.ZodEnum<{
73
73
  file: "file";
74
- reply: "reply";
75
74
  comment: "comment";
75
+ reply: "reply";
76
76
  accessProposal: "accessProposal";
77
77
  approval: "approval";
78
78
  permission: "permission";
@@ -958,13 +958,13 @@ export declare const googleDriveTriggerContracts: {
958
958
  cancelled: "cancelled";
959
959
  completed: "completed";
960
960
  deleted: "deleted";
961
+ resolved: "resolved";
961
962
  moved: "moved";
962
963
  contentChanged: "contentChanged";
963
964
  edited: "edited";
964
965
  reopened: "reopened";
965
966
  renamed: "renamed";
966
967
  reset: "reset";
967
- resolved: "resolved";
968
968
  responded: "responded";
969
969
  reviewersChanged: "reviewersChanged";
970
970
  trashed: "trashed";
@@ -985,8 +985,8 @@ export declare const googleDriveTriggerContracts: {
985
985
  resourceIds: z.ZodArray<z.ZodString>;
986
986
  resourceType: z.ZodEnum<{
987
987
  file: "file";
988
- reply: "reply";
989
988
  comment: "comment";
989
+ reply: "reply";
990
990
  accessProposal: "accessProposal";
991
991
  approval: "approval";
992
992
  permission: "permission";
@@ -1038,7 +1038,7 @@ export declare function toGoogleDriveTriggerType(providerEventType: string): Goo
1038
1038
  * @param eventType - Stable internal semantic event type.
1039
1039
  */
1040
1040
  export declare function parseGoogleDriveTriggerType(eventType: GoogleDriveTriggerType): {
1041
- action: "created" | "cancelled" | "completed" | "deleted" | "moved" | "contentChanged" | "edited" | "reopened" | "renamed" | "reset" | "resolved" | "responded" | "reviewersChanged" | "trashed" | "untrashed";
1042
- resourceType: "file" | "reply" | "comment" | "accessProposal" | "approval" | "permission";
1041
+ action: "created" | "cancelled" | "completed" | "deleted" | "resolved" | "moved" | "contentChanged" | "edited" | "reopened" | "renamed" | "reset" | "responded" | "reviewersChanged" | "trashed" | "untrashed";
1042
+ resourceType: "file" | "comment" | "reply" | "accessProposal" | "approval" | "permission";
1043
1043
  };
1044
1044
  export {};
@@ -4412,8 +4412,7 @@ export declare const LINEAR_PROVIDER_PROJECT_SCHEMA: z.ZodObject<{
4412
4412
  state: z.ZodString;
4413
4413
  color: z.ZodString;
4414
4414
  content: z.ZodNullable<z.ZodString>;
4415
- icon: z.ZodNullable<z.ZodString>;
4416
- lead: z.ZodNullable<z.ZodObject<{
4415
+ creator: z.ZodNullable<z.ZodObject<{
4417
4416
  active: z.ZodBoolean;
4418
4417
  avatarUrl: z.ZodNullable<z.ZodString>;
4419
4418
  displayName: z.ZodString;
@@ -4422,7 +4421,8 @@ export declare const LINEAR_PROVIDER_PROJECT_SCHEMA: z.ZodObject<{
4422
4421
  name: z.ZodString;
4423
4422
  }, z.core.$strip>>;
4424
4423
  startDate: z.ZodNullable<z.ZodISODate>;
4425
- creator: z.ZodNullable<z.ZodObject<{
4424
+ icon: z.ZodNullable<z.ZodString>;
4425
+ lead: z.ZodNullable<z.ZodObject<{
4426
4426
  active: z.ZodBoolean;
4427
4427
  avatarUrl: z.ZodNullable<z.ZodString>;
4428
4428
  displayName: z.ZodString;
@@ -0,0 +1,90 @@
1
+ import type { Encodable } from "@automate.ax/codec";
2
+ import * as z from "zod";
3
+ import { META_ADS_PAGE_INFO_SCHEMA } from "./schemas.js";
4
+ export declare const META_ADS_GRAPH_API_VERSION = "v26.0";
5
+ export declare const META_ADS_OAUTH_SECRET_SCHEMA: z.ZodObject<{
6
+ accessToken: z.ZodString;
7
+ expiresAt: z.ZodNullable<z.ZodNumber>;
8
+ tokenType: z.ZodString;
9
+ }, z.core.$strip>;
10
+ declare const META_ERROR_SCHEMA: z.ZodObject<{
11
+ code: z.ZodOptional<z.ZodNumber>;
12
+ errorSubcode: z.ZodOptional<z.ZodNumber>;
13
+ errorUserMessage: z.ZodOptional<z.ZodString>;
14
+ fbtraceId: z.ZodOptional<z.ZodString>;
15
+ isTransient: z.ZodOptional<z.ZodBoolean>;
16
+ message: z.ZodString;
17
+ type: z.ZodOptional<z.ZodString>;
18
+ }, z.core.$loose>;
19
+ /** Query values serialized by the shared Graph client. */
20
+ type QueryValue = boolean | number | string | string[] | undefined;
21
+ export interface MetaAdsResolvedAccount {
22
+ connectionMethodId: string;
23
+ secret: Record<string, unknown>;
24
+ serviceId: "meta-ads";
25
+ }
26
+ export interface MetaAdsRequestOptions<TSchema extends z.ZodType> {
27
+ body?: Encodable;
28
+ method?: "DELETE" | "GET" | "PATCH" | "POST";
29
+ query?: Record<string, QueryValue>;
30
+ responseSchema: TSchema;
31
+ }
32
+ export interface MetaAdsPage<T> {
33
+ items: T;
34
+ pageInfo?: z.output<typeof META_ADS_PAGE_INFO_SCHEMA>;
35
+ }
36
+ /** Structured Graph API failure with Meta quota and trace diagnostics. */
37
+ export declare class MetaAdsApiError extends Error {
38
+ readonly appUsage?: string;
39
+ readonly businessUseCaseUsage?: string;
40
+ readonly code?: number;
41
+ readonly fbtraceId?: string;
42
+ readonly isTransient: boolean;
43
+ readonly adAccountUsage?: string;
44
+ readonly errorSubcode?: number;
45
+ readonly retryAfter?: number;
46
+ readonly status: number;
47
+ /**
48
+ * Creates a structured Meta Ads failure.
49
+ *
50
+ * @param options - Transport, provider, and quota details.
51
+ * @param options.adAccountUsage - Raw ad-account usage header.
52
+ * @param options.appUsage - Raw app usage header.
53
+ * @param options.businessUseCaseUsage - Raw business-use-case usage header.
54
+ * @param options.error - Parsed provider error.
55
+ * @param options.retryAfter - Retry delay in seconds.
56
+ * @param options.status - HTTP response status.
57
+ */
58
+ constructor(options: {
59
+ adAccountUsage?: string;
60
+ appUsage?: string;
61
+ businessUseCaseUsage?: string;
62
+ error?: z.output<typeof META_ERROR_SCHEMA>;
63
+ retryAfter?: number;
64
+ status: number;
65
+ });
66
+ }
67
+ /**
68
+ * Creates the authenticated Graph API helper used by packaged and custom
69
+ * actions.
70
+ *
71
+ * @param account - Resolved Meta Ads OAuth account.
72
+ * @throws When the connection method or stored credential is invalid.
73
+ */
74
+ export declare function getMetaAdsApi(account: MetaAdsResolvedAccount): {
75
+ call: <TSchema extends z.ZodType>(path: string, options: MetaAdsRequestOptions<TSchema>) => Promise<z.output<TSchema>>;
76
+ page: <TSchema extends z.ZodType>(path: string, options: MetaAdsRequestOptions<TSchema>) => Promise<MetaAdsPage<z.output<TSchema>>>;
77
+ };
78
+ /**
79
+ * Converts public camelCase object keys to Meta wire keys recursively.
80
+ *
81
+ * @param value - Codec-safe public value.
82
+ */
83
+ export declare function toMeta(value: Encodable): Encodable;
84
+ /**
85
+ * Converts Meta wire keys to public camelCase keys recursively.
86
+ *
87
+ * @param value - Provider value.
88
+ */
89
+ export declare function fromMeta(value: unknown): unknown;
90
+ export {};
@@ -0,0 +1,260 @@
1
+ import * as z from "zod";
2
+ import { META_ADS_PAGE_INFO_SCHEMA } from "./schemas.js";
3
+ export const META_ADS_GRAPH_API_VERSION = "v26.0";
4
+ const META_ADS_API_BASE_URL = `https://graph.facebook.com/${META_ADS_GRAPH_API_VERSION}/`;
5
+ const META_ADS_API_ORIGIN = new URL(META_ADS_API_BASE_URL).origin;
6
+ export const META_ADS_OAUTH_SECRET_SCHEMA = z.object({
7
+ accessToken: z.string().min(1),
8
+ expiresAt: z.number().nullable(),
9
+ tokenType: z.string(),
10
+ });
11
+ const META_ERROR_SCHEMA = z.looseObject({
12
+ code: z.number().optional(),
13
+ errorSubcode: z.number().optional(),
14
+ errorUserMessage: z.string().optional(),
15
+ fbtraceId: z.string().optional(),
16
+ isTransient: z.boolean().optional(),
17
+ message: z.string(),
18
+ type: z.string().optional(),
19
+ });
20
+ const ERROR_ENVELOPE_SCHEMA = z.looseObject({ error: META_ERROR_SCHEMA });
21
+ const PAGE_SCHEMA = z.looseObject({
22
+ data: z.unknown(),
23
+ paging: z
24
+ .looseObject({
25
+ cursors: z
26
+ .looseObject({
27
+ after: z.string().optional(),
28
+ before: z.string().optional(),
29
+ })
30
+ .optional(),
31
+ next: z.string().optional(),
32
+ previous: z.string().optional(),
33
+ })
34
+ .optional(),
35
+ });
36
+ /** Structured Graph API failure with Meta quota and trace diagnostics. */
37
+ export class MetaAdsApiError extends Error {
38
+ appUsage;
39
+ businessUseCaseUsage;
40
+ code;
41
+ fbtraceId;
42
+ isTransient;
43
+ adAccountUsage;
44
+ errorSubcode;
45
+ retryAfter;
46
+ status;
47
+ /**
48
+ * Creates a structured Meta Ads failure.
49
+ *
50
+ * @param options - Transport, provider, and quota details.
51
+ * @param options.adAccountUsage - Raw ad-account usage header.
52
+ * @param options.appUsage - Raw app usage header.
53
+ * @param options.businessUseCaseUsage - Raw business-use-case usage header.
54
+ * @param options.error - Parsed provider error.
55
+ * @param options.retryAfter - Retry delay in seconds.
56
+ * @param options.status - HTTP response status.
57
+ */
58
+ constructor(options) {
59
+ const providerError = options.error;
60
+ super(providerError?.message
61
+ ? `Meta Ads API error (${providerError.code ?? options.status}): ${providerError.message}`
62
+ : `Meta Ads API request failed with status ${options.status}.`);
63
+ this.name = "MetaAdsApiError";
64
+ this.adAccountUsage = options.adAccountUsage;
65
+ this.appUsage = options.appUsage;
66
+ this.businessUseCaseUsage = options.businessUseCaseUsage;
67
+ this.code = providerError?.code;
68
+ this.errorSubcode = providerError?.errorSubcode;
69
+ this.fbtraceId = providerError?.fbtraceId;
70
+ this.isTransient = providerError?.isTransient ?? false;
71
+ this.retryAfter = options.retryAfter;
72
+ this.status = options.status;
73
+ }
74
+ }
75
+ /**
76
+ * Creates the authenticated Graph API helper used by packaged and custom
77
+ * actions.
78
+ *
79
+ * @param account - Resolved Meta Ads OAuth account.
80
+ * @throws When the connection method or stored credential is invalid.
81
+ */
82
+ export function getMetaAdsApi(account) {
83
+ if (account.connectionMethodId !== "oauth") {
84
+ throw new Error(`Unsupported Meta Ads connection method: ${account.connectionMethodId}`);
85
+ }
86
+ const { accessToken } = META_ADS_OAUTH_SECRET_SCHEMA.parse(account.secret);
87
+ /**
88
+ * Calls one Graph endpoint and validates its normalized result.
89
+ *
90
+ * @param path - Path relative to the pinned Graph root.
91
+ * @param options - Request options and response schema.
92
+ */
93
+ async function call(path, options) {
94
+ return options.responseSchema.parse(fromMeta(await rawRequest(path, options)));
95
+ }
96
+ /**
97
+ * Calls one Graph edge and preserves cursor metadata.
98
+ *
99
+ * @param path - Path relative to the pinned Graph root.
100
+ * @param options - Request options and item schema.
101
+ */
102
+ async function page(path, options) {
103
+ const parsed = PAGE_SCHEMA.parse(await rawRequest(path, options));
104
+ const paging = parsed.paging;
105
+ return {
106
+ items: options.responseSchema.parse(fromMeta(parsed.data)),
107
+ ...(paging && {
108
+ pageInfo: META_ADS_PAGE_INFO_SCHEMA.parse({
109
+ after: paging.cursors?.after,
110
+ before: paging.cursors?.before,
111
+ next: paging.next,
112
+ previous: paging.previous,
113
+ }),
114
+ }),
115
+ };
116
+ }
117
+ /**
118
+ * Executes one authenticated request and returns its raw JSON value.
119
+ *
120
+ * @param path - Path relative to the pinned Graph root.
121
+ * @param options - Request method, query, and body.
122
+ */
123
+ async function rawRequest(path, options) {
124
+ const url = new URL(path.replace(/^\/+/, ""), META_ADS_API_BASE_URL);
125
+ if (url.origin !== META_ADS_API_ORIGIN ||
126
+ !url.pathname.startsWith(`/${META_ADS_GRAPH_API_VERSION}/`)) {
127
+ throw new Error(`Meta Ads API paths must remain under /${META_ADS_GRAPH_API_VERSION}.`);
128
+ }
129
+ for (const [name, value] of Object.entries(options.query ?? {})) {
130
+ if (value !== undefined) {
131
+ url.searchParams.set(toSnakeCase(name), Array.isArray(value) ? value.join(",") : String(value));
132
+ }
133
+ }
134
+ const body = options.body === undefined ? undefined : toFormData(options.body);
135
+ const response = await fetch(url, {
136
+ body,
137
+ headers: { Authorization: `Bearer ${accessToken}` },
138
+ method: options.method ?? (body ? "POST" : "GET"),
139
+ });
140
+ const payload = parseJson(await response.text());
141
+ if (!response.ok) {
142
+ const error = ERROR_ENVELOPE_SCHEMA.safeParse(fromMeta(payload));
143
+ throw new MetaAdsApiError({
144
+ adAccountUsage: response.headers.get("X-Ad-Account-Usage") ?? undefined,
145
+ appUsage: response.headers.get("X-App-Usage") ?? undefined,
146
+ businessUseCaseUsage: response.headers.get("X-Business-Use-Case-Usage") ?? undefined,
147
+ error: error.success ? error.data.error : undefined,
148
+ retryAfter: numberOrUndefined(response.headers.get("Retry-After")),
149
+ status: response.status,
150
+ });
151
+ }
152
+ return payload;
153
+ }
154
+ return { call, page };
155
+ }
156
+ /**
157
+ * Encodes one public request body for Graph's form boundary.
158
+ *
159
+ * @param value - Codec-safe public request body.
160
+ * @throws When the body is not an object.
161
+ */
162
+ function toFormData(value) {
163
+ if (!isRecord(value))
164
+ throw new Error("Meta Ads request bodies must be objects.");
165
+ const form = new URLSearchParams();
166
+ for (const [name, item] of Object.entries(value)) {
167
+ if (item === undefined)
168
+ continue;
169
+ form.set(toSnakeCase(name), typeof item === "string" ||
170
+ typeof item === "number" ||
171
+ typeof item === "boolean"
172
+ ? String(item)
173
+ : item instanceof Date
174
+ ? item.toISOString()
175
+ : JSON.stringify(toMeta(item)));
176
+ }
177
+ return form;
178
+ }
179
+ /**
180
+ * Converts public camelCase object keys to Meta wire keys recursively.
181
+ *
182
+ * @param value - Codec-safe public value.
183
+ */
184
+ export function toMeta(value) {
185
+ if (value instanceof Date)
186
+ return value.toISOString();
187
+ if (Array.isArray(value))
188
+ return value.map(toMeta);
189
+ if (!isRecord(value))
190
+ return value;
191
+ return Object.fromEntries(Object.entries(value).map(([key, item]) => [
192
+ toSnakeCase(key),
193
+ toMeta(item),
194
+ ]));
195
+ }
196
+ /**
197
+ * Converts Meta wire keys to public camelCase keys recursively.
198
+ *
199
+ * @param value - Provider value.
200
+ */
201
+ export function fromMeta(value) {
202
+ if (Array.isArray(value))
203
+ return value.map(fromMeta);
204
+ if (!isRecord(value))
205
+ return value;
206
+ return Object.fromEntries(Object.entries(value).map(([key, item]) => [
207
+ toCamelCase(key),
208
+ fromMeta(item),
209
+ ]));
210
+ }
211
+ /**
212
+ * Converts one camelCase key to snake_case.
213
+ *
214
+ * @param value - Public key.
215
+ */
216
+ function toSnakeCase(value) {
217
+ return value.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
218
+ }
219
+ /**
220
+ * Converts one snake_case key to camelCase.
221
+ *
222
+ * @param value - Provider key.
223
+ */
224
+ function toCamelCase(value) {
225
+ return value.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
226
+ }
227
+ /**
228
+ * Parses a response body while retaining non-JSON provider failures.
229
+ *
230
+ * @param text - Raw response body.
231
+ */
232
+ function parseJson(text) {
233
+ if (text === "")
234
+ return undefined;
235
+ try {
236
+ return JSON.parse(text);
237
+ }
238
+ catch {
239
+ return text;
240
+ }
241
+ }
242
+ /**
243
+ * Parses an optional finite numeric header.
244
+ *
245
+ * @param value - Raw header value.
246
+ */
247
+ function numberOrUndefined(value) {
248
+ if (value === null)
249
+ return undefined;
250
+ const number = Number(value);
251
+ return Number.isFinite(number) ? number : undefined;
252
+ }
253
+ /**
254
+ * Narrows one codec-safe object value.
255
+ *
256
+ * @param value - Unknown value.
257
+ */
258
+ function isRecord(value) {
259
+ return typeof value === "object" && value !== null && !Array.isArray(value);
260
+ }