UNPKG

67.3 kBJavaScriptView Raw
1/******/ (() => { // webpackBootstrap
2/******/ "use strict";
3/******/ var __webpack_modules__ = ({
4
5/***/ "./src/Context.ts":
6/*!************************!*\
7 !*** ./src/Context.ts ***!
8 \************************/
9/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
10
11
12// Copyright (c) .NET Foundation. All rights reserved.
13// Licensed under the MIT License.
14Object.defineProperty(exports, "__esModule", ({ value: true }));
15exports.CreateContextAndInputs = void 0;
16const uuid_1 = __webpack_require__(/*! uuid */ "uuid");
17const BindingConverters_1 = __webpack_require__(/*! ./converters/BindingConverters */ "./src/converters/BindingConverters.ts");
18const RpcConverters_1 = __webpack_require__(/*! ./converters/RpcConverters */ "./src/converters/RpcConverters.ts");
19const Request_1 = __webpack_require__(/*! ./http/Request */ "./src/http/Request.ts");
20const Response_1 = __webpack_require__(/*! ./http/Response */ "./src/http/Response.ts");
21function CreateContextAndInputs(info, request, userLogCallback, doneEmitter) {
22 const context = new InvocationContext(info, request, userLogCallback, doneEmitter);
23 const bindings = {};
24 const inputs = [];
25 let httpInput;
26 for (const binding of request.inputData) {
27 if (binding.data && binding.name) {
28 let input;
29 if (binding.data && binding.data.http) {
30 input = httpInput = new Request_1.Request(binding.data.http);
31 }
32 else {
33 // TODO: Don't hard code fix for camelCase https://github.com/Azure/azure-functions-nodejs-worker/issues/188
34 if (info.getTimerTriggerName() === binding.name) {
35 // v2 worker converts timer trigger object to camelCase
36 input = (0, BindingConverters_1.convertKeysToCamelCase)(binding)['data'];
37 }
38 else {
39 input = (0, RpcConverters_1.fromTypedData)(binding.data);
40 }
41 }
42 bindings[binding.name] = input;
43 inputs.push(input);
44 }
45 }
46 context.bindings = bindings;
47 if (httpInput) {
48 context.req = httpInput;
49 context.res = new Response_1.Response(context.done);
50 // This is added for backwards compatability with what the host used to send to the worker
51 context.bindingData.sys = {
52 methodName: info.name,
53 utcNow: new Date().toISOString(),
54 randGuid: (0, uuid_1.v4)(),
55 };
56 // Populate from HTTP request for backwards compatibility if missing
57 if (!context.bindingData.query) {
58 context.bindingData.query = Object.assign({}, httpInput.query);
59 }
60 if (!context.bindingData.headers) {
61 context.bindingData.headers = Object.assign({}, httpInput.headers);
62 }
63 }
64 return {
65 context: context,
66 inputs: inputs,
67 };
68}
69exports.CreateContextAndInputs = CreateContextAndInputs;
70class InvocationContext {
71 constructor(info, request, userLogCallback, doneEmitter) {
72 this.invocationId = request.invocationId;
73 this.traceContext = (0, RpcConverters_1.fromRpcTraceContext)(request.traceContext);
74 const executionContext = {
75 invocationId: this.invocationId,
76 functionName: info.name,
77 functionDirectory: info.directory,
78 retryContext: request.retryContext,
79 };
80 this.executionContext = executionContext;
81 this.bindings = {};
82 // Log message that is tied to function invocation
83 this.log = Object.assign((...args) => userLogCallback('information', ...args), {
84 error: (...args) => userLogCallback('error', ...args),
85 warn: (...args) => userLogCallback('warning', ...args),
86 info: (...args) => userLogCallback('information', ...args),
87 verbose: (...args) => userLogCallback('trace', ...args),
88 });
89 this.bindingData = (0, BindingConverters_1.getNormalizedBindingData)(request);
90 this.bindingDefinitions = (0, BindingConverters_1.getBindingDefinitions)(info);
91 this.done = (err, result) => {
92 doneEmitter.emit('done', err, result);
93 };
94 }
95}
96
97
98/***/ }),
99
100/***/ "./src/FunctionInfo.ts":
101/*!*****************************!*\
102 !*** ./src/FunctionInfo.ts ***!
103 \*****************************/
104/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
105
106
107// Copyright (c) .NET Foundation. All rights reserved.
108// Licensed under the MIT License.
109Object.defineProperty(exports, "__esModule", ({ value: true }));
110exports.FunctionInfo = void 0;
111const RpcConverters_1 = __webpack_require__(/*! ./converters/RpcConverters */ "./src/converters/RpcConverters.ts");
112const RpcHttpConverters_1 = __webpack_require__(/*! ./converters/RpcHttpConverters */ "./src/converters/RpcHttpConverters.ts");
113const returnBindingKey = '$return';
114class FunctionInfo {
115 constructor(metadata) {
116 this.name = metadata.name;
117 this.directory = metadata.directory;
118 this.bindings = {};
119 this.outputBindings = {};
120 this.httpOutputName = '';
121 this.hasHttpTrigger = false;
122 if (metadata.bindings) {
123 const bindings = (this.bindings = metadata.bindings);
124 // determine output bindings & assign rpc converter (http has quirks)
125 Object.keys(bindings)
126 .filter((name) => bindings[name].direction !== 'in')
127 .forEach((name) => {
128 const type = bindings[name].type;
129 if (type && type.toLowerCase() === 'http') {
130 this.httpOutputName = name;
131 this.outputBindings[name] = Object.assign(bindings[name], { converter: RpcHttpConverters_1.toRpcHttp });
132 }
133 else {
134 this.outputBindings[name] = Object.assign(bindings[name], { converter: RpcConverters_1.toTypedData });
135 }
136 });
137 this.hasHttpTrigger =
138 Object.keys(bindings).filter((name) => {
139 const type = bindings[name].type;
140 return type && type.toLowerCase() === 'httptrigger';
141 }).length > 0;
142 }
143 }
144 /**
145 * Return output binding details on the special key "$return" output binding
146 */
147 getReturnBinding() {
148 return this.outputBindings[returnBindingKey];
149 }
150 getTimerTriggerName() {
151 for (const name in this.bindings) {
152 const type = this.bindings[name].type;
153 if (type && type.toLowerCase() === 'timertrigger') {
154 return name;
155 }
156 }
157 return;
158 }
159}
160exports.FunctionInfo = FunctionInfo;
161
162
163/***/ }),
164
165/***/ "./src/InvocationModel.ts":
166/*!********************************!*\
167 !*** ./src/InvocationModel.ts ***!
168 \********************************/
169/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
170
171
172// Copyright (c) .NET Foundation. All rights reserved.
173// Licensed under the MIT License.
174var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
175 function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
176 return new (P || (P = Promise))(function (resolve, reject) {
177 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
178 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
179 function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
180 step((generator = generator.apply(thisArg, _arguments || [])).next());
181 });
182};
183var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
184 if (kind === "m") throw new TypeError("Private method is not writable");
185 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
186 if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
187 return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
188};
189var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
190 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
191 if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
192 return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
193};
194var _InvocationModel_instances, _InvocationModel_doneEmitter, _InvocationModel_isDone, _InvocationModel_resultIsPromise, _InvocationModel_coreCtx, _InvocationModel_funcInfo, _InvocationModel_log, _InvocationModel_systemLog, _InvocationModel_userLog, _InvocationModel_onDone;
195Object.defineProperty(exports, "__esModule", ({ value: true }));
196exports.InvocationModel = void 0;
197const util_1 = __webpack_require__(/*! util */ "util");
198const Context_1 = __webpack_require__(/*! ./Context */ "./src/Context.ts");
199const RpcConverters_1 = __webpack_require__(/*! ./converters/RpcConverters */ "./src/converters/RpcConverters.ts");
200const errors_1 = __webpack_require__(/*! ./errors */ "./src/errors.ts");
201const FunctionInfo_1 = __webpack_require__(/*! ./FunctionInfo */ "./src/FunctionInfo.ts");
202const EventEmitter = __webpack_require__(/*! events */ "events");
203const asyncDoneLearnMoreLink = 'https://go.microsoft.com/fwlink/?linkid=2097909';
204class InvocationModel {
205 constructor(coreCtx) {
206 _InvocationModel_instances.add(this);
207 _InvocationModel_doneEmitter.set(this, new EventEmitter());
208 _InvocationModel_isDone.set(this, false);
209 _InvocationModel_resultIsPromise.set(this, false);
210 _InvocationModel_coreCtx.set(this, void 0);
211 _InvocationModel_funcInfo.set(this, void 0);
212 __classPrivateFieldSet(this, _InvocationModel_coreCtx, coreCtx, "f");
213 __classPrivateFieldSet(this, _InvocationModel_funcInfo, new FunctionInfo_1.FunctionInfo(coreCtx.metadata), "f");
214 }
215 getArguments() {
216 return __awaiter(this, void 0, void 0, function* () {
217 const { context, inputs } = (0, Context_1.CreateContextAndInputs)(__classPrivateFieldGet(this, _InvocationModel_funcInfo, "f"), __classPrivateFieldGet(this, _InvocationModel_coreCtx, "f").request, (level, ...args) => __classPrivateFieldGet(this, _InvocationModel_instances, "m", _InvocationModel_userLog).call(this, level, ...args), __classPrivateFieldGet(this, _InvocationModel_doneEmitter, "f"));
218 return { context, inputs };
219 });
220 }
221 invokeFunction(context, inputs, functionCallback) {
222 return __awaiter(this, void 0, void 0, function* () {
223 const legacyDoneTask = new Promise((resolve, reject) => {
224 __classPrivateFieldGet(this, _InvocationModel_doneEmitter, "f").on('done', (err, result) => {
225 __classPrivateFieldGet(this, _InvocationModel_instances, "m", _InvocationModel_onDone).call(this, context.suppressAsyncDoneError);
226 if ((0, errors_1.isError)(err)) {
227 reject(err);
228 }
229 else {
230 resolve(result);
231 }
232 });
233 });
234 try {
235 let rawResult = functionCallback(context, ...inputs);
236 __classPrivateFieldSet(this, _InvocationModel_resultIsPromise, !!rawResult && typeof rawResult.then === 'function', "f");
237 let resultTask;
238 if (__classPrivateFieldGet(this, _InvocationModel_resultIsPromise, "f")) {
239 rawResult = Promise.resolve(rawResult).then((r) => {
240 __classPrivateFieldGet(this, _InvocationModel_instances, "m", _InvocationModel_onDone).call(this, context.suppressAsyncDoneError);
241 return r;
242 });
243 resultTask = Promise.race([rawResult, legacyDoneTask]);
244 }
245 else {
246 resultTask = legacyDoneTask;
247 }
248 return yield resultTask;
249 }
250 finally {
251 __classPrivateFieldSet(this, _InvocationModel_isDone, true, "f");
252 }
253 });
254 }
255 getResponse(context, result) {
256 var _a, _b;
257 return __awaiter(this, void 0, void 0, function* () {
258 const response = { invocationId: __classPrivateFieldGet(this, _InvocationModel_coreCtx, "f").invocationId };
259 response.outputData = [];
260 const info = __classPrivateFieldGet(this, _InvocationModel_funcInfo, "f");
261 // Allow HTTP response from context.res if HTTP response is not defined from the context.bindings object
262 if (info.httpOutputName && context.res && context.bindings[info.httpOutputName] === undefined) {
263 context.bindings[info.httpOutputName] = context.res;
264 }
265 // As legacy behavior, falsy values get serialized to `null` in AzFunctions.
266 // This breaks Durable Functions expectations, where customers expect any
267 // JSON-serializable values to be preserved by the framework,
268 // so we check if we're serializing for durable and, if so, ensure falsy
269 // values get serialized.
270 const isDurableBinding = ((_b = (_a = info === null || info === void 0 ? void 0 : info.bindings) === null || _a === void 0 ? void 0 : _a.name) === null || _b === void 0 ? void 0 : _b.type) == 'activityTrigger';
271 const returnBinding = info.getReturnBinding();
272 // Set results from return / context.done
273 if (result || (isDurableBinding && result != null)) {
274 // $return binding is found: return result data to $return binding
275 if (returnBinding) {
276 response.returnValue = returnBinding.converter(result);
277 // $return binding is not found: read result as object of outputs
278 }
279 else if (typeof result === 'object') {
280 response.outputData = Object.keys(info.outputBindings)
281 .filter((key) => result[key] !== undefined)
282 .map((key) => ({
283 name: key,
284 data: info.outputBindings[key].converter(result[key]),
285 }));
286 }
287 // returned value does not match any output bindings (named or $return)
288 // if not http, pass along value
289 if (!response.returnValue && response.outputData.length == 0 && !info.hasHttpTrigger) {
290 response.returnValue = (0, RpcConverters_1.toTypedData)(result);
291 }
292 }
293 // Set results from context.bindings
294 if (context.bindings) {
295 response.outputData = response.outputData.concat(Object.keys(info.outputBindings)
296 // Data from return prioritized over data from context.bindings
297 .filter((key) => {
298 const definedInBindings = context.bindings[key] !== undefined;
299 const hasReturnValue = !!result;
300 const hasReturnBinding = !!returnBinding;
301 const definedInReturn = hasReturnValue &&
302 !hasReturnBinding &&
303 typeof result === 'object' &&
304 result[key] !== undefined;
305 return definedInBindings && !definedInReturn;
306 })
307 .map((key) => ({
308 name: key,
309 data: info.outputBindings[key].converter(context.bindings[key]),
310 })));
311 }
312 return response;
313 });
314 }
315}
316exports.InvocationModel = InvocationModel;
317_InvocationModel_doneEmitter = new WeakMap(), _InvocationModel_isDone = new WeakMap(), _InvocationModel_resultIsPromise = new WeakMap(), _InvocationModel_coreCtx = new WeakMap(), _InvocationModel_funcInfo = new WeakMap(), _InvocationModel_instances = new WeakSet(), _InvocationModel_log = function _InvocationModel_log(level, logCategory, ...args) {
318 __classPrivateFieldGet(this, _InvocationModel_coreCtx, "f").log(level, logCategory, util_1.format.apply(null, args));
319}, _InvocationModel_systemLog = function _InvocationModel_systemLog(level, ...args) {
320 __classPrivateFieldGet(this, _InvocationModel_instances, "m", _InvocationModel_log).call(this, level, 'system', ...args);
321}, _InvocationModel_userLog = function _InvocationModel_userLog(level, ...args) {
322 if (__classPrivateFieldGet(this, _InvocationModel_isDone, "f") && __classPrivateFieldGet(this, _InvocationModel_coreCtx, "f").state !== 'postInvocationHooks') {
323 let badAsyncMsg = "Warning: Unexpected call to 'log' on the context object after function execution has completed. Please check for asynchronous calls that are not awaited or calls to 'done' made before function execution completes. ";
324 badAsyncMsg += `Function name: ${__classPrivateFieldGet(this, _InvocationModel_funcInfo, "f").name}. Invocation Id: ${__classPrivateFieldGet(this, _InvocationModel_coreCtx, "f").invocationId}. `;
325 badAsyncMsg += `Learn more: ${asyncDoneLearnMoreLink}`;
326 __classPrivateFieldGet(this, _InvocationModel_instances, "m", _InvocationModel_systemLog).call(this, 'warning', badAsyncMsg);
327 }
328 __classPrivateFieldGet(this, _InvocationModel_instances, "m", _InvocationModel_log).call(this, level, 'user', ...args);
329}, _InvocationModel_onDone = function _InvocationModel_onDone(suppressAsyncDoneError = false) {
330 if (__classPrivateFieldGet(this, _InvocationModel_isDone, "f")) {
331 if (__classPrivateFieldGet(this, _InvocationModel_resultIsPromise, "f") && suppressAsyncDoneError) {
332 return;
333 }
334 const message = __classPrivateFieldGet(this, _InvocationModel_resultIsPromise, "f")
335 ? `Error: Choose either to return a promise or call 'done'. Do not use both in your script. Learn more: ${asyncDoneLearnMoreLink}`
336 : "Error: 'done' has already been called. Please check your script for extraneous calls to 'done'.";
337 __classPrivateFieldGet(this, _InvocationModel_instances, "m", _InvocationModel_systemLog).call(this, 'error', message);
338 }
339 __classPrivateFieldSet(this, _InvocationModel_isDone, true, "f");
340};
341
342
343/***/ }),
344
345/***/ "./src/constants.ts":
346/*!**************************!*\
347 !*** ./src/constants.ts ***!
348 \**************************/
349/***/ ((__unused_webpack_module, exports) => {
350
351
352// Copyright (c) .NET Foundation. All rights reserved.
353// Licensed under the MIT License.
354Object.defineProperty(exports, "__esModule", ({ value: true }));
355exports.MediaType = exports.HeaderName = exports.version = void 0;
356exports.version = '3.5.0';
357var HeaderName;
358(function (HeaderName) {
359 HeaderName["contentType"] = "content-type";
360 HeaderName["contentDisposition"] = "content-disposition";
361})(HeaderName = exports.HeaderName || (exports.HeaderName = {}));
362var MediaType;
363(function (MediaType) {
364 MediaType["multipartForm"] = "multipart/form-data";
365 MediaType["multipartPrefix"] = "multipart/";
366 MediaType["urlEncodedForm"] = "application/x-www-form-urlencoded";
367 MediaType["octetStream"] = "application/octet-stream";
368 MediaType["json"] = "application/json";
369})(MediaType = exports.MediaType || (exports.MediaType = {}));
370
371
372/***/ }),
373
374/***/ "./src/converters/BindingConverters.ts":
375/*!*********************************************!*\
376 !*** ./src/converters/BindingConverters.ts ***!
377 \*********************************************/
378/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
379
380
381// Copyright (c) .NET Foundation. All rights reserved.
382// Licensed under the MIT License.
383Object.defineProperty(exports, "__esModule", ({ value: true }));
384exports.convertKeysToCamelCase = exports.getNormalizedBindingData = exports.getBindingDefinitions = void 0;
385const RpcConverters_1 = __webpack_require__(/*! ./RpcConverters */ "./src/converters/RpcConverters.ts");
386function getBindingDefinitions(info) {
387 const bindings = info.bindings;
388 if (!bindings) {
389 return [];
390 }
391 return Object.keys(bindings).map((name) => {
392 return {
393 name: name,
394 type: bindings[name].type || '',
395 direction: bindings[name].direction || undefined,
396 };
397 });
398}
399exports.getBindingDefinitions = getBindingDefinitions;
400function getNormalizedBindingData(request) {
401 const bindingData = {
402 invocationId: request.invocationId,
403 };
404 // node binding data is camel cased due to language convention
405 if (request.triggerMetadata) {
406 Object.assign(bindingData, convertKeysToCamelCase(request.triggerMetadata));
407 }
408 return bindingData;
409}
410exports.getNormalizedBindingData = getNormalizedBindingData;
411// Recursively convert keys of objects to camel case
412function convertKeysToCamelCase(obj) {
413 const output = {};
414 for (const key in obj) {
415 const camelCasedKey = key.charAt(0).toLocaleLowerCase() + key.slice(1);
416 try {
417 // Only "undefined" will be replaced with original object property. For example:
418 //{ string : "0" } -> 0
419 //{ string : "false" } -> false
420 //"test" -> "test" (undefined returned from fromTypedData)
421 const valueFromDataType = (0, RpcConverters_1.fromTypedData)(obj[key]);
422 const value = valueFromDataType === undefined ? obj[key] : valueFromDataType;
423 // If the value is a JSON object (and not array and not http, which is already cased), convert keys to camel case
424 if (!Array.isArray(value) && typeof value === 'object' && value && value.http == undefined) {
425 output[camelCasedKey] = convertKeysToCamelCase(value);
426 }
427 else {
428 output[camelCasedKey] = value;
429 }
430 }
431 catch (_a) {
432 // Just use the original value if we failed to recursively convert for any reason
433 output[camelCasedKey] = obj[key];
434 }
435 }
436 return output;
437}
438exports.convertKeysToCamelCase = convertKeysToCamelCase;
439
440
441/***/ }),
442
443/***/ "./src/converters/RpcConverters.ts":
444/*!*****************************************!*\
445 !*** ./src/converters/RpcConverters.ts ***!
446 \*****************************************/
447/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
448
449
450// Copyright (c) .NET Foundation. All rights reserved.
451// Licensed under the MIT License.
452Object.defineProperty(exports, "__esModule", ({ value: true }));
453exports.toNullableTimestamp = exports.toNullableString = exports.toRpcString = exports.toNullableDouble = exports.toNullableBool = exports.toTypedData = exports.fromRpcTraceContext = exports.fromTypedData = void 0;
454const long_1 = __webpack_require__(/*! long */ "long");
455const errors_1 = __webpack_require__(/*! ../errors */ "./src/errors.ts");
456/**
457 * Converts 'ITypedData' input from the RPC layer to JavaScript types.
458 * TypedData can be string, json, or bytes
459 * @param typedData ITypedData object containing one of a string, json, or bytes property
460 * @param convertStringToJson Optionally parse the string input type as JSON
461 */
462function fromTypedData(typedData, convertStringToJson = true) {
463 typedData = typedData || {};
464 let str = typedData.string || typedData.json;
465 if (str !== undefined) {
466 if (convertStringToJson) {
467 try {
468 if (str != null) {
469 str = JSON.parse(str);
470 }
471 }
472 catch (err) { }
473 }
474 return str;
475 }
476 else if (typedData.bytes) {
477 return Buffer.from(typedData.bytes);
478 }
479 else if (typedData.collectionBytes && typedData.collectionBytes.bytes) {
480 const byteCollection = typedData.collectionBytes.bytes;
481 return byteCollection.map((element) => Buffer.from(element));
482 }
483 else if (typedData.collectionString && typedData.collectionString.string) {
484 return typedData.collectionString.string;
485 }
486 else if (typedData.collectionDouble && typedData.collectionDouble.double) {
487 return typedData.collectionDouble.double;
488 }
489 else if (typedData.collectionSint64 && typedData.collectionSint64.sint64) {
490 const longCollection = typedData.collectionSint64.sint64;
491 return longCollection.map((element) => ((0, long_1.isLong)(element) ? element.toString() : element));
492 }
493}
494exports.fromTypedData = fromTypedData;
495/**
496 * Converts 'IRpcTraceContext' input from RPC layer to dictionary of key value pairs.
497 * @param traceContext IRpcTraceContext object containing the activityId, tracestate and attributes.
498 */
499function fromRpcTraceContext(traceContext) {
500 if (traceContext) {
501 return {
502 traceparent: traceContext.traceParent,
503 tracestate: traceContext.traceState,
504 attributes: traceContext.attributes,
505 };
506 }
507 return {};
508}
509exports.fromRpcTraceContext = fromRpcTraceContext;
510/**
511 * Converts JavaScript type data to 'ITypedData' to be sent through the RPC layer
512 * TypedData can be string, json, or bytes
513 * @param inputObject A JavaScript object that is a string, Buffer, ArrayBufferView, number, or object.
514 */
515function toTypedData(inputObject) {
516 if (typeof inputObject === 'string') {
517 return { string: inputObject };
518 }
519 else if (Buffer.isBuffer(inputObject)) {
520 return { bytes: inputObject };
521 }
522 else if (ArrayBuffer.isView(inputObject)) {
523 const bytes = new Uint8Array(inputObject.buffer, inputObject.byteOffset, inputObject.byteLength);
524 return { bytes: bytes };
525 }
526 else if (typeof inputObject === 'number') {
527 if (Number.isInteger(inputObject)) {
528 return { int: inputObject };
529 }
530 else {
531 return { double: inputObject };
532 }
533 }
534 else {
535 return { json: JSON.stringify(inputObject) };
536 }
537}
538exports.toTypedData = toTypedData;
539/**
540 * Converts boolean input to an 'INullableBool' to be sent through the RPC layer.
541 * Input that is not a boolean but is also not null or undefined logs a function app level warning.
542 * @param nullable Input to be converted to an INullableBool if it is a valid boolean
543 * @param propertyName The name of the property that the caller will assign the output to. Used for debugging.
544 */
545function toNullableBool(nullable, propertyName) {
546 if (typeof nullable === 'boolean') {
547 return {
548 value: nullable,
549 };
550 }
551 if (nullable != null) {
552 throw new errors_1.AzFuncSystemError(`A 'boolean' type was expected instead of a '${typeof nullable}' type. Cannot parse value of '${propertyName}'.`);
553 }
554 return undefined;
555}
556exports.toNullableBool = toNullableBool;
557/**
558 * Converts number or string that parses to a number to an 'INullableDouble' to be sent through the RPC layer.
559 * Input that is not a valid number but is also not null or undefined logs a function app level warning.
560 * @param nullable Input to be converted to an INullableDouble if it is a valid number
561 * @param propertyName The name of the property that the caller will assign the output to. Used for debugging.
562 */
563function toNullableDouble(nullable, propertyName) {
564 if (typeof nullable === 'number') {
565 return {
566 value: nullable,
567 };
568 }
569 else if (typeof nullable === 'string') {
570 if (!isNaN(nullable)) {
571 const parsedNumber = parseFloat(nullable);
572 return {
573 value: parsedNumber,
574 };
575 }
576 }
577 if (nullable != null) {
578 throw new errors_1.AzFuncSystemError(`A 'number' type was expected instead of a '${typeof nullable}' type. Cannot parse value of '${propertyName}'.`);
579 }
580 return undefined;
581}
582exports.toNullableDouble = toNullableDouble;
583/**
584 * Converts string input to an 'INullableString' to be sent through the RPC layer.
585 * Input that is not a string but is also not null or undefined logs a function app level warning.
586 * @param nullable Input to be converted to an INullableString if it is a valid string
587 * @param propertyName The name of the property that the caller will assign the output to. Used for debugging.
588 */
589function toRpcString(nullable, propertyName) {
590 if (typeof nullable === 'string') {
591 return nullable;
592 }
593 if (nullable != null) {
594 throw new errors_1.AzFuncSystemError(`A 'string' type was expected instead of a '${typeof nullable}' type. Cannot parse value of '${propertyName}'.`);
595 }
596 return '';
597}
598exports.toRpcString = toRpcString;
599/**
600 * Converts string input to an 'INullableString' to be sent through the RPC layer.
601 * Input that is not a string but is also not null or undefined logs a function app level warning.
602 * @param nullable Input to be converted to an INullableString if it is a valid string
603 * @param propertyName The name of the property that the caller will assign the output to. Used for debugging.
604 */
605function toNullableString(nullable, propertyName) {
606 if (typeof nullable === 'string') {
607 return {
608 value: nullable,
609 };
610 }
611 if (nullable != null) {
612 throw new errors_1.AzFuncSystemError(`A 'string' type was expected instead of a '${typeof nullable}' type. Cannot parse value of '${propertyName}'.`);
613 }
614 return undefined;
615}
616exports.toNullableString = toNullableString;
617/**
618 * Converts Date or number input to an 'INullableTimestamp' to be sent through the RPC layer.
619 * Input that is not a Date or number but is also not null or undefined logs a function app level warning.
620 * @param nullable Input to be converted to an INullableTimestamp if it is valid input
621 * @param propertyName The name of the property that the caller will assign the output to. Used for debugging.
622 */
623function toNullableTimestamp(dateTime, propertyName) {
624 if (dateTime != null) {
625 try {
626 const timeInMilliseconds = typeof dateTime === 'number' ? dateTime : dateTime.getTime();
627 if (timeInMilliseconds && timeInMilliseconds >= 0) {
628 return {
629 value: {
630 seconds: Math.round(timeInMilliseconds / 1000),
631 },
632 };
633 }
634 }
635 catch (_a) {
636 throw new errors_1.AzFuncSystemError(`A 'number' or 'Date' input was expected instead of a '${typeof dateTime}'. Cannot parse value of '${propertyName}'.`);
637 }
638 }
639 return undefined;
640}
641exports.toNullableTimestamp = toNullableTimestamp;
642
643
644/***/ }),
645
646/***/ "./src/converters/RpcHttpConverters.ts":
647/*!*********************************************!*\
648 !*** ./src/converters/RpcHttpConverters.ts ***!
649 \*********************************************/
650/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
651
652
653// Copyright (c) .NET Foundation. All rights reserved.
654// Licensed under the MIT License.
655Object.defineProperty(exports, "__esModule", ({ value: true }));
656exports.toRpcHttpCookieList = exports.toRpcHttp = exports.fromNullableMapping = exports.fromRpcHttpBody = void 0;
657const errors_1 = __webpack_require__(/*! ../errors */ "./src/errors.ts");
658const RpcConverters_1 = __webpack_require__(/*! ./RpcConverters */ "./src/converters/RpcConverters.ts");
659/**
660 * Converts the provided body from the RPC layer to the appropriate javascript object.
661 * Body of type 'byte' is a special case and it's converted to it's utf-8 string representation.
662 * This is to avoid breaking changes in v2.
663 * @param body The body from the RPC layer.
664 */
665function fromRpcHttpBody(body) {
666 if (body && body.bytes) {
667 return body.bytes.toString();
668 }
669 else {
670 return (0, RpcConverters_1.fromTypedData)(body, false);
671 }
672}
673exports.fromRpcHttpBody = fromRpcHttpBody;
674function fromNullableMapping(nullableMapping, originalMapping) {
675 let converted = {};
676 if (nullableMapping && Object.keys(nullableMapping).length > 0) {
677 for (const key in nullableMapping) {
678 converted[key] = nullableMapping[key].value || '';
679 }
680 }
681 else if (originalMapping && Object.keys(originalMapping).length > 0) {
682 converted = originalMapping;
683 }
684 return converted;
685}
686exports.fromNullableMapping = fromNullableMapping;
687/**
688 * Converts the HTTP 'Response' object to an 'ITypedData' 'http' type to be sent through the RPC layer.
689 * 'http' types are a special case from other 'ITypedData' types, which come from primitive types.
690 * @param inputMessage An HTTP response object
691 */
692function toRpcHttp(data) {
693 // Check if we will fail to find any of these
694 if (typeof data !== 'object' || Array.isArray(data)) {
695 throw new errors_1.AzFuncSystemError("The HTTP response must be an 'object' type that can include properties such as 'body', 'status', and 'headers'. Learn more: https://go.microsoft.com/fwlink/?linkid=2112563");
696 }
697 const inputMessage = data || {};
698 let status = inputMessage.statusCode;
699 if (typeof inputMessage.status !== 'function') {
700 status || (status = inputMessage.status);
701 }
702 const httpMessage = Object.assign(Object.assign({}, inputMessage), { statusCode: (status === null || status === void 0 ? void 0 : status.toString()) || null, headers: toRpcHttpHeaders(inputMessage.headers), cookies: toRpcHttpCookieList(inputMessage.cookies || []), body: (0, RpcConverters_1.toTypedData)(inputMessage.body) });
703 return { http: httpMessage };
704}
705exports.toRpcHttp = toRpcHttp;
706/**
707 * Convert HTTP headers to a string/string mapping.
708 * @param inputHeaders
709 */
710function toRpcHttpHeaders(inputHeaders) {
711 const rpcHttpHeaders = {};
712 if (inputHeaders) {
713 for (const key in inputHeaders) {
714 if (inputHeaders[key] != null) {
715 rpcHttpHeaders[key] = inputHeaders[key].toString();
716 }
717 }
718 }
719 return rpcHttpHeaders;
720}
721/**
722 * Convert HTTP 'Cookie' array to an array of 'RpcHttpCookie' objects to be sent through the RPC layer
723 * @param inputCookies array of 'Cookie' objects representing options for the 'Set-Cookie' response header
724 */
725function toRpcHttpCookieList(inputCookies) {
726 const rpcCookies = [];
727 inputCookies.forEach((cookie) => {
728 rpcCookies.push(toRpcHttpCookie(cookie));
729 });
730 return rpcCookies;
731}
732exports.toRpcHttpCookieList = toRpcHttpCookieList;
733/**
734 * From RFC specifications for 'Set-Cookie' response header: https://www.rfc-editor.org/rfc/rfc6265.txt
735 * @param inputCookie
736 */
737function toRpcHttpCookie(inputCookie) {
738 // Resolve RpcHttpCookie.SameSite enum, a one-off
739 let rpcSameSite = 'none';
740 if (inputCookie && inputCookie.sameSite) {
741 const sameSite = inputCookie.sameSite.toLocaleLowerCase();
742 if (sameSite === 'lax') {
743 rpcSameSite = 'lax';
744 }
745 else if (sameSite === 'strict') {
746 rpcSameSite = 'strict';
747 }
748 else if (sameSite === 'none') {
749 rpcSameSite = 'explicitNone';
750 }
751 }
752 const rpcCookie = {
753 name: inputCookie && (0, RpcConverters_1.toRpcString)(inputCookie.name, 'cookie.name'),
754 value: inputCookie && (0, RpcConverters_1.toRpcString)(inputCookie.value, 'cookie.value'),
755 domain: (0, RpcConverters_1.toNullableString)(inputCookie && inputCookie.domain, 'cookie.domain'),
756 path: (0, RpcConverters_1.toNullableString)(inputCookie && inputCookie.path, 'cookie.path'),
757 expires: (0, RpcConverters_1.toNullableTimestamp)(inputCookie && inputCookie.expires, 'cookie.expires'),
758 secure: (0, RpcConverters_1.toNullableBool)(inputCookie && inputCookie.secure, 'cookie.secure'),
759 httpOnly: (0, RpcConverters_1.toNullableBool)(inputCookie && inputCookie.httpOnly, 'cookie.httpOnly'),
760 sameSite: rpcSameSite,
761 maxAge: (0, RpcConverters_1.toNullableDouble)(inputCookie && inputCookie.maxAge, 'cookie.maxAge'),
762 };
763 return rpcCookie;
764}
765
766
767/***/ }),
768
769/***/ "./src/errors.ts":
770/*!***********************!*\
771 !*** ./src/errors.ts ***!
772 \***********************/
773/***/ ((__unused_webpack_module, exports) => {
774
775
776// Copyright (c) .NET Foundation. All rights reserved.
777// Licensed under the MIT License.
778Object.defineProperty(exports, "__esModule", ({ value: true }));
779exports.isError = exports.ensureErrorType = exports.ReadOnlyError = exports.AzFuncRangeError = exports.AzFuncTypeError = exports.AzFuncSystemError = void 0;
780class AzFuncSystemError extends Error {
781 constructor() {
782 super(...arguments);
783 this.isAzureFunctionsSystemError = true;
784 }
785}
786exports.AzFuncSystemError = AzFuncSystemError;
787class AzFuncTypeError extends TypeError {
788 constructor() {
789 super(...arguments);
790 this.isAzureFunctionsSystemError = true;
791 }
792}
793exports.AzFuncTypeError = AzFuncTypeError;
794class AzFuncRangeError extends RangeError {
795 constructor() {
796 super(...arguments);
797 this.isAzureFunctionsSystemError = true;
798 }
799}
800exports.AzFuncRangeError = AzFuncRangeError;
801class ReadOnlyError extends AzFuncTypeError {
802 constructor(propertyName) {
803 super(`Cannot assign to read only property '${propertyName}'`);
804 }
805}
806exports.ReadOnlyError = ReadOnlyError;
807function ensureErrorType(err) {
808 if (err instanceof Error) {
809 return err;
810 }
811 else {
812 let message;
813 if (err === undefined || err === null) {
814 message = 'Unknown error';
815 }
816 else if (typeof err === 'string') {
817 message = err;
818 }
819 else if (typeof err === 'object') {
820 message = JSON.stringify(err);
821 }
822 else {
823 message = String(err);
824 }
825 return new Error(message);
826 }
827}
828exports.ensureErrorType = ensureErrorType;
829/**
830 * This is mostly for callbacks where `null` or `undefined` indicates there is no error
831 * By contrast, anything thrown/caught is assumed to be an error regardless of what it is
832 */
833function isError(err) {
834 return err !== null && err !== undefined;
835}
836exports.isError = isError;
837
838
839/***/ }),
840
841/***/ "./src/http/Request.ts":
842/*!*****************************!*\
843 !*** ./src/http/Request.ts ***!
844 \*****************************/
845/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
846
847
848// Copyright (c) .NET Foundation. All rights reserved.
849// Licensed under the MIT License.
850var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
851 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
852 if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
853 return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
854};
855var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
856 if (kind === "m") throw new TypeError("Private method is not writable");
857 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
858 if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
859 return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
860};
861var _Request_cachedUser;
862Object.defineProperty(exports, "__esModule", ({ value: true }));
863exports.Request = void 0;
864const iconv_lite_1 = __webpack_require__(/*! iconv-lite */ "iconv-lite");
865const constants_1 = __webpack_require__(/*! ../constants */ "./src/constants.ts");
866const RpcConverters_1 = __webpack_require__(/*! ../converters/RpcConverters */ "./src/converters/RpcConverters.ts");
867const RpcHttpConverters_1 = __webpack_require__(/*! ../converters/RpcHttpConverters */ "./src/converters/RpcHttpConverters.ts");
868const errors_1 = __webpack_require__(/*! ../errors */ "./src/errors.ts");
869const parseForm_1 = __webpack_require__(/*! ../parsers/parseForm */ "./src/parsers/parseForm.ts");
870const extractHttpUserFromHeaders_1 = __webpack_require__(/*! ./extractHttpUserFromHeaders */ "./src/http/extractHttpUserFromHeaders.ts");
871class Request {
872 constructor(rpcHttp) {
873 var _a, _b;
874 _Request_cachedUser.set(this, void 0);
875 this.method = rpcHttp.method;
876 this.url = rpcHttp.url;
877 this.originalUrl = rpcHttp.url;
878 this.headers = (0, RpcHttpConverters_1.fromNullableMapping)(rpcHttp.nullableHeaders, rpcHttp.headers);
879 this.query = (0, RpcHttpConverters_1.fromNullableMapping)(rpcHttp.nullableQuery, rpcHttp.query);
880 this.params = (0, RpcHttpConverters_1.fromNullableMapping)(rpcHttp.nullableParams, rpcHttp.params);
881 if ((_a = rpcHttp.body) === null || _a === void 0 ? void 0 : _a.bytes) {
882 this.bufferBody = Buffer.from(rpcHttp.body.bytes);
883 // We turned on the worker capability to always receive bytes instead of a string (RawHttpBodyBytes) so that we could introduce the `bufferBody` property
884 // However, we need to replicate the old host behavior for the `body` and `rawBody` properties so that we don't break anyone
885 // https://github.com/Azure/azure-functions-nodejs-worker/issues/294
886 // NOTE: The tests for this are in the e2e test folder of the worker. This is so we can test the full .net host behavior of encoding/parsing/etc.
887 // https://github.com/Azure/azure-functions-nodejs-worker/blob/b109082f9b85b42af1de00db4192483460214d81/test/end-to-end/Azure.Functions.NodejsWorker.E2E/Azure.Functions.NodejsWorker.E2E/HttpEndToEndTests.cs
888 const contentType = (_b = this.get(constants_1.HeaderName.contentType)) === null || _b === void 0 ? void 0 : _b.toLowerCase();
889 let legacyBody;
890 if (contentType === constants_1.MediaType.octetStream || (contentType === null || contentType === void 0 ? void 0 : contentType.startsWith(constants_1.MediaType.multipartPrefix))) {
891 // If the content type was octet or multipart, the host would leave the body as bytes
892 // https://github.com/Azure/azure-functions-host/blob/9ac904e34b744d95a6f746921556235d4b2b3f0f/src/WebJobs.Script.Grpc/MessageExtensions/GrpcMessageConversionExtensions.cs#L233
893 legacyBody = rpcHttp.body;
894 }
895 else {
896 // Otherwise the host would decode the buffer to a string
897 legacyBody = {
898 string: decodeBuffer(this.bufferBody),
899 };
900 }
901 this.body = (0, RpcConverters_1.fromTypedData)(legacyBody);
902 this.rawBody = (0, RpcHttpConverters_1.fromRpcHttpBody)(legacyBody);
903 }
904 }
905 get user() {
906 if (__classPrivateFieldGet(this, _Request_cachedUser, "f") === undefined) {
907 __classPrivateFieldSet(this, _Request_cachedUser, (0, extractHttpUserFromHeaders_1.extractHttpUserFromHeaders)(this.headers), "f");
908 }
909 return __classPrivateFieldGet(this, _Request_cachedUser, "f");
910 }
911 get(field) {
912 return this.headers && this.headers[field.toLowerCase()];
913 }
914 parseFormBody() {
915 const contentType = this.get(constants_1.HeaderName.contentType);
916 if (!contentType) {
917 throw new errors_1.AzFuncSystemError(`"${constants_1.HeaderName.contentType}" header must be defined.`);
918 }
919 else {
920 return (0, parseForm_1.parseForm)(this.body, contentType);
921 }
922 }
923}
924exports.Request = Request;
925_Request_cachedUser = new WeakMap();
926/**
927 * The host used utf8 by default, but supported `detectEncodingFromByteOrderMarks` so we have to replicate that
928 * Host code: https://github.com/Azure/azure-webjobs-sdk-extensions/blob/03cb2ce82db74ed5a2f3299e8a84a6c35835c269/src/WebJobs.Extensions.Http/Extensions/HttpRequestExtensions.cs#L27
929 * .NET code: https://github.com/dotnet/runtime/blob/e55c908229e36f99a52745d4ee85316a0e8bb6a2/src/libraries/System.Private.CoreLib/src/System/IO/StreamReader.cs#L469
930 * .NET description of encoding preambles: https://docs.microsoft.com/en-us/dotnet/api/system.text.encoding.getpreamble?view=net-6.0#remarks
931 **/
932function decodeBuffer(buffer) {
933 let encoding = 'utf8';
934 if (buffer[0] === 0xfe && buffer[1] === 0xff) {
935 encoding = 'utf16be'; // The same as `Encoding.BigEndianUnicode` in .NET
936 buffer = compressBuffer(buffer, 2);
937 }
938 else if (buffer[0] === 0xff && buffer[1] === 0xfe) {
939 if (buffer[2] !== 0 || buffer[3] !== 0) {
940 encoding = 'utf16le'; // The same as `Encoding.Unicode` in .NET
941 buffer = compressBuffer(buffer, 2);
942 }
943 else {
944 encoding = 'utf32le';
945 buffer = compressBuffer(buffer, 4);
946 }
947 }
948 else if (buffer[0] === 0xef && buffer[1] === 0xbb && buffer[2] === 0xbf) {
949 encoding = 'utf8';
950 buffer = compressBuffer(buffer, 3);
951 }
952 else if (buffer[0] === 0 && buffer[1] === 0 && buffer[2] === 0xfe && buffer[3] === 0xff) {
953 encoding = 'utf32be';
954 buffer = compressBuffer(buffer, 4);
955 }
956 // NOTE: Node.js doesn't support all the above encodings by default, so we have to use "iconv-lite" to help
957 // Here are the iconv-lite supported encodings: https://github.com/ashtuchkin/iconv-lite/wiki/Supported-Encodings
958 return (0, iconv_lite_1.decode)(buffer, encoding);
959}
960function compressBuffer(buffer, n) {
961 return buffer.subarray(n);
962}
963
964
965/***/ }),
966
967/***/ "./src/http/Response.ts":
968/*!******************************!*\
969 !*** ./src/http/Response.ts ***!
970 \******************************/
971/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
972
973
974// Copyright (c) .NET Foundation. All rights reserved.
975// Licensed under the MIT License.
976Object.defineProperty(exports, "__esModule", ({ value: true }));
977exports.Response = void 0;
978const constants_1 = __webpack_require__(/*! ../constants */ "./src/constants.ts");
979class Response {
980 constructor(done) {
981 this.headers = {};
982 this.cookies = [];
983 this.send = this.end;
984 this.header = this.setHeader;
985 this.set = this.setHeader;
986 this.get = this.getHeader;
987 this._done = done;
988 }
989 end(body) {
990 if (body !== undefined) {
991 this.body = body;
992 }
993 this.setContentType();
994 this._done();
995 return this;
996 }
997 setHeader(field, val) {
998 this.headers[field.toLowerCase()] = val;
999 return this;
1000 }
1001 getHeader(field) {
1002 return this.headers[field.toLowerCase()];
1003 }
1004 removeHeader(field) {
1005 delete this.headers[field.toLowerCase()];
1006 return this;
1007 }
1008 status(statusCode) {
1009 this.statusCode = statusCode;
1010 return this;
1011 }
1012 sendStatus(statusCode) {
1013 this.status(statusCode);
1014 // eslint-disable-next-line deprecation/deprecation
1015 return this.end();
1016 }
1017 type(type) {
1018 return this.set(constants_1.HeaderName.contentType, type);
1019 }
1020 json(body) {
1021 this.type(constants_1.MediaType.json);
1022 // eslint-disable-next-line deprecation/deprecation
1023 this.send(body);
1024 return;
1025 }
1026 // NOTE: This is considered private and people should not be referencing it, but for the sake of backwards compatibility we will avoid using `#`
1027 setContentType() {
1028 if (this.body !== undefined) {
1029 if (this.get(constants_1.HeaderName.contentType)) {
1030 // use user defined content type, if exists
1031 return;
1032 }
1033 if (Buffer.isBuffer(this.body)) {
1034 this.type(constants_1.MediaType.octetStream);
1035 }
1036 }
1037 }
1038}
1039exports.Response = Response;
1040
1041
1042/***/ }),
1043
1044/***/ "./src/http/extractHttpUserFromHeaders.ts":
1045/*!************************************************!*\
1046 !*** ./src/http/extractHttpUserFromHeaders.ts ***!
1047 \************************************************/
1048/***/ ((__unused_webpack_module, exports) => {
1049
1050
1051// Copyright (c) .NET Foundation. All rights reserved.
1052// Licensed under the MIT License.
1053Object.defineProperty(exports, "__esModule", ({ value: true }));
1054exports.extractHttpUserFromHeaders = void 0;
1055function extractHttpUserFromHeaders(headers) {
1056 let user = null;
1057 if (headers['x-ms-client-principal']) {
1058 const claimsPrincipalData = JSON.parse(Buffer.from(headers['x-ms-client-principal'], 'base64').toString('utf-8'));
1059 if (claimsPrincipalData['identityProvider']) {
1060 user = {
1061 type: 'StaticWebApps',
1062 id: claimsPrincipalData['userId'],
1063 username: claimsPrincipalData['userDetails'],
1064 identityProvider: claimsPrincipalData['identityProvider'],
1065 claimsPrincipalData,
1066 };
1067 }
1068 else {
1069 user = {
1070 type: 'AppService',
1071 id: headers['x-ms-client-principal-id'],
1072 username: headers['x-ms-client-principal-name'],
1073 identityProvider: headers['x-ms-client-principal-idp'],
1074 claimsPrincipalData,
1075 };
1076 }
1077 }
1078 return user;
1079}
1080exports.extractHttpUserFromHeaders = extractHttpUserFromHeaders;
1081
1082
1083/***/ }),
1084
1085/***/ "./src/parsers/parseForm.ts":
1086/*!**********************************!*\
1087 !*** ./src/parsers/parseForm.ts ***!
1088 \**********************************/
1089/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
1090
1091
1092// Copyright (c) .NET Foundation. All rights reserved.
1093// Licensed under the MIT License.
1094var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
1095 if (kind === "m") throw new TypeError("Private method is not writable");
1096 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
1097 if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
1098 return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
1099};
1100var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
1101 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
1102 if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
1103 return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
1104};
1105var _Form_parts;
1106Object.defineProperty(exports, "__esModule", ({ value: true }));
1107exports.Form = exports.parseForm = void 0;
1108const constants_1 = __webpack_require__(/*! ../constants */ "./src/constants.ts");
1109const errors_1 = __webpack_require__(/*! ../errors */ "./src/errors.ts");
1110const parseHeader_1 = __webpack_require__(/*! ./parseHeader */ "./src/parsers/parseHeader.ts");
1111const parseMultipartForm_1 = __webpack_require__(/*! ./parseMultipartForm */ "./src/parsers/parseMultipartForm.ts");
1112/**
1113 * See ./test/parseForm.test.ts for examples
1114 */
1115function parseForm(data, contentType) {
1116 const [mediaType, parameters] = (0, parseHeader_1.parseContentType)(contentType);
1117 switch (mediaType.toLowerCase()) {
1118 case constants_1.MediaType.multipartForm: {
1119 const boundary = parameters.get('boundary');
1120 const parts = (0, parseMultipartForm_1.parseMultipartForm)(typeof data === 'string' ? Buffer.from(data) : data, boundary);
1121 return new Form(parts);
1122 }
1123 case constants_1.MediaType.urlEncodedForm: {
1124 const parsed = new URLSearchParams(data.toString());
1125 const parts = [];
1126 for (const [key, value] of parsed) {
1127 parts.push([key, { value: Buffer.from(value) }]);
1128 }
1129 return new Form(parts);
1130 }
1131 default:
1132 throw new errors_1.AzFuncSystemError(`Media type "${mediaType}" does not match types supported for form parsing: "${constants_1.MediaType.multipartForm}", "${constants_1.MediaType.urlEncodedForm}".`);
1133 }
1134}
1135exports.parseForm = parseForm;
1136class Form {
1137 constructor(parts) {
1138 _Form_parts.set(this, void 0);
1139 __classPrivateFieldSet(this, _Form_parts, parts, "f");
1140 }
1141 get(name) {
1142 for (const [key, value] of __classPrivateFieldGet(this, _Form_parts, "f")) {
1143 if (key === name) {
1144 return value;
1145 }
1146 }
1147 return null;
1148 }
1149 getAll(name) {
1150 const result = [];
1151 for (const [key, value] of __classPrivateFieldGet(this, _Form_parts, "f")) {
1152 if (key === name) {
1153 result.push(value);
1154 }
1155 }
1156 return result;
1157 }
1158 has(name) {
1159 for (const [key] of __classPrivateFieldGet(this, _Form_parts, "f")) {
1160 if (key === name) {
1161 return true;
1162 }
1163 }
1164 return false;
1165 }
1166 [(_Form_parts = new WeakMap(), Symbol.iterator)]() {
1167 return __classPrivateFieldGet(this, _Form_parts, "f")[Symbol.iterator]();
1168 }
1169 get length() {
1170 return __classPrivateFieldGet(this, _Form_parts, "f").length;
1171 }
1172}
1173exports.Form = Form;
1174
1175
1176/***/ }),
1177
1178/***/ "./src/parsers/parseHeader.ts":
1179/*!************************************!*\
1180 !*** ./src/parsers/parseHeader.ts ***!
1181 \************************************/
1182/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
1183
1184
1185// Copyright (c) .NET Foundation. All rights reserved.
1186// Licensed under the MIT License.
1187var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
1188 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
1189 if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
1190 return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
1191};
1192var _HeaderParams_params;
1193Object.defineProperty(exports, "__esModule", ({ value: true }));
1194exports.HeaderParams = exports.parseContentDisposition = exports.parseContentType = exports.getHeaderValue = void 0;
1195const constants_1 = __webpack_require__(/*! ../constants */ "./src/constants.ts");
1196const errors_1 = __webpack_require__(/*! ../errors */ "./src/errors.ts");
1197const space = ' ';
1198// See "LEXICAL TOKENS" section for definition of ctl chars and quoted string: https://www.w3.org/Protocols/rfc822/3_Lexical.html
1199const ctlChars = '\\u0000-\\u001F\\u007F';
1200const quotedString = '(?:[^"\\\\]|\\\\.)*';
1201// General description of content type header, including defintion of tspecials and token https://www.w3.org/Protocols/rfc1341/4_Content-Type.html
1202const tspecials = '\\(\\)<>@,;:\\\\"\\/\\[\\]\\?\\.=';
1203const token = `[^${space}${ctlChars}${tspecials}]+`;
1204const start = '^\\s*'; // allows leading whitespace
1205const end = '\\s*(.*)$'; // gets the rest of the string except leading whitespace
1206const semicolonEnd = `\\s*;?${end}`; // allows optional semicolon and otherwise gets the rest of the string
1207/**
1208 * @param data a full header, e.g. "Content-Type: text/html; charset=UTF-8"
1209 * @param headerName the header name, e.g. "Content-Type"
1210 * @returns the header value, e.g. "text/html; charset=UTF-8" or null if not found
1211 */
1212function getHeaderValue(data, headerName) {
1213 const match = new RegExp(`${start}${headerName}\\s*:${end}`, 'i').exec(data);
1214 if (match) {
1215 return match[1].trim();
1216 }
1217 return null;
1218}
1219exports.getHeaderValue = getHeaderValue;
1220/**
1221 * @param data a content type, e.g. "text/html; charset=UTF-8"
1222 * @returns an array containing the media type (e.g. text/html) and an object with the parameters
1223 */
1224function parseContentType(data) {
1225 const match = new RegExp(`${start}(${token}\\/${token})${semicolonEnd}`, 'i').exec(data);
1226 if (!match) {
1227 throw new errors_1.AzFuncSystemError(`${constants_1.HeaderName.contentType} must begin with format "type/subtype".`);
1228 }
1229 else {
1230 return [match[1], parseHeaderParams(match[2])];
1231 }
1232}
1233exports.parseContentType = parseContentType;
1234/**
1235 * @param data a content disposition, e.g. "form-data; name=myfile; filename=test.txt"
1236 * @returns an array containing the disposition (e.g. form-data) and an object with the parameters
1237 */
1238function parseContentDisposition(data) {
1239 const match = new RegExp(`${start}(${token})${semicolonEnd}`, 'i').exec(data);
1240 if (!match) {
1241 throw new errors_1.AzFuncSystemError(`${constants_1.HeaderName.contentDisposition} must begin with disposition type.`);
1242 }
1243 else {
1244 return [match[1], parseHeaderParams(match[2])];
1245 }
1246}
1247exports.parseContentDisposition = parseContentDisposition;
1248function parseHeaderParams(data) {
1249 const result = new HeaderParams();
1250 while (data) {
1251 // try to find an unquoted name=value pair first
1252 const regexp = new RegExp(`${start}(${token})=(${token})${semicolonEnd}`, 'i');
1253 let match = regexp.exec(data);
1254 // if that didn't work, try to find a quoted name="value" pair instead
1255 if (!match) {
1256 const quotedPartsRegexp = new RegExp(`${start}(${token})="(${quotedString})"${semicolonEnd}`, 'i');
1257 match = quotedPartsRegexp.exec(data);
1258 }
1259 if (match) {
1260 result.add(match[1], match[2].replace(/\\"/g, '"')); // un-escape any quotes
1261 data = match[3];
1262 }
1263 else {
1264 break;
1265 }
1266 }
1267 return result;
1268}
1269class HeaderParams {
1270 constructor() {
1271 _HeaderParams_params.set(this, {});
1272 }
1273 get(name) {
1274 const result = __classPrivateFieldGet(this, _HeaderParams_params, "f")[name.toLowerCase()];
1275 if (result === undefined) {
1276 throw new errors_1.AzFuncSystemError(`Failed to find parameter with name "${name}".`);
1277 }
1278 else {
1279 return result;
1280 }
1281 }
1282 has(name) {
1283 return __classPrivateFieldGet(this, _HeaderParams_params, "f")[name.toLowerCase()] !== undefined;
1284 }
1285 add(name, value) {
1286 __classPrivateFieldGet(this, _HeaderParams_params, "f")[name.toLowerCase()] = value;
1287 }
1288}
1289exports.HeaderParams = HeaderParams;
1290_HeaderParams_params = new WeakMap();
1291
1292
1293/***/ }),
1294
1295/***/ "./src/parsers/parseMultipartForm.ts":
1296/*!*******************************************!*\
1297 !*** ./src/parsers/parseMultipartForm.ts ***!
1298 \*******************************************/
1299/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
1300
1301
1302// Copyright (c) .NET Foundation. All rights reserved.
1303// Licensed under the MIT License.
1304Object.defineProperty(exports, "__esModule", ({ value: true }));
1305exports.parseMultipartForm = void 0;
1306const constants_1 = __webpack_require__(/*! ../constants */ "./src/constants.ts");
1307const errors_1 = __webpack_require__(/*! ../errors */ "./src/errors.ts");
1308const parseHeader_1 = __webpack_require__(/*! ./parseHeader */ "./src/parsers/parseHeader.ts");
1309const carriageReturn = Buffer.from('\r')[0];
1310const newline = Buffer.from('\n')[0];
1311// multipart/form-data specification https://datatracker.ietf.org/doc/html/rfc7578
1312function parseMultipartForm(chunk, boundary) {
1313 const result = [];
1314 let currentName;
1315 let currentPart;
1316 let inHeaders = false;
1317 const boundaryBuffer = Buffer.from(`--${boundary}`);
1318 const endBoundaryBuffer = Buffer.from(`--${boundary}--`);
1319 let lineStart = 0;
1320 let lineEnd = 0;
1321 let partValueStart = 0;
1322 let partValueEnd = 0;
1323 for (let index = 0; index < chunk.length; index++) {
1324 let line;
1325 if (chunk[index] === newline) {
1326 lineEnd = chunk[index - 1] === carriageReturn ? index - 1 : index;
1327 line = chunk.slice(lineStart, lineEnd);
1328 lineStart = index + 1;
1329 }
1330 else {
1331 continue;
1332 }
1333 const isBoundary = line.equals(boundaryBuffer);
1334 const isBoundaryEnd = line.equals(endBoundaryBuffer);
1335 if (isBoundary || isBoundaryEnd) {
1336 if (currentPart) {
1337 currentPart.value = chunk.slice(partValueStart, partValueEnd);
1338 }
1339 if (isBoundaryEnd) {
1340 break;
1341 }
1342 currentPart = {
1343 value: Buffer.from(''),
1344 };
1345 inHeaders = true;
1346 }
1347 else if (inHeaders) {
1348 if (!currentPart) {
1349 throw new errors_1.AzFuncSystemError(`Expected form data to start with boundary "${boundary}".`);
1350 }
1351 const lineAsString = line.toString();
1352 if (!lineAsString) {
1353 // A blank line means we're done with the headers for this part
1354 inHeaders = false;
1355 if (!currentName) {
1356 throw new errors_1.AzFuncSystemError(`Expected part to have header "${constants_1.HeaderName.contentDisposition}" with parameter "name".`);
1357 }
1358 else {
1359 partValueStart = lineStart;
1360 partValueEnd = lineStart;
1361 result.push([currentName, currentPart]);
1362 }
1363 }
1364 else {
1365 const contentDisposition = (0, parseHeader_1.getHeaderValue)(lineAsString, constants_1.HeaderName.contentDisposition);
1366 if (contentDisposition) {
1367 const [, dispositionParts] = (0, parseHeader_1.parseContentDisposition)(contentDisposition);
1368 currentName = dispositionParts.get('name');
1369 // filename is optional, even for files
1370 if (dispositionParts.has('fileName')) {
1371 currentPart.fileName = dispositionParts.get('fileName');
1372 }
1373 }
1374 else {
1375 const contentType = (0, parseHeader_1.getHeaderValue)(lineAsString, constants_1.HeaderName.contentType);
1376 if (contentType) {
1377 currentPart.contentType = contentType;
1378 }
1379 }
1380 }
1381 }
1382 else {
1383 partValueEnd = lineEnd;
1384 }
1385 }
1386 return result;
1387}
1388exports.parseMultipartForm = parseMultipartForm;
1389
1390
1391/***/ }),
1392
1393/***/ "@azure/functions-core":
1394/*!****************************************!*\
1395 !*** external "@azure/functions-core" ***!
1396 \****************************************/
1397/***/ ((module) => {
1398
1399module.exports = require("@azure/functions-core");
1400
1401/***/ }),
1402
1403/***/ "events":
1404/*!*************************!*\
1405 !*** external "events" ***!
1406 \*************************/
1407/***/ ((module) => {
1408
1409module.exports = require("events");
1410
1411/***/ }),
1412
1413/***/ "iconv-lite":
1414/*!*****************************!*\
1415 !*** external "iconv-lite" ***!
1416 \*****************************/
1417/***/ ((module) => {
1418
1419module.exports = require("iconv-lite");
1420
1421/***/ }),
1422
1423/***/ "long":
1424/*!***********************!*\
1425 !*** external "long" ***!
1426 \***********************/
1427/***/ ((module) => {
1428
1429module.exports = require("long");
1430
1431/***/ }),
1432
1433/***/ "util":
1434/*!***********************!*\
1435 !*** external "util" ***!
1436 \***********************/
1437/***/ ((module) => {
1438
1439module.exports = require("util");
1440
1441/***/ }),
1442
1443/***/ "uuid":
1444/*!***********************!*\
1445 !*** external "uuid" ***!
1446 \***********************/
1447/***/ ((module) => {
1448
1449module.exports = require("uuid");
1450
1451/***/ })
1452
1453/******/ });
1454/************************************************************************/
1455/******/ // The module cache
1456/******/ var __webpack_module_cache__ = {};
1457/******/
1458/******/ // The require function
1459/******/ function __webpack_require__(moduleId) {
1460/******/ // Check if module is in cache
1461/******/ var cachedModule = __webpack_module_cache__[moduleId];
1462/******/ if (cachedModule !== undefined) {
1463/******/ return cachedModule.exports;
1464/******/ }
1465/******/ // Create a new module (and put it into the cache)
1466/******/ var module = __webpack_module_cache__[moduleId] = {
1467/******/ // no module.id needed
1468/******/ // no module.loaded needed
1469/******/ exports: {}
1470/******/ };
1471/******/
1472/******/ // Execute the module function
1473/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
1474/******/
1475/******/ // Return the exports of the module
1476/******/ return module.exports;
1477/******/ }
1478/******/
1479/************************************************************************/
1480var __webpack_exports__ = {};
1481// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
1482(() => {
1483var exports = __webpack_exports__;
1484/*!**********************!*\
1485 !*** ./src/index.ts ***!
1486 \**********************/
1487
1488// Copyright (c) .NET Foundation. All rights reserved.
1489// Licensed under the MIT License.
1490Object.defineProperty(exports, "__esModule", ({ value: true }));
1491exports.setup = void 0;
1492const functions_core_1 = __webpack_require__(/*! @azure/functions-core */ "@azure/functions-core");
1493const constants_1 = __webpack_require__(/*! ./constants */ "./src/constants.ts");
1494const InvocationModel_1 = __webpack_require__(/*! ./InvocationModel */ "./src/InvocationModel.ts");
1495class ProgrammingModel {
1496 constructor() {
1497 this.name = '@azure/functions';
1498 this.version = constants_1.version;
1499 }
1500 getInvocationModel(coreCtx) {
1501 return new InvocationModel_1.InvocationModel(coreCtx);
1502 }
1503}
1504function setup() {
1505 (0, functions_core_1.setProgrammingModel)(new ProgrammingModel());
1506}
1507exports.setup = setup;
1508
1509})();
1510
1511module.exports = __webpack_exports__;
1512/******/ })()
1513;
1514//# sourceMappingURL=azure-functions.js.map
\No newline at end of file