UNPKG

9.64 kBJavaScriptView Raw
1"use strict";
2
3// Copyright 2019 Google LLC
4//
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16var __createBinding = this && this.__createBinding || (Object.create ? function (o, m, k, k2) {
17 if (k2 === undefined) k2 = k;
18 var desc = Object.getOwnPropertyDescriptor(m, k);
19 if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
20 desc = {
21 enumerable: true,
22 get: function () {
23 return m[k];
24 }
25 };
26 }
27 Object.defineProperty(o, k2, desc);
28} : function (o, m, k, k2) {
29 if (k2 === undefined) k2 = k;
30 o[k2] = m[k];
31});
32var __setModuleDefault = this && this.__setModuleDefault || (Object.create ? function (o, v) {
33 Object.defineProperty(o, "default", {
34 enumerable: true,
35 value: v
36 });
37} : function (o, v) {
38 o["default"] = v;
39});
40var __importStar = this && this.__importStar || function (mod) {
41 if (mod && mod.__esModule) return mod;
42 var result = {};
43 if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
44 __setModuleDefault(result, mod);
45 return result;
46};
47Object.defineProperty(exports, "__esModule", {
48 value: true
49});
50exports.PassThroughShim = void 0;
51exports.normalize = normalize;
52exports.objectEntries = objectEntries;
53exports.fixedEncodeURIComponent = fixedEncodeURIComponent;
54exports.encodeURI = encodeURI;
55exports.qsStringify = qsStringify;
56exports.objectKeyToLowercase = objectKeyToLowercase;
57exports.unicodeJSONStringify = unicodeJSONStringify;
58exports.convertObjKeysToSnakeCase = convertObjKeysToSnakeCase;
59exports.formatAsUTCISO = formatAsUTCISO;
60exports.getRuntimeTrackingString = getRuntimeTrackingString;
61exports.getUserAgentString = getUserAgentString;
62exports.getDirName = getDirName;
63exports.getModuleFormat = getModuleFormat;
64const path = __importStar(require("path"));
65const querystring = __importStar(require("querystring"));
66const stream_1 = require("stream");
67const url = __importStar(require("url"));
68// eslint-disable-next-line @typescript-eslint/ban-ts-comment
69// @ts-ignore
70const package_json_helper_cjs_1 = require("./package-json-helper.cjs");
71// Done to avoid a problem with mangling of identifiers when using esModuleInterop
72const fileURLToPath = url.fileURLToPath;
73const isEsm = false;
74function normalize(optionsOrCallback, cb) {
75 const options = typeof optionsOrCallback === 'object' ? optionsOrCallback : {};
76 const callback = typeof optionsOrCallback === 'function' ? optionsOrCallback : cb;
77 return {
78 options,
79 callback
80 };
81}
82/**
83 * Flatten an object into an Array of arrays, [[key, value], ..].
84 * Implements Object.entries() for Node.js <8
85 * @internal
86 */
87function objectEntries(obj) {
88 return Object.keys(obj).map(key => [key, obj[key]]);
89}
90/**
91 * Encode `str` with encodeURIComponent, plus these
92 * reserved characters: `! * ' ( )`.
93 *
94 * See {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent| MDN: fixedEncodeURIComponent}
95 *
96 * @param {string} str The URI component to encode.
97 * @return {string} The encoded string.
98 */
99function fixedEncodeURIComponent(str) {
100 return encodeURIComponent(str).replace(/[!'()*]/g, c => '%' + c.charCodeAt(0).toString(16).toUpperCase());
101}
102/**
103 * URI encode `uri` for generating signed URLs, using fixedEncodeURIComponent.
104 *
105 * Encode every byte except `A-Z a-Z 0-9 ~ - . _`.
106 *
107 * @param {string} uri The URI to encode.
108 * @param [boolean=false] encodeSlash If `true`, the "/" character is not encoded.
109 * @return {string} The encoded string.
110 */
111function encodeURI(uri, encodeSlash) {
112 // Split the string by `/`, and conditionally rejoin them with either
113 // %2F if encodeSlash is `true`, or '/' if `false`.
114 return uri.split('/').map(fixedEncodeURIComponent).join(encodeSlash ? '%2F' : '/');
115}
116/**
117 * Serialize an object to a URL query string using util.encodeURI(uri, true).
118 * @param {string} url The object to serialize.
119 * @return {string} Serialized string.
120 */
121function qsStringify(qs) {
122 return querystring.stringify(qs, '&', '=', {
123 encodeURIComponent: component => encodeURI(component, true)
124 });
125}
126function objectKeyToLowercase(object) {
127 const newObj = {};
128 for (let key of Object.keys(object)) {
129 const value = object[key];
130 key = key.toLowerCase();
131 newObj[key] = value;
132 }
133 return newObj;
134}
135/**
136 * JSON encode str, with unicode \u+ representation.
137 * @param {object} obj The object to encode.
138 * @return {string} Serialized string.
139 */
140function unicodeJSONStringify(obj) {
141 return JSON.stringify(obj).replace(/[\u0080-\uFFFF]/g, char => '\\u' + ('0000' + char.charCodeAt(0).toString(16)).slice(-4));
142}
143/**
144 * Converts the given objects keys to snake_case
145 * @param {object} obj object to convert keys to snake case.
146 * @returns {object} object with keys converted to snake case.
147 */
148function convertObjKeysToSnakeCase(obj) {
149 if (obj instanceof Date || obj instanceof RegExp) {
150 return obj;
151 }
152 if (Array.isArray(obj)) {
153 return obj.map(convertObjKeysToSnakeCase);
154 }
155 if (obj instanceof Object) {
156 return Object.keys(obj).reduce((acc, cur) => {
157 const s = cur[0].toLocaleLowerCase() + cur.slice(1).replace(/([A-Z]+)/g, (match, p1) => {
158 return `_${p1.toLowerCase()}`;
159 });
160 acc[s] = convertObjKeysToSnakeCase(obj[cur]);
161 return acc;
162 }, Object());
163 }
164 return obj;
165}
166/**
167 * Formats the provided date object as a UTC ISO string.
168 * @param {Date} dateTimeToFormat date object to be formatted.
169 * @param {boolean} includeTime flag to include hours, minutes, seconds in output.
170 * @param {string} dateDelimiter delimiter between date components.
171 * @param {string} timeDelimiter delimiter between time components.
172 * @returns {string} UTC ISO format of provided date obect.
173 */
174function formatAsUTCISO(dateTimeToFormat, includeTime = false, dateDelimiter = '', timeDelimiter = '') {
175 const year = dateTimeToFormat.getUTCFullYear();
176 const month = dateTimeToFormat.getUTCMonth() + 1;
177 const day = dateTimeToFormat.getUTCDate();
178 const hour = dateTimeToFormat.getUTCHours();
179 const minute = dateTimeToFormat.getUTCMinutes();
180 const second = dateTimeToFormat.getUTCSeconds();
181 let resultString = `${year.toString().padStart(4, '0')}${dateDelimiter}${month.toString().padStart(2, '0')}${dateDelimiter}${day.toString().padStart(2, '0')}`;
182 if (includeTime) {
183 resultString = `${resultString}T${hour.toString().padStart(2, '0')}${timeDelimiter}${minute.toString().padStart(2, '0')}${timeDelimiter}${second.toString().padStart(2, '0')}Z`;
184 }
185 return resultString;
186}
187/**
188 * Examines the runtime environment and returns the appropriate tracking string.
189 * @returns {string} metrics tracking string based on the current runtime environment.
190 */
191function getRuntimeTrackingString() {
192 if (
193 // eslint-disable-next-line @typescript-eslint/ban-ts-comment
194 // @ts-ignore
195 globalThis.Deno &&
196 // eslint-disable-next-line @typescript-eslint/ban-ts-comment
197 // @ts-ignore
198 globalThis.Deno.version &&
199 // eslint-disable-next-line @typescript-eslint/ban-ts-comment
200 // @ts-ignore
201 globalThis.Deno.version.deno) {
202 // eslint-disable-next-line @typescript-eslint/ban-ts-comment
203 // @ts-ignore
204 return `gl-deno/${globalThis.Deno.version.deno}`;
205 } else {
206 return `gl-node/${process.versions.node}`;
207 }
208}
209/**
210 * Looks at package.json and creates the user-agent string to be applied to request headers.
211 * @returns {string} user agent string.
212 */
213function getUserAgentString() {
214 const pkg = (0, package_json_helper_cjs_1.getPackageJSON)();
215 const hyphenatedPackageName = pkg.name.replace('@google-cloud', 'gcloud-node') // For legacy purposes.
216 .replace('/', '-'); // For UA spec-compliance purposes.
217 return hyphenatedPackageName + '/' + pkg.version;
218}
219function getDirName() {
220 let dirToUse = '';
221 try {
222 dirToUse = __dirname;
223 } catch (e) {
224 // eslint-disable-next-line @typescript-eslint/ban-ts-comment
225 // @ts-ignore
226 dirToUse = __dirname;
227 }
228 return dirToUse;
229}
230function getModuleFormat() {
231 return isEsm ? 'ESM' : 'CJS';
232}
233class PassThroughShim extends stream_1.PassThrough {
234 constructor() {
235 super(...arguments);
236 this.shouldEmitReading = true;
237 this.shouldEmitWriting = true;
238 }
239 _read(size) {
240 if (this.shouldEmitReading) {
241 this.emit('reading');
242 this.shouldEmitReading = false;
243 }
244 super._read(size);
245 }
246 _write(chunk, encoding, callback) {
247 if (this.shouldEmitWriting) {
248 this.emit('writing');
249 this.shouldEmitWriting = false;
250 }
251 // Per the nodejs documention, callback must be invoked on the next tick
252 process.nextTick(() => {
253 super._write(chunk, encoding, callback);
254 });
255 }
256 _final(callback) {
257 // If the stream is empty (i.e. empty file) final will be invoked before _read / _write
258 // and we should still emit the proper events.
259 if (this.shouldEmitReading) {
260 this.emit('reading');
261 this.shouldEmitReading = false;
262 }
263 if (this.shouldEmitWriting) {
264 this.emit('writing');
265 this.shouldEmitWriting = false;
266 }
267 callback(null);
268 }
269}
270exports.PassThroughShim = PassThroughShim;