google-ads-api 20.0.0 → 20.0.1

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.
@@ -5,7 +5,7 @@ const service_1 = require("../../service");
5
5
  const index_1 = require("../index");
6
6
  class ServiceFactory extends service_1.Service {
7
7
  constructor(clientOptions, customerOptions, hooks) {
8
- super(clientOptions, customerOptions, hooks !== null && hooks !== void 0 ? hooks : {});
8
+ super(clientOptions, customerOptions, hooks ?? {});
9
9
  }
10
10
  /**
11
11
  * @link https://developers.google.com/google-ads/api/reference/rpc/v20/AccountBudgetProposalService
@@ -6,7 +6,7 @@ export import resources = protos.google.ads.googleads.v20.resources;
6
6
  export import services = protos.google.ads.googleads.v20.services;
7
7
  export import internalEnums = protos.google.ads.googleads.v20.enums;
8
8
  export { enums } from "./autogen/enums";
9
- export { fields } from "./autogen/fields";
9
+ export { fields, fieldDataTypes } from "./autogen/fields";
10
10
  export { GoogleAdsServiceClient } from "google-ads-node";
11
11
  export type AllServices = Omit<typeof allProtos, typeof VERSION>;
12
12
  export type ServiceName = keyof Omit<typeof allProtos, typeof VERSION>;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.longrunning = exports.protobuf = exports.GoogleAdsServiceClient = exports.fields = exports.enums = exports.internalEnums = exports.services = exports.resources = exports.errors = exports.common = exports.VERSION = void 0;
3
+ exports.longrunning = exports.protobuf = exports.GoogleAdsServiceClient = exports.fieldDataTypes = exports.fields = exports.enums = exports.internalEnums = exports.services = exports.resources = exports.errors = exports.common = exports.VERSION = void 0;
4
4
  const google_ads_node_1 = require("google-ads-node");
5
5
  const version_1 = require("../version");
6
6
  // "as vN" is required to avoid type issues later on
@@ -17,6 +17,7 @@ var enums_1 = require("./autogen/enums");
17
17
  Object.defineProperty(exports, "enums", { enumerable: true, get: function () { return enums_1.enums; } });
18
18
  var fields_1 = require("./autogen/fields");
19
19
  Object.defineProperty(exports, "fields", { enumerable: true, get: function () { return fields_1.fields; } });
20
+ Object.defineProperty(exports, "fieldDataTypes", { enumerable: true, get: function () { return fields_1.fieldDataTypes; } });
20
21
  // Common service used for report/query methods
21
22
  var google_ads_node_2 = require("google-ads-node");
22
23
  Object.defineProperty(exports, "GoogleAdsServiceClient", { enumerable: true, get: function () { return google_ads_node_2.GoogleAdsServiceClient; } });
@@ -51,7 +51,7 @@ exports.QueryError = {
51
51
  UNDEFINED_ENTITY: "The entity of the query must be defined.",
52
52
  };
53
53
  function buildSelectClause(attributes, metrics, segments) {
54
- if (!(attributes === null || attributes === void 0 ? void 0 : attributes.length) && !(metrics === null || metrics === void 0 ? void 0 : metrics.length) && !(segments === null || segments === void 0 ? void 0 : segments.length)) {
54
+ if (!attributes?.length && !metrics?.length && !segments?.length) {
55
55
  throw new Error(exports.QueryError.MISSING_FIELDS);
56
56
  }
57
57
  const selections = [
@@ -16,6 +16,7 @@ export declare class Service {
16
16
  get credentials(): CustomerCredentials;
17
17
  protected get callHeaders(): CallHeaders;
18
18
  private getCredentials;
19
+ getAccessToken(): Promise<string>;
19
20
  protected loadService<T = AllServices>(service: ServiceName): T;
20
21
  protected getGoogleAdsError(error: Error): errors.GoogleAdsFailure | Error;
21
22
  private decodeGoogleAdsFailureBuffer;
@@ -14,18 +14,26 @@ const ttlcache_1 = __importDefault(require("@isaacs/ttlcache"));
14
14
  exports.FAILURE_KEY = `google.ads.googleads.${version_1.googleAdsVersion}.errors.googleadsfailure-bin`;
15
15
  // A global service cache to avoid re-initialising services
16
16
  const serviceCache = new ttlcache_1.default({
17
- max: 1000,
17
+ max: 1_000,
18
18
  ttl: 10 * 60 * 1000, // 10 minutes
19
19
  dispose: async (service) => {
20
20
  // Close connections when services are removed from the cache
21
21
  await service.close();
22
22
  },
23
23
  });
24
+ // A global access token cache used by REST calls. Issued tokens expire after 1 hour, so we cache them for 50 minutes.
25
+ const accessTokenCache = new ttlcache_1.default({
26
+ max: 100_000,
27
+ ttl: 50 * 60 * 1000, // 50 minutes
28
+ });
24
29
  class Service {
30
+ clientOptions;
31
+ customerOptions;
32
+ hooks;
25
33
  constructor(clientOptions, customerOptions, hooks) {
26
34
  this.clientOptions = clientOptions;
27
35
  this.customerOptions = customerOptions;
28
- this.hooks = hooks !== null && hooks !== void 0 ? hooks : {};
36
+ this.hooks = hooks ?? {};
29
37
  // @ts-expect-error All fields don't need to be set here
30
38
  this.serviceCache = {};
31
39
  }
@@ -48,12 +56,30 @@ class Service {
48
56
  }
49
57
  return headers;
50
58
  }
59
+ // Used only by gRPC calls
51
60
  getCredentials() {
52
61
  const sslCreds = google_gax_1.grpc.credentials.createSsl();
53
62
  const authClient = new google_auth_library_1.UserRefreshClient(this.clientOptions.client_id, this.clientOptions.client_secret, this.customerOptions.refresh_token);
54
63
  const credentials = google_gax_1.grpc.credentials.combineChannelCredentials(sslCreds, google_gax_1.grpc.credentials.createFromGoogleCredential(authClient));
55
64
  return credentials;
56
65
  }
66
+ // Used only by REST calls
67
+ async getAccessToken() {
68
+ const cachedToken = accessTokenCache.get(this.customerOptions.refresh_token);
69
+ if (cachedToken) {
70
+ return cachedToken;
71
+ }
72
+ const oAuth2Client = new google_auth_library_1.OAuth2Client(this.clientOptions.client_id, this.clientOptions.client_secret);
73
+ oAuth2Client.setCredentials({
74
+ refresh_token: this.customerOptions.refresh_token,
75
+ });
76
+ const { token } = await oAuth2Client.getAccessToken();
77
+ if (typeof token !== "string") {
78
+ throw new Error("Failed to retrieve access token");
79
+ }
80
+ accessTokenCache.set(this.customerOptions.refresh_token, token);
81
+ return token;
82
+ }
57
83
  loadService(service) {
58
84
  const serviceCacheKey = `${service}_${this.customerOptions.refresh_token}`;
59
85
  if (serviceCache.has(serviceCacheKey)) {
@@ -72,9 +98,8 @@ class Service {
72
98
  return client;
73
99
  }
74
100
  getGoogleAdsError(error) {
75
- var _a;
76
101
  // @ts-expect-error No type exists for GA query error
77
- if (typeof ((_a = error === null || error === void 0 ? void 0 : error.metadata) === null || _a === void 0 ? void 0 : _a.internalRepr.get(exports.FAILURE_KEY)) === "undefined") {
102
+ if (typeof error?.metadata?.internalRepr.get(exports.FAILURE_KEY) === "undefined") {
78
103
  return error;
79
104
  }
80
105
  // @ts-expect-error No type exists for GA query error
@@ -86,13 +111,12 @@ class Service {
86
111
  return googleAdsFailure;
87
112
  }
88
113
  decodePartialFailureError(response) {
89
- var _a;
90
- if (typeof (response === null || response === void 0 ? void 0 : response.partial_failure_error) === "undefined" ||
91
- !(response === null || response === void 0 ? void 0 : response.partial_failure_error)) {
114
+ if (typeof response?.partial_failure_error === "undefined" ||
115
+ !response?.partial_failure_error) {
92
116
  return response;
93
117
  }
94
118
  const { details } = response.partial_failure_error;
95
- const buffer = (_a = details === null || details === void 0 ? void 0 : details.find((d) => d.type_url.includes("errors.GoogleAdsFailure"))) === null || _a === void 0 ? void 0 : _a.value;
119
+ const buffer = details?.find((d) => d.type_url.includes("errors.GoogleAdsFailure"))?.value;
96
120
  if (typeof buffer === "undefined") {
97
121
  return response;
98
122
  }
@@ -123,15 +147,13 @@ class Service {
123
147
  buildMutationRequestAndService(mutations, options) {
124
148
  const service = this.loadService("GoogleAdsServiceClient");
125
149
  const mutateOperations = mutations.map((mutation) => {
126
- var _a, _b;
127
150
  const opKey = (0, utils_1.toSnakeCase)(`${mutation.entity}Operation`);
128
151
  const operation = {
129
- [(_a = mutation.operation) !== null && _a !== void 0 ? _a : "create"]: mutation.resource,
152
+ [mutation.operation ?? "create"]: mutation.resource,
130
153
  };
131
154
  if (mutation.operation === "create" &&
132
- (
133
155
  //@ts-ignore
134
- (_b = mutation === null || mutation === void 0 ? void 0 : mutation.exempt_policy_violation_keys) === null || _b === void 0 ? void 0 : _b.length)) {
156
+ mutation?.exempt_policy_violation_keys?.length) {
135
157
  //@ts-ignore
136
158
  operation.exempt_policy_violation_keys =
137
159
  mutation.exempt_policy_violation_keys;
@@ -154,13 +176,12 @@ class Service {
154
176
  }
155
177
  buildOperations(type, entities, message) {
156
178
  const ops = entities.map((e) => {
157
- var _a;
158
179
  const op = {
159
180
  [type]: e,
160
181
  operation: type,
161
182
  };
162
183
  //@ts-ignore
163
- if (type === "create" && ((_a = e === null || e === void 0 ? void 0 : e.exempt_policy_violation_keys) === null || _a === void 0 ? void 0 : _a.length)) {
184
+ if (type === "create" && e?.exempt_policy_violation_keys?.length) {
164
185
  // @ts-expect-error Field required for policy violation exemptions
165
186
  op.exempt_policy_violation_keys = e.exempt_policy_violation_keys;
166
187
  //@ts-ignore
@@ -1,3 +1,4 @@
1
+ import { Readable } from "stream";
1
2
  import { Customer } from "./customer";
2
3
  import { Hooks } from "./hooks";
3
4
  import { errors, GoogleAdsServiceClient, services } from "./protos";
@@ -11,7 +12,39 @@ export declare const MOCK_LOGIN_CID = "MOCK LOGIN CID";
11
12
  export declare const mockGaqlQuery = "SELECT campaign.resource_name FROM campaign LIMIT 1";
12
13
  export declare const mockReportOptions: ReportOptions;
13
14
  export declare const mockMutations: MutateOperation<any>[];
15
+ export declare const mockSearchRawResult: {
16
+ totalResultsCount: number;
17
+ results: {
18
+ campaign: {
19
+ resourceName: string;
20
+ };
21
+ }[];
22
+ }[];
23
+ export declare const mockSearchRawResultWithSummaryRow: ({
24
+ totalResultsCount: number;
25
+ results: {
26
+ campaign: {
27
+ resourceName: string;
28
+ };
29
+ }[];
30
+ summaryRow?: undefined;
31
+ } | {
32
+ summaryRow: {
33
+ metrics: {
34
+ clicks: number;
35
+ impressions: number;
36
+ };
37
+ };
38
+ totalResultsCount?: undefined;
39
+ results?: undefined;
40
+ })[];
14
41
  export declare const mockQueryReturnValue: services.IGoogleAdsRow[];
42
+ export declare const mockQueryReturnValueWithSummaryRow: services.IGoogleAdsRow[];
43
+ export declare const mockQueryReturnValueUnparsed: {
44
+ campaign: {
45
+ resourceName: string;
46
+ };
47
+ }[];
15
48
  export declare const mockSummaryRow: services.IGoogleAdsRow;
16
49
  export declare const mockTotalResultsCount = 23;
17
50
  export declare const mockMutationReturnValue: services.MutateGoogleAdsResponse;
@@ -26,6 +59,10 @@ export declare const mockError: {
26
59
  export declare const mockErrorMessage = "mock error message";
27
60
  export declare const mockParseValue: services.IGoogleAdsRow;
28
61
  export declare const mockParsedValues: services.IGoogleAdsRow[];
62
+ export declare const mockStream: (data?: any) => Readable;
63
+ export declare function mockGetAccessToken(customer: Customer): jest.SpyInstance;
64
+ export declare const mockStreamWithSummaryRow: () => Readable;
65
+ export declare const mockStreamWithBadData: () => Readable;
29
66
  export declare function mockPaginatedSearch(customer: Customer, includeTotalResultsCount?: boolean): jest.SpyInstance;
30
67
  export declare function mockSearchOnce({ customer, response, nextPageToken, includeTotalResultsCount, }: {
31
68
  customer: Customer;
@@ -61,6 +98,7 @@ export declare function mockBuildMutateRequestAndService({ customer, shouldThrow
61
98
  export declare function mockGetGoogleAdsError(customer: Customer): jest.SpyInstance;
62
99
  export declare function mockQuery(customer: Customer): jest.SpyInstance;
63
100
  export declare function mockParse(mockParsedValues: services.IGoogleAdsRow[]): jest.SpyInstance;
101
+ export declare function mockParseRest(mockParsedValues: services.IGoogleAdsRow[]): jest.SpyInstance;
64
102
  export declare function noopParser(rows: services.IGoogleAdsRow[]): services.IGoogleAdsRow[];
65
103
  export declare function mockMethod(): {
66
104
  method(): void;
@@ -32,8 +32,12 @@ var __importStar = (this && this.__importStar) || (function () {
32
32
  return result;
33
33
  };
34
34
  })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
35
38
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.mockParsedValues = exports.mockParseValue = exports.mockErrorMessage = exports.mockError = exports.mockMutationReturnValue = exports.mockTotalResultsCount = exports.mockSummaryRow = exports.mockQueryReturnValue = exports.mockMutations = exports.mockReportOptions = exports.mockGaqlQuery = exports.MOCK_LOGIN_CID = exports.MOCK_CID = exports.MOCK_REFRESH_TOKEN = exports.MOCK_DEVELOPER_TOKEN = exports.MOCK_CLIENT_SECRET = exports.MOCK_CLIENT_ID = void 0;
39
+ exports.mockStreamWithBadData = exports.mockStreamWithSummaryRow = exports.mockStream = exports.mockParsedValues = exports.mockParseValue = exports.mockErrorMessage = exports.mockError = exports.mockMutationReturnValue = exports.mockTotalResultsCount = exports.mockSummaryRow = exports.mockQueryReturnValueUnparsed = exports.mockQueryReturnValueWithSummaryRow = exports.mockQueryReturnValue = exports.mockSearchRawResultWithSummaryRow = exports.mockSearchRawResult = exports.mockMutations = exports.mockReportOptions = exports.mockGaqlQuery = exports.MOCK_LOGIN_CID = exports.MOCK_CID = exports.MOCK_REFRESH_TOKEN = exports.MOCK_DEVELOPER_TOKEN = exports.MOCK_CLIENT_SECRET = exports.MOCK_CLIENT_ID = void 0;
40
+ exports.mockGetAccessToken = mockGetAccessToken;
37
41
  exports.mockPaginatedSearch = mockPaginatedSearch;
38
42
  exports.mockSearchOnce = mockSearchOnce;
39
43
  exports.mockBuildSearchStreamRequestAndService = mockBuildSearchStreamRequestAndService;
@@ -42,6 +46,7 @@ exports.mockBuildMutateRequestAndService = mockBuildMutateRequestAndService;
42
46
  exports.mockGetGoogleAdsError = mockGetGoogleAdsError;
43
47
  exports.mockQuery = mockQuery;
44
48
  exports.mockParse = mockParse;
49
+ exports.mockParseRest = mockParseRest;
45
50
  exports.noopParser = noopParser;
46
51
  exports.mockMethod = mockMethod;
47
52
  exports.failTestIfExecuted = failTestIfExecuted;
@@ -49,7 +54,9 @@ exports.newCustomer = newCustomer;
49
54
  const stream_1 = require("stream");
50
55
  const customer_1 = require("./customer");
51
56
  const parser = __importStar(require("./parser"));
57
+ const parserRest = __importStar(require("./parserRest"));
52
58
  const protos_1 = require("./protos");
59
+ const lodash_1 = __importDefault(require("lodash"));
53
60
  exports.MOCK_CLIENT_ID = "MOCK CLIENT ID";
54
61
  exports.MOCK_CLIENT_SECRET = "MOCK CLIENT SECRET";
55
62
  exports.MOCK_DEVELOPER_TOKEN = "MOCK DEVELOPER TOKEN";
@@ -65,11 +72,45 @@ exports.mockReportOptions = {
65
72
  exports.mockMutations = [
66
73
  { resource: "abc", entity: "campaign", operation: "create" },
67
74
  ];
75
+ exports.mockSearchRawResult = [
76
+ {
77
+ totalResultsCount: 23,
78
+ results: [
79
+ { campaign: { resourceName: "customers/1/campaigns/11" } },
80
+ { campaign: { resourceName: "customers/2/campaigns/22" } },
81
+ { campaign: { resourceName: "customers/3/campaigns/33" } },
82
+ ],
83
+ },
84
+ ];
85
+ exports.mockSearchRawResultWithSummaryRow = [
86
+ {
87
+ totalResultsCount: 23,
88
+ results: [
89
+ { campaign: { resourceName: "customers/1/campaigns/11" } },
90
+ { campaign: { resourceName: "customers/2/campaigns/22" } },
91
+ { campaign: { resourceName: "customers/3/campaigns/33" } },
92
+ ],
93
+ },
94
+ {
95
+ summaryRow: { metrics: { clicks: 90, impressions: 153 } },
96
+ },
97
+ ];
68
98
  exports.mockQueryReturnValue = [
69
99
  { campaign: { resource_name: "customers/1/campaigns/11" } },
70
100
  { campaign: { resource_name: "customers/2/campaigns/22" } },
71
101
  { campaign: { resource_name: "customers/3/campaigns/33" } },
72
102
  ];
103
+ exports.mockQueryReturnValueWithSummaryRow = [
104
+ { campaign: { resource_name: "customers/1/campaigns/11" } },
105
+ { campaign: { resource_name: "customers/2/campaigns/22" } },
106
+ { campaign: { resource_name: "customers/3/campaigns/33" } },
107
+ { metrics: { clicks: 90, impressions: 153 } },
108
+ ];
109
+ exports.mockQueryReturnValueUnparsed = [
110
+ { campaign: { resourceName: "customers/1/campaigns/11" } },
111
+ { campaign: { resourceName: "customers/2/campaigns/22" } },
112
+ { campaign: { resourceName: "customers/3/campaigns/33" } },
113
+ ];
73
114
  exports.mockSummaryRow = {
74
115
  metrics: { clicks: 90, impressions: 153 },
75
116
  };
@@ -97,17 +138,42 @@ exports.mockParsedValues = [
97
138
  exports.mockParseValue,
98
139
  exports.mockParseValue,
99
140
  ];
141
+ // Returns a stream that emits the provided values
142
+ const mockStream = function (data = exports.mockSearchRawResult) {
143
+ const chunks = lodash_1.default.chunk(JSON.stringify(data), 10).map((c) => c.join("")); // random splits
144
+ const stream = new stream_1.Readable({ objectMode: true });
145
+ chunks.forEach((value) => stream.push(new Buffer(value)));
146
+ stream.push(null);
147
+ return stream;
148
+ };
149
+ exports.mockStream = mockStream;
150
+ function mockGetAccessToken(customer) {
151
+ return (jest
152
+ .spyOn(customer, "getAccessToken")
153
+ // ts-expect-error
154
+ .mockImplementation(async () => {
155
+ return "mockedAccessTokenHere";
156
+ }));
157
+ }
158
+ const mockStreamWithSummaryRow = function () {
159
+ return (0, exports.mockStream)(exports.mockSearchRawResultWithSummaryRow);
160
+ };
161
+ exports.mockStreamWithSummaryRow = mockStreamWithSummaryRow;
162
+ const mockStreamWithBadData = function () {
163
+ return (0, exports.mockStream)({ results: 66 });
164
+ };
165
+ exports.mockStreamWithBadData = mockStreamWithBadData;
100
166
  function mockPaginatedSearch(customer, includeTotalResultsCount = false) {
101
167
  return (jest
102
168
  // @ts-expect-error private method
103
169
  .spyOn(customer, "paginatedSearch")
104
170
  // @ts-expect-error
105
- .mockImplementation((gaqlQuery, requestOptions, _parser) => {
171
+ .mockImplementation((gaqlQuery, requestOptions) => {
106
172
  const totalResultsCount = includeTotalResultsCount
107
173
  ? exports.mockTotalResultsCount
108
174
  : undefined;
109
175
  return {
110
- response: _parser(exports.mockQueryReturnValue),
176
+ response: exports.mockQueryReturnValue,
111
177
  totalResultsCount,
112
178
  };
113
179
  }));
@@ -198,7 +264,7 @@ function mockBuildMutateRequestAndService({ customer, shouldThrow = false, reque
198
264
  if (shouldThrow) {
199
265
  throw new Error(exports.mockErrorMessage);
200
266
  }
201
- return [response !== null && response !== void 0 ? response : exports.mockMutationReturnValue];
267
+ return [response ?? exports.mockMutationReturnValue];
202
268
  },
203
269
  };
204
270
  const spyBuild = jest
@@ -208,7 +274,7 @@ function mockBuildMutateRequestAndService({ customer, shouldThrow = false, reque
208
274
  .mockImplementation(() => {
209
275
  return {
210
276
  service: mockService,
211
- request: request !== null && request !== void 0 ? request : {},
277
+ request: request ?? {},
212
278
  };
213
279
  });
214
280
  return { mockService, spyBuild };
@@ -235,6 +301,11 @@ function mockQuery(customer) {
235
301
  function mockParse(mockParsedValues) {
236
302
  return jest.spyOn(parser, "parse").mockImplementation(() => mockParsedValues);
237
303
  }
304
+ function mockParseRest(mockParsedValues) {
305
+ return jest
306
+ .spyOn(parserRest, "decamelizeKeys")
307
+ .mockImplementation(() => mockParsedValues);
308
+ }
238
309
  function noopParser(rows) {
239
310
  return rows;
240
311
  }
@@ -47,8 +47,3 @@ export declare function toCamelCase(str: string): string;
47
47
  export declare function toSnakeCase(str: string): string;
48
48
  export declare function recursiveFieldMaskSearch(data: Record<string, any>): string[];
49
49
  export declare function getFieldMask(data: Record<string, any>): protobuf.FieldMask;
50
- export declare function createNextChunkArrivedPromise(): {
51
- newPromise: Promise<unknown>;
52
- resolve: () => void;
53
- reject: (error: Error) => void;
54
- };
@@ -8,7 +8,6 @@ exports.toCamelCase = toCamelCase;
8
8
  exports.toSnakeCase = toSnakeCase;
9
9
  exports.recursiveFieldMaskSearch = recursiveFieldMaskSearch;
10
10
  exports.getFieldMask = getFieldMask;
11
- exports.createNextChunkArrivedPromise = createNextChunkArrivedPromise;
12
11
  const protos_1 = require("./protos");
13
12
  /**
14
13
  * @param micros Money value in micros format
@@ -100,17 +99,3 @@ function getFieldMask(data) {
100
99
  paths,
101
100
  });
102
101
  }
103
- function createNextChunkArrivedPromise() {
104
- let resolvePromise = () => {
105
- return;
106
- };
107
- let rejectPromise = (error) => {
108
- throw error;
109
- };
110
- const newPromise = new Promise((resolve, reject) => {
111
- // @ts-ignore
112
- resolvePromise = resolve;
113
- rejectPromise = reject;
114
- });
115
- return { newPromise, resolve: resolvePromise, reject: rejectPromise };
116
- }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "google-ads-api",
3
- "version": "20.0.0",
3
+ "version": "20.0.1",
4
4
  "description": "Google Ads API Client Library for Node.js",
5
5
  "repository": "https://github.com/Opteo/google-ads-api",
6
6
  "main": "build/src/index.js",
@@ -11,7 +11,7 @@
11
11
  "test": "jest",
12
12
  "lint": "eslint . --ext .ts",
13
13
  "build": "tsc",
14
- "compile": "tsc && node build/scripts/index.js",
14
+ "compile": "esbuild --bundle --platform=node ./scripts/index.ts --outfile=./build/scripts/index.js && node ./build/scripts/index.js",
15
15
  "prepare": "rm -rf build && npm run build",
16
16
  "node": "tsx"
17
17
  },
@@ -19,22 +19,32 @@
19
19
  "license": "MIT",
20
20
  "dependencies": {
21
21
  "@isaacs/ttlcache": "^1.2.2",
22
- "google-ads-node": "17.0.0",
22
+ "axios": "^1.6.7",
23
+ "circ-json": "^1.0.4",
24
+ "google-ads-node": "17.0.1",
23
25
  "google-auth-library": "^9.15.1",
24
26
  "google-gax": "^5.1.1-rc.1",
25
- "long": "^4.0.0"
27
+ "long": "^4.0.0",
28
+ "map-obj": "^4.0.0",
29
+ "stream-json": "^1.8.0"
26
30
  },
27
31
  "devDependencies": {
28
32
  "@types/jest": "^29.0.1",
29
33
  "@types/long": "^4.0.0",
34
+ "@types/lodash": "^4.14.202",
30
35
  "@types/node": "^22.5.4",
31
36
  "@types/pluralize": "^0.0.29",
37
+ "@types/stream-json": "^1.7.7",
32
38
  "@typescript-eslint/eslint-plugin": "^4.8.2",
33
39
  "@typescript-eslint/parser": "^4.8.2",
40
+ "axios-mock-adapter": "^1.22.0",
41
+ "esbuild": "^0.20.1",
34
42
  "eslint": "^7.14.0",
35
- "jest": "^29.0.3",
43
+ "jest": "^29.7.0",
44
+ "lodash": "^4.17.21",
36
45
  "pluralize": "^8.0.0",
37
- "ts-jest": "^29.0.0",
46
+ "protobufjs": "^7.2.6",
47
+ "ts-jest": "^29.1.2",
38
48
  "tsx": "^4.19.3",
39
49
  "typescript": "^5.5.4"
40
50
  },