@defoai/ads-client 1.4.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 (188) hide show
  1. package/README.md +88 -0
  2. package/dist/generated/apis/AdAssetsApi.d.ts +140 -0
  3. package/dist/generated/apis/AdAssetsApi.js +173 -0
  4. package/dist/generated/apis/AdGroupsApi.d.ts +165 -0
  5. package/dist/generated/apis/AdGroupsApi.js +205 -0
  6. package/dist/generated/apis/AdsApi.d.ts +160 -0
  7. package/dist/generated/apis/AdsApi.js +200 -0
  8. package/dist/generated/apis/AssetsApi.d.ts +162 -0
  9. package/dist/generated/apis/AssetsApi.js +203 -0
  10. package/dist/generated/apis/CampaignAssetsApi.d.ts +136 -0
  11. package/dist/generated/apis/CampaignAssetsApi.js +167 -0
  12. package/dist/generated/apis/CampaignsApi.d.ts +169 -0
  13. package/dist/generated/apis/CampaignsApi.js +206 -0
  14. package/dist/generated/apis/KeywordsApi.d.ts +160 -0
  15. package/dist/generated/apis/KeywordsApi.js +200 -0
  16. package/dist/generated/apis/MediaApi.d.ts +50 -0
  17. package/dist/generated/apis/MediaApi.js +51 -0
  18. package/dist/generated/apis/MetaApi.d.ts +86 -0
  19. package/dist/generated/apis/MetaApi.js +104 -0
  20. package/dist/generated/apis/ReportsApi.d.ts +50 -0
  21. package/dist/generated/apis/ReportsApi.js +51 -0
  22. package/dist/generated/apis/SitesApi.d.ts +163 -0
  23. package/dist/generated/apis/SitesApi.js +202 -0
  24. package/dist/generated/apis/SyncApi.d.ts +199 -0
  25. package/dist/generated/apis/SyncApi.js +241 -0
  26. package/dist/generated/apis/index.d.ts +12 -0
  27. package/dist/generated/apis/index.js +14 -0
  28. package/dist/generated/index.d.ts +3 -0
  29. package/dist/generated/index.js +5 -0
  30. package/dist/generated/models/AdAssetCreate.d.ts +83 -0
  31. package/dist/generated/models/AdAssetCreate.js +76 -0
  32. package/dist/generated/models/AdCreate.d.ts +147 -0
  33. package/dist/generated/models/AdCreate.js +97 -0
  34. package/dist/generated/models/AdGroupAudience.d.ts +44 -0
  35. package/dist/generated/models/AdGroupAudience.js +49 -0
  36. package/dist/generated/models/AdGroupCreate.d.ts +104 -0
  37. package/dist/generated/models/AdGroupCreate.js +74 -0
  38. package/dist/generated/models/AdGroupUpdate.d.ts +104 -0
  39. package/dist/generated/models/AdGroupUpdate.js +70 -0
  40. package/dist/generated/models/AdUpdate.d.ts +147 -0
  41. package/dist/generated/models/AdUpdate.js +85 -0
  42. package/dist/generated/models/AssetCreate.d.ts +117 -0
  43. package/dist/generated/models/AssetCreate.js +80 -0
  44. package/dist/generated/models/AssetUpdate.d.ts +79 -0
  45. package/dist/generated/models/AssetUpdate.js +61 -0
  46. package/dist/generated/models/BiddingStrategy.d.ts +70 -0
  47. package/dist/generated/models/BiddingStrategy.js +62 -0
  48. package/dist/generated/models/CampaignAdScheduleField.d.ts +12 -0
  49. package/dist/generated/models/CampaignAdScheduleField.js +4 -0
  50. package/dist/generated/models/CampaignAssetCreate.d.ts +57 -0
  51. package/dist/generated/models/CampaignAssetCreate.js +63 -0
  52. package/dist/generated/models/CampaignCreate.d.ts +161 -0
  53. package/dist/generated/models/CampaignCreate.js +102 -0
  54. package/dist/generated/models/CampaignTargeting.d.ts +50 -0
  55. package/dist/generated/models/CampaignTargeting.js +47 -0
  56. package/dist/generated/models/CampaignUpdate.d.ts +161 -0
  57. package/dist/generated/models/CampaignUpdate.js +98 -0
  58. package/dist/generated/models/CampaignsListCursorParameter.d.ts +26 -0
  59. package/dist/generated/models/CampaignsListCursorParameter.js +31 -0
  60. package/dist/generated/models/ErrorEnvelope.d.ts +33 -0
  61. package/dist/generated/models/ErrorEnvelope.js +44 -0
  62. package/dist/generated/models/ErrorEnvelopeError.d.ts +44 -0
  63. package/dist/generated/models/ErrorEnvelopeError.js +49 -0
  64. package/dist/generated/models/KeywordCreate.d.ts +86 -0
  65. package/dist/generated/models/KeywordCreate.js +73 -0
  66. package/dist/generated/models/KeywordUpdate.d.ts +86 -0
  67. package/dist/generated/models/KeywordUpdate.js +69 -0
  68. package/dist/generated/models/Location.d.ts +61 -0
  69. package/dist/generated/models/Location.js +61 -0
  70. package/dist/generated/models/NegativeKeywordEntry.d.ts +47 -0
  71. package/dist/generated/models/NegativeKeywordEntry.js +55 -0
  72. package/dist/generated/models/ScheduleWindow.d.ts +95 -0
  73. package/dist/generated/models/ScheduleWindow.js +87 -0
  74. package/dist/generated/models/SiteCreate.d.ts +99 -0
  75. package/dist/generated/models/SiteCreate.js +78 -0
  76. package/dist/generated/models/SiteCreateSeoKeywords.d.ts +11 -0
  77. package/dist/generated/models/SiteCreateSeoKeywords.js +12 -0
  78. package/dist/generated/models/SiteCreateTargetGroups.d.ts +11 -0
  79. package/dist/generated/models/SiteCreateTargetGroups.js +12 -0
  80. package/dist/generated/models/SiteLinkEntry.d.ts +50 -0
  81. package/dist/generated/models/SiteLinkEntry.js +47 -0
  82. package/dist/generated/models/SiteUpdate.d.ts +99 -0
  83. package/dist/generated/models/SiteUpdate.js +74 -0
  84. package/dist/generated/models/Sitelink.d.ts +64 -0
  85. package/dist/generated/models/Sitelink.js +51 -0
  86. package/dist/generated/models/StructuredSchedule.d.ts +39 -0
  87. package/dist/generated/models/StructuredSchedule.js +46 -0
  88. package/dist/generated/models/StructuredSnippet.d.ts +38 -0
  89. package/dist/generated/models/StructuredSnippet.js +47 -0
  90. package/dist/generated/models/SuccessEnvelope.d.ts +39 -0
  91. package/dist/generated/models/SuccessEnvelope.js +46 -0
  92. package/dist/generated/models/SuccessEnvelopeMeta.d.ts +39 -0
  93. package/dist/generated/models/SuccessEnvelopeMeta.js +44 -0
  94. package/dist/generated/models/SuccessEnvelopeMetaNextCursor.d.ts +26 -0
  95. package/dist/generated/models/SuccessEnvelopeMetaNextCursor.js +31 -0
  96. package/dist/generated/models/SyncCampaignDetail.d.ts +88 -0
  97. package/dist/generated/models/SyncCampaignDetail.js +71 -0
  98. package/dist/generated/models/SyncPlan.d.ts +35 -0
  99. package/dist/generated/models/SyncPlan.js +43 -0
  100. package/dist/generated/models/SyncPlanPlatformsValue.d.ts +33 -0
  101. package/dist/generated/models/SyncPlanPlatformsValue.js +42 -0
  102. package/dist/generated/models/SyncPlanPlatformsValueTotals.d.ts +44 -0
  103. package/dist/generated/models/SyncPlanPlatformsValueTotals.js +45 -0
  104. package/dist/generated/models/SyncProgress.d.ts +57 -0
  105. package/dist/generated/models/SyncProgress.js +50 -0
  106. package/dist/generated/models/SyncRecord.d.ts +103 -0
  107. package/dist/generated/models/SyncRecord.js +73 -0
  108. package/dist/generated/models/SyncRecordErrorsInner.d.ts +38 -0
  109. package/dist/generated/models/SyncRecordErrorsInner.js +43 -0
  110. package/dist/generated/models/SyncTotals.d.ts +68 -0
  111. package/dist/generated/models/SyncTotals.js +53 -0
  112. package/dist/generated/models/SyncTriggerRequest.d.ts +39 -0
  113. package/dist/generated/models/SyncTriggerRequest.js +44 -0
  114. package/dist/generated/models/SyncTriggerRequestOptions.d.ts +56 -0
  115. package/dist/generated/models/SyncTriggerRequestOptions.js +49 -0
  116. package/dist/generated/models/SyncTriggerResponse.d.ts +59 -0
  117. package/dist/generated/models/SyncTriggerResponse.js +55 -0
  118. package/dist/generated/models/SyncUnlinkRequest.d.ts +44 -0
  119. package/dist/generated/models/SyncUnlinkRequest.js +47 -0
  120. package/dist/generated/models/index.d.ts +45 -0
  121. package/dist/generated/models/index.js +47 -0
  122. package/dist/generated/runtime.d.ts +182 -0
  123. package/dist/generated/runtime.js +318 -0
  124. package/dist/index.d.ts +177 -0
  125. package/dist/index.js +207 -0
  126. package/package.json +32 -0
  127. package/src/generated/apis/AdAssetsApi.ts +342 -0
  128. package/src/generated/apis/AdGroupsApi.ts +408 -0
  129. package/src/generated/apis/AdsApi.ts +399 -0
  130. package/src/generated/apis/AssetsApi.ts +405 -0
  131. package/src/generated/apis/CampaignAssetsApi.ts +330 -0
  132. package/src/generated/apis/CampaignsApi.ts +408 -0
  133. package/src/generated/apis/KeywordsApi.ts +399 -0
  134. package/src/generated/apis/MediaApi.ts +99 -0
  135. package/src/generated/apis/MetaApi.ts +186 -0
  136. package/src/generated/apis/ReportsApi.ts +99 -0
  137. package/src/generated/apis/SitesApi.ts +402 -0
  138. package/src/generated/apis/SyncApi.ts +468 -0
  139. package/src/generated/apis/index.ts +14 -0
  140. package/src/generated/index.ts +5 -0
  141. package/src/generated/models/AdAssetCreate.ts +133 -0
  142. package/src/generated/models/AdCreate.ts +234 -0
  143. package/src/generated/models/AdGroupAudience.ts +83 -0
  144. package/src/generated/models/AdGroupCreate.ts +167 -0
  145. package/src/generated/models/AdGroupUpdate.ts +165 -0
  146. package/src/generated/models/AdUpdate.ts +228 -0
  147. package/src/generated/models/AssetCreate.ts +175 -0
  148. package/src/generated/models/AssetUpdate.ts +125 -0
  149. package/src/generated/models/BiddingStrategy.ts +114 -0
  150. package/src/generated/models/CampaignAdScheduleField.ts +16 -0
  151. package/src/generated/models/CampaignAssetCreate.ts +100 -0
  152. package/src/generated/models/CampaignCreate.ts +263 -0
  153. package/src/generated/models/CampaignTargeting.ts +89 -0
  154. package/src/generated/models/CampaignUpdate.ts +261 -0
  155. package/src/generated/models/CampaignsListCursorParameter.ts +46 -0
  156. package/src/generated/models/ErrorEnvelope.ts +74 -0
  157. package/src/generated/models/ErrorEnvelopeError.ts +83 -0
  158. package/src/generated/models/KeywordCreate.ts +137 -0
  159. package/src/generated/models/KeywordUpdate.ts +135 -0
  160. package/src/generated/models/Location.ts +105 -0
  161. package/src/generated/models/NegativeKeywordEntry.ts +87 -0
  162. package/src/generated/models/ScheduleWindow.ts +146 -0
  163. package/src/generated/models/SiteCreate.ts +173 -0
  164. package/src/generated/models/SiteCreateSeoKeywords.ts +16 -0
  165. package/src/generated/models/SiteCreateTargetGroups.ts +16 -0
  166. package/src/generated/models/SiteLinkEntry.ts +89 -0
  167. package/src/generated/models/SiteUpdate.ts +171 -0
  168. package/src/generated/models/Sitelink.ts +105 -0
  169. package/src/generated/models/StructuredSchedule.ts +82 -0
  170. package/src/generated/models/StructuredSnippet.ts +75 -0
  171. package/src/generated/models/SuccessEnvelope.ts +82 -0
  172. package/src/generated/models/SuccessEnvelopeMeta.ts +81 -0
  173. package/src/generated/models/SuccessEnvelopeMetaNextCursor.ts +46 -0
  174. package/src/generated/models/SyncCampaignDetail.ts +137 -0
  175. package/src/generated/models/SyncPlan.ts +73 -0
  176. package/src/generated/models/SyncPlanPlatformsValue.ts +73 -0
  177. package/src/generated/models/SyncPlanPlatformsValueTotals.ts +81 -0
  178. package/src/generated/models/SyncProgress.ts +105 -0
  179. package/src/generated/models/SyncRecord.ts +174 -0
  180. package/src/generated/models/SyncRecordErrorsInner.ts +73 -0
  181. package/src/generated/models/SyncTotals.ts +113 -0
  182. package/src/generated/models/SyncTriggerRequest.ts +81 -0
  183. package/src/generated/models/SyncTriggerRequestOptions.ts +97 -0
  184. package/src/generated/models/SyncTriggerResponse.ts +108 -0
  185. package/src/generated/models/SyncUnlinkRequest.ts +82 -0
  186. package/src/generated/models/index.ts +47 -0
  187. package/src/generated/runtime.ts +431 -0
  188. package/src/index.ts +229 -0
@@ -0,0 +1,431 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+ /**
4
+ * Defo Ads Public API
5
+ * Stable public API for managing campaigns, ads, keywords, and sites.
6
+ *
7
+ * The version of the OpenAPI document: 1.4.0
8
+ *
9
+ *
10
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
11
+ * https://openapi-generator.tech
12
+ * Do not edit the class manually.
13
+ */
14
+
15
+
16
+ export const BASE_PATH = "https://api.ads.defoai.com".replace(/\/+$/, "");
17
+
18
+ export interface ConfigurationParameters {
19
+ basePath?: string; // override base path
20
+ fetchApi?: FetchAPI; // override for fetch implementation
21
+ middleware?: Middleware[]; // middleware to apply before/after fetch requests
22
+ queryParamsStringify?: (params: HTTPQuery) => string; // stringify function for query strings
23
+ username?: string; // parameter for basic security
24
+ password?: string; // parameter for basic security
25
+ apiKey?: string | Promise<string> | ((name: string) => string | Promise<string>); // parameter for apiKey security
26
+ accessToken?: string | Promise<string> | ((name?: string, scopes?: string[]) => string | Promise<string>); // parameter for oauth2 security
27
+ headers?: HTTPHeaders; //header params we want to use on every request
28
+ credentials?: RequestCredentials; //value for the credentials param we want to use on each request
29
+ }
30
+
31
+ export class Configuration {
32
+ constructor(private configuration: ConfigurationParameters = {}) {}
33
+
34
+ set config(configuration: Configuration) {
35
+ this.configuration = configuration;
36
+ }
37
+
38
+ get basePath(): string {
39
+ return this.configuration.basePath != null ? this.configuration.basePath : BASE_PATH;
40
+ }
41
+
42
+ get fetchApi(): FetchAPI | undefined {
43
+ return this.configuration.fetchApi;
44
+ }
45
+
46
+ get middleware(): Middleware[] {
47
+ return this.configuration.middleware || [];
48
+ }
49
+
50
+ get queryParamsStringify(): (params: HTTPQuery) => string {
51
+ return this.configuration.queryParamsStringify || querystring;
52
+ }
53
+
54
+ get username(): string | undefined {
55
+ return this.configuration.username;
56
+ }
57
+
58
+ get password(): string | undefined {
59
+ return this.configuration.password;
60
+ }
61
+
62
+ get apiKey(): ((name: string) => string | Promise<string>) | undefined {
63
+ const apiKey = this.configuration.apiKey;
64
+ if (apiKey) {
65
+ return typeof apiKey === 'function' ? apiKey : () => apiKey;
66
+ }
67
+ return undefined;
68
+ }
69
+
70
+ get accessToken(): ((name?: string, scopes?: string[]) => string | Promise<string>) | undefined {
71
+ const accessToken = this.configuration.accessToken;
72
+ if (accessToken) {
73
+ return typeof accessToken === 'function' ? accessToken : async () => accessToken;
74
+ }
75
+ return undefined;
76
+ }
77
+
78
+ get headers(): HTTPHeaders | undefined {
79
+ return this.configuration.headers;
80
+ }
81
+
82
+ get credentials(): RequestCredentials | undefined {
83
+ return this.configuration.credentials;
84
+ }
85
+ }
86
+
87
+ export const DefaultConfig = new Configuration();
88
+
89
+ /**
90
+ * This is the base class for all generated API classes.
91
+ */
92
+ export class BaseAPI {
93
+
94
+ private static readonly jsonRegex = new RegExp('^(:?application\/json|[^;/ \t]+\/[^;/ \t]+[+]json)[ \t]*(:?;.*)?$', 'i');
95
+ private middleware: Middleware[];
96
+
97
+ constructor(protected configuration = DefaultConfig) {
98
+ this.middleware = configuration.middleware;
99
+ }
100
+
101
+ withMiddleware<T extends BaseAPI>(this: T, ...middlewares: Middleware[]) {
102
+ const next = this.clone<T>();
103
+ next.middleware = next.middleware.concat(...middlewares);
104
+ return next;
105
+ }
106
+
107
+ withPreMiddleware<T extends BaseAPI>(this: T, ...preMiddlewares: Array<Middleware['pre']>) {
108
+ const middlewares = preMiddlewares.map((pre) => ({ pre }));
109
+ return this.withMiddleware<T>(...middlewares);
110
+ }
111
+
112
+ withPostMiddleware<T extends BaseAPI>(this: T, ...postMiddlewares: Array<Middleware['post']>) {
113
+ const middlewares = postMiddlewares.map((post) => ({ post }));
114
+ return this.withMiddleware<T>(...middlewares);
115
+ }
116
+
117
+ /**
118
+ * Check if the given MIME is a JSON MIME.
119
+ * JSON MIME examples:
120
+ * application/json
121
+ * application/json; charset=UTF8
122
+ * APPLICATION/JSON
123
+ * application/vnd.company+json
124
+ * @param mime - MIME (Multipurpose Internet Mail Extensions)
125
+ * @return True if the given MIME is JSON, false otherwise.
126
+ */
127
+ protected isJsonMime(mime: string | null | undefined): boolean {
128
+ if (!mime) {
129
+ return false;
130
+ }
131
+ return BaseAPI.jsonRegex.test(mime);
132
+ }
133
+
134
+ protected async request(context: RequestOpts, initOverrides?: RequestInit | InitOverrideFunction): Promise<Response> {
135
+ const { url, init } = await this.createFetchParams(context, initOverrides);
136
+ const response = await this.fetchApi(url, init);
137
+ if (response && (response.status >= 200 && response.status < 300)) {
138
+ return response;
139
+ }
140
+ throw new ResponseError(response, 'Response returned an error code');
141
+ }
142
+
143
+ private async createFetchParams(context: RequestOpts, initOverrides?: RequestInit | InitOverrideFunction) {
144
+ let url = this.configuration.basePath + context.path;
145
+ if (context.query !== undefined && Object.keys(context.query).length !== 0) {
146
+ // only add the querystring to the URL if there are query parameters.
147
+ // this is done to avoid urls ending with a "?" character which buggy webservers
148
+ // do not handle correctly sometimes.
149
+ url += '?' + this.configuration.queryParamsStringify(context.query);
150
+ }
151
+
152
+ const headers = Object.assign({}, this.configuration.headers, context.headers);
153
+ Object.keys(headers).forEach(key => headers[key] === undefined ? delete headers[key] : {});
154
+
155
+ const initOverrideFn =
156
+ typeof initOverrides === "function"
157
+ ? initOverrides
158
+ : async () => initOverrides;
159
+
160
+ const initParams = {
161
+ method: context.method,
162
+ headers,
163
+ body: context.body,
164
+ credentials: this.configuration.credentials,
165
+ };
166
+
167
+ const overriddenInit: RequestInit = {
168
+ ...initParams,
169
+ ...(await initOverrideFn({
170
+ init: initParams,
171
+ context,
172
+ }))
173
+ };
174
+
175
+ let body: any;
176
+ if (isFormData(overriddenInit.body)
177
+ || (overriddenInit.body instanceof URLSearchParams)
178
+ || isBlob(overriddenInit.body)) {
179
+ body = overriddenInit.body;
180
+ } else if (this.isJsonMime(headers['Content-Type'])) {
181
+ body = JSON.stringify(overriddenInit.body);
182
+ } else {
183
+ body = overriddenInit.body;
184
+ }
185
+
186
+ const init: RequestInit = {
187
+ ...overriddenInit,
188
+ body
189
+ };
190
+
191
+ return { url, init };
192
+ }
193
+
194
+ private fetchApi = async (url: string, init: RequestInit) => {
195
+ let fetchParams = { url, init };
196
+ for (const middleware of this.middleware) {
197
+ if (middleware.pre) {
198
+ fetchParams = await middleware.pre({
199
+ fetch: this.fetchApi,
200
+ ...fetchParams,
201
+ }) || fetchParams;
202
+ }
203
+ }
204
+ let response: Response | undefined = undefined;
205
+ try {
206
+ response = await (this.configuration.fetchApi || fetch)(fetchParams.url, fetchParams.init);
207
+ } catch (e) {
208
+ for (const middleware of this.middleware) {
209
+ if (middleware.onError) {
210
+ response = await middleware.onError({
211
+ fetch: this.fetchApi,
212
+ url: fetchParams.url,
213
+ init: fetchParams.init,
214
+ error: e,
215
+ response: response ? response.clone() : undefined,
216
+ }) || response;
217
+ }
218
+ }
219
+ if (response === undefined) {
220
+ if (e instanceof Error) {
221
+ throw new FetchError(e, 'The request failed and the interceptors did not return an alternative response');
222
+ } else {
223
+ throw e;
224
+ }
225
+ }
226
+ }
227
+ for (const middleware of this.middleware) {
228
+ if (middleware.post) {
229
+ response = await middleware.post({
230
+ fetch: this.fetchApi,
231
+ url: fetchParams.url,
232
+ init: fetchParams.init,
233
+ response: response.clone(),
234
+ }) || response;
235
+ }
236
+ }
237
+ return response;
238
+ }
239
+
240
+ /**
241
+ * Create a shallow clone of `this` by constructing a new instance
242
+ * and then shallow cloning data members.
243
+ */
244
+ private clone<T extends BaseAPI>(this: T): T {
245
+ const constructor = this.constructor as any;
246
+ const next = new constructor(this.configuration);
247
+ next.middleware = this.middleware.slice();
248
+ return next;
249
+ }
250
+ };
251
+
252
+ function isBlob(value: any): value is Blob {
253
+ return typeof Blob !== 'undefined' && value instanceof Blob;
254
+ }
255
+
256
+ function isFormData(value: any): value is FormData {
257
+ return typeof FormData !== "undefined" && value instanceof FormData;
258
+ }
259
+
260
+ export class ResponseError extends Error {
261
+ override name: "ResponseError" = "ResponseError";
262
+ constructor(public response: Response, msg?: string) {
263
+ super(msg);
264
+ }
265
+ }
266
+
267
+ export class FetchError extends Error {
268
+ override name: "FetchError" = "FetchError";
269
+ constructor(public cause: Error, msg?: string) {
270
+ super(msg);
271
+ }
272
+ }
273
+
274
+ export class RequiredError extends Error {
275
+ override name: "RequiredError" = "RequiredError";
276
+ constructor(public field: string, msg?: string) {
277
+ super(msg);
278
+ }
279
+ }
280
+
281
+ export const COLLECTION_FORMATS = {
282
+ csv: ",",
283
+ ssv: " ",
284
+ tsv: "\t",
285
+ pipes: "|",
286
+ };
287
+
288
+ export type FetchAPI = WindowOrWorkerGlobalScope['fetch'];
289
+
290
+ export type Json = any;
291
+ export type HTTPMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'OPTIONS' | 'HEAD';
292
+ export type HTTPHeaders = { [key: string]: string };
293
+ export type HTTPQuery = { [key: string]: string | number | null | boolean | Array<string | number | null | boolean> | Set<string | number | null | boolean> | HTTPQuery };
294
+ export type HTTPBody = Json | FormData | URLSearchParams;
295
+ export type HTTPRequestInit = { headers?: HTTPHeaders; method: HTTPMethod; credentials?: RequestCredentials; body?: HTTPBody };
296
+ export type ModelPropertyNaming = 'camelCase' | 'snake_case' | 'PascalCase' | 'original';
297
+
298
+ export type InitOverrideFunction = (requestContext: { init: HTTPRequestInit, context: RequestOpts }) => Promise<RequestInit>
299
+
300
+ export interface FetchParams {
301
+ url: string;
302
+ init: RequestInit;
303
+ }
304
+
305
+ export interface RequestOpts {
306
+ path: string;
307
+ method: HTTPMethod;
308
+ headers: HTTPHeaders;
309
+ query?: HTTPQuery;
310
+ body?: HTTPBody;
311
+ }
312
+
313
+ export function querystring(params: HTTPQuery, prefix: string = ''): string {
314
+ return Object.keys(params)
315
+ .map(key => querystringSingleKey(key, params[key], prefix))
316
+ .filter(part => part.length > 0)
317
+ .join('&');
318
+ }
319
+
320
+ function querystringSingleKey(key: string, value: string | number | null | undefined | boolean | Array<string | number | null | boolean> | Set<string | number | null | boolean> | HTTPQuery, keyPrefix: string = ''): string {
321
+ const fullKey = keyPrefix + (keyPrefix.length ? `[${key}]` : key);
322
+ if (value instanceof Array) {
323
+ const multiValue = value.map(singleValue => encodeURIComponent(String(singleValue)))
324
+ .join(`&${encodeURIComponent(fullKey)}=`);
325
+ return `${encodeURIComponent(fullKey)}=${multiValue}`;
326
+ }
327
+ if (value instanceof Set) {
328
+ const valueAsArray = Array.from(value);
329
+ return querystringSingleKey(key, valueAsArray, keyPrefix);
330
+ }
331
+ if (value instanceof Date) {
332
+ return `${encodeURIComponent(fullKey)}=${encodeURIComponent(value.toISOString())}`;
333
+ }
334
+ if (value instanceof Object) {
335
+ return querystring(value as HTTPQuery, fullKey);
336
+ }
337
+ return `${encodeURIComponent(fullKey)}=${encodeURIComponent(String(value))}`;
338
+ }
339
+
340
+ export function exists(json: any, key: string) {
341
+ const value = json[key];
342
+ return value !== null && value !== undefined;
343
+ }
344
+
345
+ export function mapValues(data: any, fn: (item: any) => any) {
346
+ return Object.keys(data).reduce(
347
+ (acc, key) => ({ ...acc, [key]: fn(data[key]) }),
348
+ {}
349
+ );
350
+ }
351
+
352
+ export function canConsumeForm(consumes: Consume[]): boolean {
353
+ for (const consume of consumes) {
354
+ if ('multipart/form-data' === consume.contentType) {
355
+ return true;
356
+ }
357
+ }
358
+ return false;
359
+ }
360
+
361
+ export interface Consume {
362
+ contentType: string;
363
+ }
364
+
365
+ export interface RequestContext {
366
+ fetch: FetchAPI;
367
+ url: string;
368
+ init: RequestInit;
369
+ }
370
+
371
+ export interface ResponseContext {
372
+ fetch: FetchAPI;
373
+ url: string;
374
+ init: RequestInit;
375
+ response: Response;
376
+ }
377
+
378
+ export interface ErrorContext {
379
+ fetch: FetchAPI;
380
+ url: string;
381
+ init: RequestInit;
382
+ error: unknown;
383
+ response?: Response;
384
+ }
385
+
386
+ export interface Middleware {
387
+ pre?(context: RequestContext): Promise<FetchParams | void>;
388
+ post?(context: ResponseContext): Promise<Response | void>;
389
+ onError?(context: ErrorContext): Promise<Response | void>;
390
+ }
391
+
392
+ export interface ApiResponse<T> {
393
+ raw: Response;
394
+ value(): Promise<T>;
395
+ }
396
+
397
+ export interface ResponseTransformer<T> {
398
+ (json: any): T;
399
+ }
400
+
401
+ export class JSONApiResponse<T> {
402
+ constructor(public raw: Response, private transformer: ResponseTransformer<T> = (jsonValue: any) => jsonValue) {}
403
+
404
+ async value(): Promise<T> {
405
+ return this.transformer(await this.raw.json());
406
+ }
407
+ }
408
+
409
+ export class VoidApiResponse {
410
+ constructor(public raw: Response) {}
411
+
412
+ async value(): Promise<void> {
413
+ return undefined;
414
+ }
415
+ }
416
+
417
+ export class BlobApiResponse {
418
+ constructor(public raw: Response) {}
419
+
420
+ async value(): Promise<Blob> {
421
+ return await this.raw.blob();
422
+ };
423
+ }
424
+
425
+ export class TextApiResponse {
426
+ constructor(public raw: Response) {}
427
+
428
+ async value(): Promise<string> {
429
+ return await this.raw.text();
430
+ };
431
+ }
package/src/index.ts ADDED
@@ -0,0 +1,229 @@
1
+ // Defo Ads — official TypeScript SDK (US-ADS-267).
2
+ //
3
+ // A thin, hand-written façade over the OpenAPI-generated core (./generated). It
4
+ // gives you the ergonomic surface — `new DefoAds({ token }).campaigns.list()` —
5
+ // with bearer auth, a default Space header, cursor auto-pagination, retry-on-429
6
+ // (honoring Retry-After) and typed errors, while the generated core (regenerated
7
+ // from the spec on every release) does the wire work and stays byte-true to the
8
+ // API contract.
9
+ //
10
+ // Quick start:
11
+ // import { DefoAds } from '@defoai/ads-client';
12
+ // const defo = new DefoAds({ token: process.env.DEFOADS_TOKEN!, space: 'spc_…' });
13
+ // const campaigns = await defo.campaigns.list(); // first page
14
+ // for await (const c of defo.campaigns.listAll()) { … } // every page
15
+ // const created = await defo.campaigns.create({ name: 'Launch', budget: 50 });
16
+
17
+ import {
18
+ Configuration,
19
+ CampaignsApi, AdGroupsApi, AdsApi, KeywordsApi, SitesApi, AssetsApi,
20
+ CampaignAssetsApi, AdAssetsApi, MediaApi, ReportsApi, SyncApi, MetaApi,
21
+ type Middleware,
22
+ type CampaignCreate, type CampaignUpdate,
23
+ type AdGroupCreate, type AdGroupUpdate,
24
+ type AdCreate, type AdUpdate,
25
+ type KeywordCreate, type KeywordUpdate,
26
+ type SiteCreate, type SiteUpdate,
27
+ type AssetCreate, type AssetUpdate,
28
+ type CampaignAssetCreate, type AdAssetCreate,
29
+ type SyncTriggerRequest, type SyncUnlinkRequest,
30
+ } from './generated';
31
+
32
+ /** The production base URL. Override via `baseUrl` (e.g. for staging). */
33
+ export const PRODUCTION_BASE_URL = 'https://api.ads.defoai.com';
34
+ export const STAGING_BASE_URL = 'https://api-ads-staging.defoai.com';
35
+
36
+ export interface DefoAdsOptions {
37
+ /** A Defo Ads personal access token (`dads_…`). Required. */
38
+ token: string;
39
+ /** Default Space id (`spc_…`) sent as `X-Space-Id` on every call. Omit to use your Personal Space. */
40
+ space?: string;
41
+ /** Base URL. Defaults to production. Use {@link STAGING_BASE_URL} for staging. */
42
+ baseUrl?: string;
43
+ /** Max automatic retries on 429 / 5xx. Default 3. */
44
+ maxRetries?: number;
45
+ /** Inject a fetch implementation (handy for tests / non-global-fetch runtimes). */
46
+ fetch?: typeof fetch;
47
+ }
48
+
49
+ // ---- Typed errors -------------------------------------------------------------
50
+ /** Base error for any non-2xx response; carries the API's `{ code, message, details }`. */
51
+ export class DefoAdsError extends Error {
52
+ readonly status: number;
53
+ readonly code?: string;
54
+ readonly details?: unknown;
55
+ constructor(status: number, code: string | undefined, message: string, details?: unknown) {
56
+ super(message);
57
+ this.name = 'DefoAdsError';
58
+ this.status = status;
59
+ this.code = code;
60
+ this.details = details;
61
+ }
62
+ }
63
+ /** 401 — missing/invalid token. */ export class AuthError extends DefoAdsError { override name = 'AuthError'; }
64
+ /** 403 — token lacks the required scope or Space membership. */ export class ForbiddenError extends DefoAdsError { override name = 'ForbiddenError'; }
65
+ /** 404 — resource not found (or outside your Space). */ export class NotFoundError extends DefoAdsError { override name = 'NotFoundError'; }
66
+ /** 409 — conflict (e.g. delete blocked by dependents, or a sync already running). */ export class ConflictError extends DefoAdsError { override name = 'ConflictError'; }
67
+ /** 429 — rate limited. The SDK already retried up to `maxRetries`. */ export class RateLimitError extends DefoAdsError { override name = 'RateLimitError'; }
68
+
69
+ function toTypedError(status: number, code: string | undefined, message: string, details?: unknown): DefoAdsError {
70
+ const msg = message || `HTTP ${status}`;
71
+ switch (status) {
72
+ case 401: return new AuthError(status, code, msg, details);
73
+ case 403: return new ForbiddenError(status, code, msg, details);
74
+ case 404: return new NotFoundError(status, code, msg, details);
75
+ case 409: return new ConflictError(status, code, msg, details);
76
+ case 429: return new RateLimitError(status, code, msg, details);
77
+ default: return new DefoAdsError(status, code, msg, details);
78
+ }
79
+ }
80
+
81
+ // ---- fetch with retry/backoff (honors Retry-After) ---------------------------
82
+ function retryingFetch(baseFetch: typeof fetch, maxRetries: number): typeof fetch {
83
+ return async (input: any, init?: any): Promise<Response> => {
84
+ const method = (init?.method || 'GET').toUpperCase();
85
+ const idempotent = method === 'GET' || method === 'PUT' || method === 'DELETE';
86
+ let attempt = 0;
87
+ // eslint-disable-next-line no-constant-condition
88
+ while (true) {
89
+ const res = await baseFetch(input, init);
90
+ const retryable = res.status === 429 || (res.status >= 500 && idempotent);
91
+ if (!retryable || attempt >= maxRetries) return res;
92
+ const retryAfter = res.headers.get('retry-after');
93
+ const waitMs = retryAfter
94
+ ? Number(retryAfter) * 1000
95
+ : Math.min(2 ** attempt * 500, 8000);
96
+ await new Promise((r) => setTimeout(r, Number.isFinite(waitMs) ? waitMs : 1000));
97
+ attempt += 1;
98
+ }
99
+ };
100
+ }
101
+
102
+ // Throw a typed error on any 4xx/5xx, parsing the `ErrorEnvelope`, BEFORE the
103
+ // generated core raises its generic ResponseError.
104
+ const errorMiddleware: Middleware = {
105
+ post: async ({ response }) => {
106
+ if (response.status >= 400) {
107
+ let code: string | undefined;
108
+ let message = response.statusText;
109
+ let details: unknown;
110
+ try {
111
+ const body: any = await response.clone().json();
112
+ code = body?.error?.code;
113
+ message = body?.error?.message ?? message;
114
+ details = body?.error?.details;
115
+ } catch { /* non-JSON error body */ }
116
+ throw toTypedError(response.status, code, message, details);
117
+ }
118
+ return response;
119
+ },
120
+ };
121
+
122
+ // ---- generic resource factory ------------------------------------------------
123
+ // Every generated method takes a single request-params object and returns a
124
+ // SuccessEnvelope `{ data, meta }`; the façade unwraps `.data` and threads the
125
+ // default Space + cursor pagination. Input bodies stay fully typed (C/U); list
126
+ // responses are arrays (the envelope's `data` is contract-untyped today).
127
+ const data = (env: any) => env?.data;
128
+
129
+ interface ListParams { limit?: number; cursor?: string | number }
130
+
131
+ function crudResource<C, U>(api: any, prefix: string, createKey: string, updateKey: string) {
132
+ return {
133
+ /** List one page (default 50, max 200). */
134
+ list: (params: ListParams = {}): Promise<any[]> => api[`${prefix}List`]({ ...params }).then(data),
135
+ /** Async-iterate EVERY item across all pages (follows `meta.nextCursor`). */
136
+ async *listAll(params: ListParams = {}): AsyncGenerator<any> {
137
+ let cursor = params.cursor;
138
+ do {
139
+ const env = await api[`${prefix}List`]({ ...params, cursor });
140
+ for (const item of env.data ?? []) yield item;
141
+ cursor = env.meta?.nextCursor ?? undefined;
142
+ } while (cursor);
143
+ },
144
+ /** Fetch one by id. */
145
+ get: (id: string): Promise<any> => api[`${prefix}Get`]({ id }).then(data),
146
+ /** Create. */
147
+ create: (body: C): Promise<any> => api[`${prefix}Create`]({ [createKey]: body }).then(data),
148
+ /** Partial update by id. */
149
+ update: (id: string, body: U): Promise<any> => api[`${prefix}Update`]({ id, [updateKey]: body }).then(data),
150
+ /** Delete by id. */
151
+ delete: (id: string): Promise<any> => api[`${prefix}Delete`]({ id }).then(data),
152
+ };
153
+ }
154
+
155
+ /** The Defo Ads client. Construct once, reuse everywhere. */
156
+ export class DefoAds {
157
+ readonly campaigns; readonly adGroups; readonly ads; readonly keywords;
158
+ readonly sites; readonly assets; readonly campaignAssets; readonly adAssets;
159
+ readonly media; readonly reports; readonly sync; readonly meta;
160
+
161
+ constructor(options: DefoAdsOptions) {
162
+ if (!options?.token) throw new Error('DefoAds: `token` is required (a dads_… personal access token).');
163
+ const baseFetch = options.fetch ?? globalThis.fetch;
164
+ if (!baseFetch) throw new Error('DefoAds: no global fetch — pass `fetch` in options (Node < 18).');
165
+
166
+ const config = new Configuration({
167
+ basePath: options.baseUrl ?? PRODUCTION_BASE_URL,
168
+ accessToken: options.token, // → Authorization: Bearer <token>
169
+ headers: options.space ? { 'X-Space-Id': options.space } : {},
170
+ fetchApi: retryingFetch(baseFetch, options.maxRetries ?? 3),
171
+ middleware: [errorMiddleware],
172
+ });
173
+
174
+ this.campaigns = crudResource<CampaignCreate, CampaignUpdate>(new CampaignsApi(config), 'campaigns', 'campaignCreate', 'campaignUpdate');
175
+ this.adGroups = crudResource<AdGroupCreate, AdGroupUpdate>(new AdGroupsApi(config), 'adGroups', 'adGroupCreate', 'adGroupUpdate');
176
+ this.ads = crudResource<AdCreate, AdUpdate>(new AdsApi(config), 'ads', 'adCreate', 'adUpdate');
177
+ this.keywords = crudResource<KeywordCreate, KeywordUpdate>(new KeywordsApi(config), 'keywords', 'keywordCreate', 'keywordUpdate');
178
+ this.sites = crudResource<SiteCreate, SiteUpdate>(new SitesApi(config), 'sites', 'siteCreate', 'siteUpdate');
179
+ this.assets = crudResource<AssetCreate, AssetUpdate>(new AssetsApi(config), 'assets', 'assetCreate', 'assetUpdate');
180
+
181
+ // Binding-only resources (no full CRUD).
182
+ const campaignAssetsApi = new CampaignAssetsApi(config);
183
+ this.campaignAssets = {
184
+ list: (p: ListParams & { campaignId?: string; assetId?: string } = {}) => campaignAssetsApi.campaignAssetsList(p as any).then(data),
185
+ get: (id: string) => campaignAssetsApi.campaignAssetsGet({ id }).then(data),
186
+ create: (body: CampaignAssetCreate) => campaignAssetsApi.campaignAssetsCreate({ campaignAssetCreate: body }).then(data),
187
+ delete: (id: string) => campaignAssetsApi.campaignAssetsDelete({ id }).then(data),
188
+ };
189
+ const adAssetsApi = new AdAssetsApi(config);
190
+ this.adAssets = {
191
+ list: (p: ListParams & { adId?: string; adGroupId?: string; campaignId?: string; role?: string } = {}) => adAssetsApi.adAssetsList(p as any).then(data),
192
+ get: (id: string) => adAssetsApi.adAssetsGet({ id }).then(data),
193
+ create: (body: AdAssetCreate) => adAssetsApi.adAssetsCreate({ adAssetCreate: body }).then(data),
194
+ delete: (id: string) => adAssetsApi.adAssetsDelete({ id }).then(data),
195
+ };
196
+
197
+ const mediaApi = new MediaApi(config);
198
+ this.media = { matrix: () => mediaApi.mediaMatrix().then(data) };
199
+
200
+ const reportsApi = new ReportsApi(config);
201
+ this.reports = {
202
+ /** Performance stats; see the reference for `date_range`, `group_by`, `metrics`, etc. */
203
+ stats: (params: Record<string, any> = {}) => reportsApi.reportsStats(params as any).then(data),
204
+ };
205
+
206
+ const syncApi = new SyncApi(config);
207
+ this.sync = {
208
+ /** Trigger a sync for the active Space (async — poll `get(syncId)`). */
209
+ trigger: (body: SyncTriggerRequest = {}) => syncApi.syncTrigger({ syncTriggerRequest: body }).then(data),
210
+ list: (p: ListParams = {}) => syncApi.syncList(p).then(data),
211
+ /** Dry-run plan (import/export/remove) without executing. */
212
+ plan: (p: { platforms?: string } = {}) => syncApi.syncPlan(p as any).then(data),
213
+ get: (id: string) => syncApi.syncGet({ id }).then(data),
214
+ cancel: (id: string) => syncApi.syncCancel({ id }).then(data),
215
+ /** Unlink campaigns from a platform (keeps the local campaign). */
216
+ unlink: (body: SyncUnlinkRequest) => syncApi.syncUnlink({ syncUnlinkRequest: body }).then(data),
217
+ };
218
+
219
+ const metaApi = new MetaApi(config);
220
+ this.meta = {
221
+ /** Introspect the authenticated token. */
222
+ me: () => metaApi.meGet().then(data),
223
+ /** List Spaces the token can access. */
224
+ spaces: () => metaApi.spacesList().then(data),
225
+ };
226
+ }
227
+ }
228
+
229
+ export default DefoAds;