UNPKG

8.44 kBJavaScriptView Raw
1"use strict";
2var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3 if (k2 === undefined) k2 = k;
4 var desc = Object.getOwnPropertyDescriptor(m, k);
5 if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6 desc = { enumerable: true, get: function() { return m[k]; } };
7 }
8 Object.defineProperty(o, k2, desc);
9}) : (function(o, m, k, k2) {
10 if (k2 === undefined) k2 = k;
11 o[k2] = m[k];
12}));
13var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14 Object.defineProperty(o, "default", { enumerable: true, value: v });
15}) : function(o, v) {
16 o["default"] = v;
17});
18var __importStar = (this && this.__importStar) || function (mod) {
19 if (mod && mod.__esModule) return mod;
20 var result = {};
21 if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22 __setModuleDefault(result, mod);
23 return result;
24};
25Object.defineProperty(exports, "__esModule", { value: true });
26exports.Service = exports.DEFAULT_PROJECT_ID_TOKEN = void 0;
27/*!
28 * Copyright 2022 Google LLC. All Rights Reserved.
29 *
30 * Licensed under the Apache License, Version 2.0 (the "License");
31 * you may not use this file except in compliance with the License.
32 * You may obtain a copy of the License at
33 *
34 * http://www.apache.org/licenses/LICENSE-2.0
35 *
36 * Unless required by applicable law or agreed to in writing, software
37 * distributed under the License is distributed on an "AS IS" BASIS,
38 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
39 * See the License for the specific language governing permissions and
40 * limitations under the License.
41 */
42const google_auth_library_1 = require("google-auth-library");
43const uuid = __importStar(require("uuid"));
44const util_js_1 = require("./util.js");
45const util_js_2 = require("../util.js");
46exports.DEFAULT_PROJECT_ID_TOKEN = '{{projectId}}';
47class Service {
48 /**
49 * Service is a base class, meant to be inherited from by a "service," like
50 * BigQuery or Storage.
51 *
52 * This handles making authenticated requests by exposing a `makeReq_`
53 * function.
54 *
55 * @constructor
56 * @alias module:common/service
57 *
58 * @param {object} config - Configuration object.
59 * @param {string} config.baseUrl - The base URL to make API requests to.
60 * @param {string[]} config.scopes - The scopes required for the request.
61 * @param {object=} options - [Configuration object](#/docs).
62 */
63 constructor(config, options = {}) {
64 this.baseUrl = config.baseUrl;
65 this.apiEndpoint = config.apiEndpoint;
66 this.timeout = options.timeout;
67 this.globalInterceptors = Array.isArray(options.interceptors_)
68 ? options.interceptors_
69 : [];
70 this.interceptors = [];
71 this.packageJson = config.packageJson;
72 this.projectId = options.projectId || exports.DEFAULT_PROJECT_ID_TOKEN;
73 this.projectIdRequired = config.projectIdRequired !== false;
74 this.providedUserAgent = options.userAgent;
75 this.universeDomain = options.universeDomain || google_auth_library_1.DEFAULT_UNIVERSE;
76 this.customEndpoint = config.customEndpoint || false;
77 this.makeAuthenticatedRequest = util_js_1.util.makeAuthenticatedRequestFactory({
78 ...config,
79 projectIdRequired: this.projectIdRequired,
80 projectId: this.projectId,
81 authClient: options.authClient || config.authClient,
82 credentials: options.credentials,
83 keyFile: options.keyFilename,
84 email: options.email,
85 clientOptions: {
86 universeDomain: options.universeDomain,
87 ...options.clientOptions,
88 },
89 });
90 this.authClient = this.makeAuthenticatedRequest.authClient;
91 const isCloudFunctionEnv = !!process.env.FUNCTION_NAME;
92 if (isCloudFunctionEnv) {
93 this.interceptors.push({
94 request(reqOpts) {
95 reqOpts.forever = false;
96 return reqOpts;
97 },
98 });
99 }
100 }
101 /**
102 * Return the user's custom request interceptors.
103 */
104 getRequestInterceptors() {
105 // Interceptors should be returned in the order they were assigned.
106 return [].slice
107 .call(this.globalInterceptors)
108 .concat(this.interceptors)
109 .filter(interceptor => typeof interceptor.request === 'function')
110 .map(interceptor => interceptor.request);
111 }
112 getProjectId(callback) {
113 if (!callback) {
114 return this.getProjectIdAsync();
115 }
116 this.getProjectIdAsync().then(p => callback(null, p), callback);
117 }
118 async getProjectIdAsync() {
119 const projectId = await this.authClient.getProjectId();
120 if (this.projectId === exports.DEFAULT_PROJECT_ID_TOKEN && projectId) {
121 this.projectId = projectId;
122 }
123 return this.projectId;
124 }
125 request_(reqOpts, callback) {
126 reqOpts = { ...reqOpts, timeout: this.timeout };
127 const isAbsoluteUrl = reqOpts.uri.indexOf('http') === 0;
128 const uriComponents = [this.baseUrl];
129 if (this.projectIdRequired) {
130 if (reqOpts.projectId) {
131 uriComponents.push('projects');
132 uriComponents.push(reqOpts.projectId);
133 }
134 else {
135 uriComponents.push('projects');
136 uriComponents.push(this.projectId);
137 }
138 }
139 uriComponents.push(reqOpts.uri);
140 if (isAbsoluteUrl) {
141 uriComponents.splice(0, uriComponents.indexOf(reqOpts.uri));
142 }
143 reqOpts.uri = uriComponents
144 .map(uriComponent => {
145 const trimSlashesRegex = /^\/*|\/*$/g;
146 return uriComponent.replace(trimSlashesRegex, '');
147 })
148 .join('/')
149 // Some URIs have colon separators.
150 // Bad: https://.../projects/:list
151 // Good: https://.../projects:list
152 .replace(/\/:/g, ':');
153 const requestInterceptors = this.getRequestInterceptors();
154 const interceptorArray = Array.isArray(reqOpts.interceptors_)
155 ? reqOpts.interceptors_
156 : [];
157 interceptorArray.forEach(interceptor => {
158 if (typeof interceptor.request === 'function') {
159 requestInterceptors.push(interceptor.request);
160 }
161 });
162 requestInterceptors.forEach(requestInterceptor => {
163 reqOpts = requestInterceptor(reqOpts);
164 });
165 delete reqOpts.interceptors_;
166 const pkg = this.packageJson;
167 let userAgent = (0, util_js_2.getUserAgentString)();
168 if (this.providedUserAgent) {
169 userAgent = `${this.providedUserAgent} ${userAgent}`;
170 }
171 reqOpts.headers = {
172 ...reqOpts.headers,
173 'User-Agent': userAgent,
174 'x-goog-api-client': `${(0, util_js_2.getRuntimeTrackingString)()} gccl/${pkg.version}-${(0, util_js_2.getModuleFormat)()} gccl-invocation-id/${uuid.v4()}`,
175 };
176 if (reqOpts[util_js_1.GCCL_GCS_CMD_KEY]) {
177 reqOpts.headers['x-goog-api-client'] +=
178 ` gccl-gcs-cmd/${reqOpts[util_js_1.GCCL_GCS_CMD_KEY]}`;
179 }
180 if (reqOpts.shouldReturnStream) {
181 return this.makeAuthenticatedRequest(reqOpts);
182 }
183 else {
184 this.makeAuthenticatedRequest(reqOpts, callback);
185 }
186 }
187 /**
188 * Make an authenticated API request.
189 *
190 * @param {object} reqOpts - Request options that are passed to `request`.
191 * @param {string} reqOpts.uri - A URI relative to the baseUrl.
192 * @param {function} callback - The callback function passed to `request`.
193 */
194 request(reqOpts, callback) {
195 Service.prototype.request_.call(this, reqOpts, callback);
196 }
197 /**
198 * Make an authenticated API request.
199 *
200 * @param {object} reqOpts - Request options that are passed to `request`.
201 * @param {string} reqOpts.uri - A URI relative to the baseUrl.
202 */
203 requestStream(reqOpts) {
204 const opts = { ...reqOpts, shouldReturnStream: true };
205 return Service.prototype.request_.call(this, opts);
206 }
207}
208exports.Service = Service;