@google-cloud/nodejs-common 1.7.9-alpha → 1.8.1-alpha

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@google-cloud/nodejs-common",
3
- "version": "1.7.9-alpha",
3
+ "version": "1.8.1-alpha",
4
4
  "description": "A NodeJs common library for solutions based on Cloud Functions",
5
5
  "author": "Google Inc.",
6
6
  "license": "Apache-2.0",
@@ -27,11 +27,12 @@
27
27
  "@google-cloud/scheduler": "^4.0.0",
28
28
  "@google-cloud/secret-manager": "^5.0.0",
29
29
  "gaxios": "^6.1.0",
30
- "google-ads-api": "^13.0.1",
31
- "google-ads-node": "^11.0.0",
30
+ "google-ads-api": "^14.1.0",
31
+ "google-ads-node": "^12.0.2",
32
32
  "google-auth-library": "^9.0.0",
33
33
  "googleapis": "^126.0.1",
34
34
  "winston": "^3.10.0",
35
+ "@grpc/grpc-js": "1.9.5",
35
36
  "lodash": "^4.17.21"
36
37
  },
37
38
  "devDependencies": {
@@ -18,8 +18,7 @@
18
18
 
19
19
  'use strict';
20
20
 
21
- const {request, GaxiosOptions} = require('gaxios');
22
- const AuthClient = require('./auth_client.js');
21
+ const { AuthRestfulApi } = require('./base/auth_restful_api.js');
23
22
 
24
23
  const API_SCOPES = Object.freeze([
25
24
  'https://www.googleapis.com/auth/adsdatahub',
@@ -31,7 +30,7 @@ const API_ENDPOINT = 'https://adsdatahub.googleapis.com';
31
30
  * Ads Data Hub (ADH) API connector class based on ADH REST API.
32
31
  * @see: https://developers.google.com/ads-data-hub/reference/rest
33
32
  */
34
- class AdsDataHub {
33
+ class AdsDataHub extends AuthRestfulApi {
35
34
  /**
36
35
  * Constructor.
37
36
  *
@@ -41,20 +40,19 @@ class AdsDataHub {
41
40
  * variables.
42
41
  */
43
42
  constructor(options, customerId = undefined, env = process.env) {
44
- this.authClient = new AuthClient(API_SCOPES, env);
43
+ super(env);
45
44
  /** @const{GaxiosOptions} */ this.options = options || {};
46
45
  /** @const{string|undefined=} */ this.customerId = customerId;
47
46
  }
48
47
 
49
- /**
50
- * Gets the auth object.
51
- * @return {!Promise<{!OAuth2Client|!JWT|!Compute}>}
52
- */
53
- async getAuth_() {
54
- if (this.auth) return this.auth;
55
- await this.authClient.prepareCredentials();
56
- this.auth = this.authClient.getDefaultAuth();
57
- return this.auth;
48
+ /** @override */
49
+ getScope() {
50
+ return API_SCOPES;
51
+ }
52
+
53
+ /** @override */
54
+ getBaseUrl() {
55
+ return `${API_ENDPOINT}/${API_VERSION}`;
58
56
  }
59
57
 
60
58
  /**
@@ -74,37 +72,6 @@ class AdsDataHub {
74
72
  return `customers/${customerId}/analysisQueries/${queryName}`;
75
73
  }
76
74
 
77
- /**
78
- * Returns the base Url of API service.
79
- * @return {string} Base Url.
80
- * @private
81
- */
82
- getRequestBaseUrl_() {
83
- return `${API_ENDPOINT}/${API_VERSION}/`;
84
- }
85
-
86
- /**
87
- * Sends a request to server and return the response body.
88
- * @param {string} path Request relative path.
89
- * @param {string=} method HTTP method, default is 'GET'.
90
- * @param {Object|undefined=} data HTTP data to send
91
- * @return {!Promise<Object>} Response body.
92
- * @private
93
- */
94
- async sendRequestAndReturnResponse_(path, method = 'GET', data = undefined) {
95
- const auth = await this.getAuth_();
96
- const headers = await auth.getRequestHeaders();
97
- const url = this.getRequestBaseUrl_() + path;
98
- const response = await request(/** @type {GaxiosOptions} */
99
- Object.assign({}, this.options, {
100
- url,
101
- method,
102
- headers,
103
- data,
104
- }));
105
- return response.data;
106
- }
107
-
108
75
  /**
109
76
  * Retrieves the requested analysis query. If query doesn't exist, it will
110
77
  * throw an error.
@@ -116,24 +83,24 @@ class AdsDataHub {
116
83
  */
117
84
  async getQuery(queryName, customerId = this.customerId) {
118
85
  const uniqueQueryName = this.getUniqueQueryName_(queryName, customerId);
119
- return this.sendRequestAndReturnResponse_(uniqueQueryName);
86
+ const response = await this.request(uniqueQueryName);
87
+ return response.data;
120
88
  }
121
89
 
122
90
  /**
123
91
  * Lists the analysis queries owned by the specified customer.
124
92
  * @see https://developers.google.com/ads-data-hub/reference/rest/v1/customers.analysisQueries/list
125
- * @param {Object=} parameters The query parameter object.
126
93
  * @param {string=} customerId
127
94
  * @return {!Promise<{
128
- * queries:Array<Object>,
129
- * nextPageToken:string,
130
- * }>}
131
- */
95
+ * queries:Array<Object>,
96
+ * nextPageToken:string,
97
+ * }>}
98
+ */
132
99
  async listQuery(parameters = {}, customerId = this.customerId) {
133
- const querystring = this.getQueryString_(parameters);
134
- const path = `customers/${customerId}/analysisQueries`
135
- + (querystring ? `?${querystring}` : '');
136
- return this.sendRequestAndReturnResponse_(path);
100
+ const querystring = this.getQueryString(parameters);
101
+ const path = `customers/${customerId}/analysisQueries${querystring}`;
102
+ const response = await this.request(path);
103
+ return response.data;
137
104
  }
138
105
 
139
106
  /**
@@ -157,22 +124,8 @@ class AdsDataHub {
157
124
  async startTransientQuery(queryText, spec, destTable, customerId = this.customerId) {
158
125
  const path = `customers/${customerId}/analysisQueries:startTransient`;
159
126
  const data = { query: { queryText }, spec, destTable };
160
- return this.sendRequestAndReturnResponse_(path, 'POST', data);
161
- }
162
-
163
- /**
164
- * Creates a query and returns the unique query name in the form of
165
- * 'customers/[customerId]/analysisQueries/[resource_id]'.
166
- * @see https://developers.google.com/ads-data-hub/reference/rest/v1/customers.analysisQueries/create
167
- * @param {string} title The title of the query.
168
- * @param {string} queryText The content of the query
169
- * @return {!Promise<string>} Promised unique name of created query.
170
- */
171
- async createQuery(title, queryText) {
172
- const path = `customers/${this.customerId}/analysisQueries`;
173
- const data = {title, queryText,};
174
- const query = await this.sendRequestAndReturnResponse_(path, 'POST', data);
175
- return query.name;
127
+ const response = await this.request(path, 'POST', data);
128
+ return response.data;
176
129
  }
177
130
 
178
131
  /**
@@ -198,7 +151,23 @@ class AdsDataHub {
198
151
  async startQuery(uniqueQueryName, spec, destTable, customerId = undefined) {
199
152
  const path = `${uniqueQueryName}:start`;
200
153
  const data = {spec, destTable, customerId};
201
- return this.sendRequestAndReturnResponse_(path, 'POST', data);
154
+ const response = await this.request(path, 'POST', data);
155
+ return response.data;
156
+ }
157
+
158
+ /**
159
+ * Creates a query and returns the unique query name in the form of
160
+ * 'customers/[customerId]/analysisQueries/[resource_id]'.
161
+ * @see https://developers.google.com/ads-data-hub/reference/rest/v1/customers.analysisQueries/create
162
+ * @param {string} title The title of the query.
163
+ * @param {string} queryText The content of the query
164
+ * @return {!Promise<string>} Promised unique name of created query.
165
+ */
166
+ async createQuery(title, queryText) {
167
+ const path = `customers/${this.customerId}/analysisQueries`;
168
+ const data = { title, queryText, };
169
+ const response = await this.request(path, 'POST', data);
170
+ return response.data.name;
202
171
  }
203
172
 
204
173
  /**
@@ -210,7 +179,8 @@ class AdsDataHub {
210
179
  */
211
180
  async deleteQuery(queryName, customerId = this.customerId) {
212
181
  const uniqueQueryName = this.getUniqueQueryName_(queryName, customerId);
213
- return this.sendRequestAndReturnResponse_(uniqueQueryName, 'DELETE');
182
+ const response = await this.request(uniqueQueryName, 'DELETE');
183
+ return response.data;
214
184
  }
215
185
 
216
186
  /**
@@ -221,21 +191,14 @@ class AdsDataHub {
221
191
  * @see https://developers.google.com/ads-data-hub/reference/rest/v1/operations#Operation
222
192
  */
223
193
  async getQueryStatus(operationName) {
224
- return this.sendRequestAndReturnResponse_(operationName);
225
- }
226
-
227
- /**
228
- * Gets the query string of a parameter object.
229
- * @param {Object} parameters The object of key-value pairs which will be
230
- * converted into query string format.
231
- * @return string
232
- * @private
233
- */
234
- getQueryString_(parameters = {}) {
235
- return Object.keys(parameters)
236
- .map((key) => key + '=' + encodeURIComponent(parameters[key]))
237
- .join('&');
194
+ const response = await this.request(operationName);
195
+ return response.data;
238
196
  }
239
197
  }
240
198
 
241
- exports.AdsDataHub = AdsDataHub;
199
+ module.exports = {
200
+ AdsDataHub,
201
+ API_SCOPES,
202
+ API_VERSION,
203
+ API_ENDPOINT,
204
+ };
@@ -0,0 +1,59 @@
1
+ // Copyright 2023 Google Inc.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ /**
16
+ * @fileoverview A base class for RESTful API with authorization client.
17
+ */
18
+
19
+ const { RestfuleApiBase } = require('./restful_api_base');
20
+ const AuthClient = require('../auth_client.js');
21
+
22
+ /**
23
+ * A RESTful API class with authorization client.
24
+ */
25
+ class AuthRestfulApi extends RestfuleApiBase {
26
+
27
+ /**
28
+ * Returns the Api scope for authorization.
29
+ * @return {!Array<string>}
30
+ * @abstract
31
+ */
32
+ getScope() { }
33
+
34
+ /**
35
+ * Gets the auth object.
36
+ * @return {!Promise<{!OAuth2Client|!JWT|!Compute}>}
37
+ */
38
+ async getAuth() {
39
+ if (this.auth) return this.auth;
40
+ this.authClient = new AuthClient(this.getScope(), this.env);
41
+ await this.authClient.prepareCredentials();
42
+ this.auth = this.authClient.getDefaultAuth();
43
+ return this.auth;
44
+ }
45
+
46
+ /**
47
+ * Returns HTTP headers. By default, it contains access token.
48
+ * @return {object} HTTP headers.
49
+ * @override
50
+ */
51
+ async getDefaultHeaders() {
52
+ const auth = await this.getAuth();
53
+ const headers = await auth.getRequestHeaders();
54
+ return Object.assign({}, super.getDefaultHeaders(), headers);
55
+ }
56
+
57
+ }
58
+
59
+ module.exports = { AuthRestfulApi };
@@ -0,0 +1,143 @@
1
+ // Copyright 2023 Google Inc.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ /**
16
+ * @fileoverview A base class for RESTful API based on gaxios.
17
+ */
18
+
19
+ const {
20
+ request: gaxiosRequest,
21
+ GaxiosResponse,
22
+ GaxiosOptions,
23
+ } = require('gaxios');
24
+
25
+ /**
26
+ * A type for an Api response which is independent to the 'request' library.
27
+ * @typedef {{
28
+ * data:string,
29
+ * code:number,
30
+ * }}
31
+ */
32
+ let Response;
33
+
34
+ /**
35
+ * Base class for RESTful API based on gaxios.
36
+ * @see https://github.com/googleapis/gaxios
37
+ */
38
+ class RestfuleApiBase {
39
+
40
+ constructor(env = process.env) {
41
+ this.env = env;
42
+ }
43
+
44
+ /**
45
+ * Returns the base Url of the Api request.
46
+ * @return {string}
47
+ * @abstract
48
+ */
49
+ getBaseUrl() { }
50
+
51
+ /**
52
+ * Returns default HTTP headers.
53
+ * @return {object} HTTP headers.
54
+ */
55
+ async getDefaultHeaders() {
56
+ return {};
57
+ }
58
+
59
+ /**
60
+ * Gets an object as request options.
61
+ * @return {Object=}
62
+ */
63
+ getRequesterOptions() {
64
+ return {
65
+ responseType: 'json',
66
+ };
67
+ }
68
+
69
+ /**
70
+ * Gets a response object. Different `request` libraries can be used in
71
+ * different situations. This function is used to isolate the different
72
+ * responses from different `request` libraries.
73
+ * @param {GaxiosResponse} response
74
+ * @return {!Response}
75
+ */
76
+ getResponseProcessor(response) {
77
+ return {
78
+ data: response.data,
79
+ code: response.status,
80
+ };
81
+ }
82
+
83
+ /**
84
+ * Sends our a request and returns the response.
85
+ * @param {string|undefined} uri
86
+ * @param {string=} method
87
+ * @param {object|undefined} data
88
+ * @param {object|undefined} headers
89
+ * @return {!Response}
90
+ */
91
+ async request(uri, method = 'GET', data, headers) {
92
+ /** @type {GaxiosOptions} */
93
+ const options = Object.assign(
94
+ this.getRequesterOptions(),
95
+ {
96
+ url: this.getRequestUrl(uri),
97
+ method,
98
+ headers: headers || await this.getDefaultHeaders(),
99
+ data,
100
+ }
101
+ );
102
+ return this.getResponseProcessor(await gaxiosRequest(options));
103
+ }
104
+
105
+ /**
106
+ * Constructs the fully-qualified URL to the API using the given @param
107
+ * {requestUri}.
108
+ * If it is an absolute url, return it directly;
109
+ * Otherwise append it after base url which is defined in detail API classes.
110
+ *
111
+ * @param {string} requestUri The URI of the specific resource to request.
112
+ * @return {string} representing the fully-qualified API URL.
113
+ */
114
+ getRequestUrl(requestUri) {
115
+ const baseUrl = this.getBaseUrl();
116
+ if (requestUri) {
117
+ if (requestUri.toLocaleLowerCase().startsWith('http')) return requestUri;
118
+ return `${baseUrl}/${requestUri}`;
119
+ }
120
+ return baseUrl;
121
+ }
122
+
123
+ /**
124
+ * Gets the URL encoded querystring from a parameter object.
125
+ * If a parameter is an array, the parameter will be in the querystring for
126
+ * multiple times.
127
+ * @param {object} params.
128
+ * @return {string} A querystring which starts with '?'.
129
+ */
130
+ getQueryString(params) {
131
+ if (!params || Object.keys(params).length === 0) return '';
132
+ return '?' + Object.keys(params).map((key) => {
133
+ if (!Array.isArray(params[key]))
134
+ return `${key}=${encodeURIComponent(params[key])}`;
135
+ return params[key].map((v) => `${key}=${encodeURIComponent(v)}`).join('&');
136
+ }).join('&');
137
+ }
138
+ }
139
+
140
+ module.exports = {
141
+ Response,
142
+ RestfuleApiBase,
143
+ };
package/src/apis/index.js CHANGED
@@ -106,7 +106,12 @@ exports.googleads = require('./google_ads.js');
106
106
 
107
107
  /**
108
108
  * APIs integration class for Ads Data Hub.
109
- * @const {{AdsDataHub:!AdsDataHub}}
109
+ * @const {{
110
+ * AdsDataHub:!AdsDataHub,
111
+ * API_SCOPES: !Array<string>,
112
+ * API_VERSION: string,
113
+ * API_ENDPOINT: string,
114
+ * }}
110
115
  */
111
116
  exports.adsdatahub = require('./ads_data_hub.js');
112
117
 
@@ -128,3 +133,13 @@ exports.measurementprotocolga4 = require('./measurement_protocol_ga4.js');
128
133
  * }}
129
134
  */
130
135
  exports.youtube = require('./youtube.js');
136
+
137
+ /**
138
+ * APIs integration class for SendGrid.
139
+ * @const {{
140
+ * SendGrid:!SendGrid,
141
+ * API_VERSION: string,
142
+ * API_ENDPOINT: string,
143
+ * }}
144
+ */
145
+ exports.sendgrid = require('./sendgrid.js');
@@ -0,0 +1,65 @@
1
+ // Copyright 2023 Google Inc.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ /**
16
+ * @fileoverview SendGrip API class.
17
+ */
18
+
19
+ 'use strict';
20
+
21
+ const { RestfuleApiBase } = require('./base/restful_api_base.js');
22
+ const { getLogger } = require('../components/utils.js');
23
+
24
+ const API_VERSION = 'v3';
25
+ const API_ENDPOINT = 'https://api.sendgrid.com';
26
+
27
+ /**
28
+ * SendGrid API access class.
29
+ * @see https://docs.sendgrid.com/api-reference/how-to-use-the-sendgrid-v3-api/authentication
30
+ */
31
+ class SendGrid extends RestfuleApiBase {
32
+
33
+ constructor(apiKey, env = process.env) {
34
+ super(env);
35
+ this.apiKey = apiKey;
36
+ this.logger = getLogger('SendGrid');
37
+ }
38
+
39
+ /** @override */
40
+ getBaseUrl() {
41
+ return `${API_ENDPOINT}/${API_VERSION}`;
42
+ }
43
+
44
+ /** @override */
45
+ async getDefaultHeaders() {
46
+ return Object.assign({}, super.getDefaultHeaders(), {
47
+ Authorization: `Bearer ${this.apiKey}`,
48
+ });
49
+ }
50
+
51
+ /**
52
+ * Sends an email.
53
+ * @see https://docs.sendgrid.com/api-reference/mail-send/mail-send
54
+ */
55
+ async sendMail(email) {
56
+ const response = await this.request('mail/send', 'POST', email);
57
+ return response;
58
+ }
59
+ }
60
+
61
+ module.exports = {
62
+ SendGrid,
63
+ API_VERSION,
64
+ API_ENDPOINT,
65
+ };