From 5fd940773a7ba648295ef36052c1600d654f24f8 Mon Sep 17 00:00:00 2001 From: Takanori Oishi Date: Sat, 4 Nov 2023 13:21:27 +0900 Subject: [PATCH 01/14] fix: Replace axios to Fetch API #82 --- .renovaterc.json | 8 +--- package-lock.json | 8 +++- package.json | 3 +- src/pr/index.spec.ts | 21 +++------ src/pr/index.ts | 6 +-- src/pr/postComments.spec.ts | 93 +++++++++++++++++++++++-------------- src/pr/postComments.ts | 20 ++++---- 7 files changed, 89 insertions(+), 70 deletions(-) diff --git a/.renovaterc.json b/.renovaterc.json index 8f7d944..443a530 100644 --- a/.renovaterc.json +++ b/.renovaterc.json @@ -1,9 +1,3 @@ { - "extends": ["github>bicstone/renovate-config"], - "packageRules": [ - { - "enabled": false, - "matchPackagePatterns": ["axios"] - } - ] + "extends": ["github>bicstone/renovate-config"] } diff --git a/package-lock.json b/package-lock.json index 601229d..7dbacaf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,8 @@ "dependencies": { "@actions/core": "1.10.1", "axios": "1.1.3", - "lodash.template": "4.5.0" + "lodash.template": "4.5.0", + "result-type-ts": "2.1.3" }, "devDependencies": { "@octokit/webhooks-examples": "7.3.1", @@ -5347,6 +5348,11 @@ "node": ">=8" } }, + "node_modules/result-type-ts": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/result-type-ts/-/result-type-ts-2.1.3.tgz", + "integrity": "sha512-bOOAJ3zoDRtqhLBoQP2WsllFcfmfnOYBVgOr79B+UHEDs+aWwJKs23DrtsGYPOZYv4OOFY0VJXziSYh2Z2jFcA==" + }, "node_modules/reusify": { "version": "1.0.4", "dev": true, diff --git a/package.json b/package.json index 4af12dc..76f1ed8 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,8 @@ "dependencies": { "@actions/core": "1.10.1", "axios": "1.1.3", - "lodash.template": "4.5.0" + "lodash.template": "4.5.0", + "result-type-ts": "2.1.3" }, "devDependencies": { "@octokit/webhooks-examples": "7.3.1", diff --git a/src/pr/index.spec.ts b/src/pr/index.spec.ts index fd52672..5c05655 100644 --- a/src/pr/index.spec.ts +++ b/src/pr/index.spec.ts @@ -6,7 +6,8 @@ import type { PullRequestEvent } from "@octokit/webhooks-types" import { pr, PrProps } from "./" import { ParsedPullRequest, parsePullRequest } from "./parsePullRequest" -import { postComments, Response } from "./postComments" +import { postComments } from "./postComments" +import { Result } from "result-type-ts" jest.mock("@actions/core") jest.mock("./parsePullRequest") @@ -51,16 +52,6 @@ describe.each(pullRequestEvents)("index", (event) => { ...parsedPullRequest, }) - const getResponse = (response?: Partial): Response => ({ - data: {}, - status: 200, - statusText: "OK", - headers: {}, - config: {}, - request: {}, - ...response, - }) - beforeEach(() => { mocked(info).mockImplementation((m) => m) mocked(setFailed).mockImplementation((m) => m) @@ -68,7 +59,7 @@ describe.each(pullRequestEvents)("index", (event) => { parsedPullRequest: getParsedPullRequest(), })) mocked(postComments).mockImplementation(() => - Promise.resolve(getResponse()), + Promise.resolve(Result.success("OK")), ) }) @@ -116,9 +107,11 @@ describe.each(pullRequestEvents)("index", (event) => { }) test("not continue and resolve processing when pr title without issueKey", async () => { - mocked(postComments).mockImplementation(() => Promise.resolve("string")) + mocked(postComments).mockImplementation(() => + Promise.resolve(Result.failure("failed")), + ) - await expect(pr(getConfigs())).resolves.toStrictEqual("string") + await expect(pr(getConfigs())).resolves.toStrictEqual("failed") expect(parsePullRequest).toHaveBeenCalledTimes(1) expect(postComments).toHaveBeenCalledTimes(1) diff --git a/src/pr/index.ts b/src/pr/index.ts index a7b01e3..28ab213 100644 --- a/src/pr/index.ts +++ b/src/pr/index.ts @@ -55,7 +55,7 @@ export const pr = async ({ startGroup(`コメント送信中`) - const response = await postComments({ + const result = await postComments({ parsedPullRequest, fixStatusId, closeStatusId, @@ -68,8 +68,8 @@ export const pr = async ({ apiKey, }) - if (typeof response === "string") { - return response + if (result.isFailure) { + return result.error } startGroup(`${parsedPullRequest.issueKey}:`) diff --git a/src/pr/postComments.spec.ts b/src/pr/postComments.spec.ts index b854c2d..6fcdf98 100644 --- a/src/pr/postComments.spec.ts +++ b/src/pr/postComments.spec.ts @@ -29,6 +29,7 @@ const prClosedCommentTemplate = const prMergedCommentTemplate = "merged,<%= sender.login %>,<%= title %>,<%= pr.html_url %>" const endpoint = `https://${apiHost}/api/v2/issues/${issueKey}?apiKey=${apiKey}` +const statusText = "OK" const events = (webhooks.find((v) => v.name === "pull_request")?.examples ?? []) as PullRequestEvent[] @@ -102,7 +103,7 @@ const getConfigs = ( const getResponse = (response?: Partial): Response => ({ data: {}, status: 200, - statusText: "OK", + statusText, headers: {}, config: {}, request: {}, @@ -126,50 +127,57 @@ describe("postComments", () => { const event = getEvent(_event) const comment = `${event.action},${login},${title},${html_url}` - test("post a comment to Backlog API", () => { + it("post a comment to Backlog API", async () => { const parsedPullRequest = getParsedPullRequest(event) const configs = getConfigs(parsedPullRequest) + const result = await postComments(configs) - expect(postComments(configs)).resolves.toStrictEqual(getResponse()) + expect(result.isSuccess).toEqual(true) + expect(result.value).toEqual(statusText) expect(mockedAxios.patch).toHaveBeenCalledTimes(1) expect(mockedAxios.patch).toHaveBeenCalledWith( endpoint, getRequestParams(comment), ) }) - test("post a comment only when change to fixed", () => { + it("post a comment only when change to fixed", async () => { const parsedPullRequest = getParsedPullRequest(event, { isFix: true }) const configs = getConfigs(parsedPullRequest) + const result = await postComments(configs) - expect(postComments(configs)).resolves.toStrictEqual(getResponse()) + expect(result.isSuccess).toEqual(true) + expect(result.value).toEqual(statusText) expect(mockedAxios.patch).toHaveBeenCalledTimes(1) expect(mockedAxios.patch).toHaveBeenCalledWith( endpoint, getRequestParams(comment), ) }) - test("post a comment only when change to close", () => { + it("post a comment only when change to close", async () => { const parsedPullRequest = getParsedPullRequest(event, { isClose: true }) const configs = getConfigs(parsedPullRequest) + const result = await postComments(configs) - expect(postComments(configs)).resolves.toStrictEqual(getResponse()) + expect(result.isSuccess).toEqual(true) + expect(result.value).toEqual(statusText) expect(mockedAxios.patch).toHaveBeenCalledTimes(1) expect(mockedAxios.patch).toHaveBeenCalledWith( endpoint, getRequestParams(comment), ) }) - test("not continue and return message if pr is draft", () => { + it("not continue and return message if pr is draft", async () => { const event = getEvent({ ..._event, pull_request: { ..._event.pull_request, draft: true }, } as PullRequestEvent) const parsedPullRequest = getParsedPullRequest(event) const configs = getConfigs(parsedPullRequest) + const result = await postComments(configs) + + expect(result.isSuccess).toEqual(false) + expect(result.error).toEqual("プルリクエストが下書きでした。") - expect(postComments(configs)).resolves.toStrictEqual( - "プルリクエストが下書きでした。", - ) expect(mockedAxios.patch).toHaveBeenCalledTimes(0) }) }, @@ -182,50 +190,57 @@ describe("postComments", () => { } as PullRequestEvent) const comment = `merged,${login},${title},${html_url}` - test("post a comment to Backlog API", () => { + it("post a comment to Backlog API", async () => { const parsedPullRequest = getParsedPullRequest(event) const configs = getConfigs(parsedPullRequest) + const result = await postComments(configs) - expect(postComments(configs)).resolves.toStrictEqual(getResponse()) + expect(result.isSuccess).toEqual(true) + expect(result.value).toEqual(statusText) expect(mockedAxios.patch).toHaveBeenCalledTimes(1) expect(mockedAxios.patch).toHaveBeenCalledWith( endpoint, getRequestParams(comment), ) }) - test("post a comment and change status when change to fixed", () => { + it("post a comment and change status when change to fixed", async () => { const parsedPullRequest = getParsedPullRequest(event, { isFix: true }) const configs = getConfigs(parsedPullRequest) + const result = await postComments(configs) - expect(postComments(configs)).resolves.toStrictEqual(getResponse()) + expect(result.isSuccess).toEqual(true) + expect(result.value).toEqual(statusText) expect(mockedAxios.patch).toHaveBeenCalledTimes(1) expect(mockedAxios.patch).toHaveBeenCalledWith( endpoint, getRequestParams(comment, { statusId: fixStatusId }), ) }) - test("post a comment and change status when change to close", () => { + it("post a comment and change status when change to close", async () => { const parsedPullRequest = getParsedPullRequest(event, { isClose: true }) const configs = getConfigs(parsedPullRequest) + const result = await postComments(configs) - expect(postComments(configs)).resolves.toStrictEqual(getResponse()) + expect(result.isSuccess).toEqual(true) + expect(result.value).toEqual(statusText) expect(mockedAxios.patch).toHaveBeenCalledTimes(1) expect(mockedAxios.patch).toHaveBeenCalledWith( endpoint, getRequestParams(comment, { statusId: closeStatusId }), ) }) - test("not continue and return message if pr is draft", () => { + it("not continue and return message if pr is draft", async () => { const event = getEvent({ ..._event, pull_request: { ..._event.pull_request, draft: true }, } as PullRequestEvent) const parsedPullRequest = getParsedPullRequest(event) const configs = getConfigs(parsedPullRequest) + const result = await postComments(configs) + + expect(result.isSuccess).toEqual(false) + expect(result.error).toEqual("プルリクエストが下書きでした。") - expect(postComments(configs)).resolves.toStrictEqual( - "プルリクエストが下書きでした。", - ) expect(mockedAxios.patch).toHaveBeenCalledTimes(0) }) }) @@ -234,63 +249,71 @@ describe("postComments", () => { const event = getEvent(_event) const comment = `closed,${login},${title},${html_url}` - test("post a comment to Backlog API", () => { + it("post a comment to Backlog API", async () => { const parsedPullRequest = getParsedPullRequest(event) const configs = getConfigs(parsedPullRequest) + const result = await postComments(configs) - expect(postComments(configs)).resolves.toStrictEqual(getResponse()) + expect(result.isSuccess).toEqual(true) + expect(result.value).toEqual(statusText) expect(mockedAxios.patch).toHaveBeenCalledTimes(1) expect(mockedAxios.patch).toHaveBeenCalledWith( endpoint, getRequestParams(comment), ) }) - test("post a comment only when change to fixed", () => { + it("post a comment only when change to fixed", async () => { const parsedPullRequest = getParsedPullRequest(event, { isFix: true }) const configs = getConfigs(parsedPullRequest) + const result = await postComments(configs) - expect(postComments(configs)).resolves.toStrictEqual(getResponse()) + expect(result.isSuccess).toEqual(true) + expect(result.value).toEqual(statusText) expect(mockedAxios.patch).toHaveBeenCalledTimes(1) expect(mockedAxios.patch).toHaveBeenCalledWith( endpoint, getRequestParams(comment), ) }) - test("post a comment only when change to close", () => { + it("post a comment only when change to close", async () => { const parsedPullRequest = getParsedPullRequest(event, { isClose: true }) const configs = getConfigs(parsedPullRequest) + const result = await postComments(configs) - expect(postComments(configs)).resolves.toStrictEqual(getResponse()) + expect(result.isSuccess).toEqual(true) + expect(result.value).toEqual(statusText) expect(mockedAxios.patch).toHaveBeenCalledTimes(1) expect(mockedAxios.patch).toHaveBeenCalledWith( endpoint, getRequestParams(comment), ) }) - test("not continue and return message if pr is draft", () => { + it("not continue and return message if pr is draft", async () => { const event = getEvent({ ..._event, pull_request: { ..._event.pull_request, draft: true }, } as PullRequestEvent) const parsedPullRequest = getParsedPullRequest(event) const configs = getConfigs(parsedPullRequest) + const result = await postComments(configs) + + expect(result.isSuccess).toEqual(false) + expect(result.error).toEqual("プルリクエストが下書きでした。") - expect(postComments(configs)).resolves.toStrictEqual( - "プルリクエストが下書きでした。", - ) expect(mockedAxios.patch).toHaveBeenCalledTimes(0) }) }) describe.each(unexpectedEvents)("unexpected", (_event) => { - test("not continue and return message", () => { + it("not continue and return message", async () => { const event = getEvent(_event) const parsedPullRequest = getParsedPullRequest(event) const configs = getConfigs(parsedPullRequest) + const result = await postComments(configs) + + expect(result.isSuccess).toEqual(false) + expect(result.error).toEqual("予期しないイベントでした。") - expect(postComments(configs)).resolves.toStrictEqual( - "予期しないイベントでした。", - ) expect(mockedAxios.patch).toHaveBeenCalledTimes(0) }) }) diff --git a/src/pr/postComments.ts b/src/pr/postComments.ts index 0330f26..8a25bdf 100644 --- a/src/pr/postComments.ts +++ b/src/pr/postComments.ts @@ -1,3 +1,4 @@ +import { Result } from "result-type-ts" import { URLSearchParams } from "url" import axios, { AxiosResponse } from "axios" import template from "lodash.template" @@ -28,7 +29,7 @@ export type PostCommentsProps = { * Post the comment to Backlog API */ -export const postComments = ({ +export const postComments = async ({ parsedPullRequest, fixStatusId, closeStatusId, @@ -39,7 +40,7 @@ export const postComments = ({ prMergedCommentTemplate, apiHost, apiKey, -}: PostCommentsProps): Promise => { +}: PostCommentsProps): Promise> => { const { issueKey, isFix, isClose, action, pr } = parsedPullRequest const endpoint = updateIssueApiUrlTemplate({ @@ -68,12 +69,12 @@ export const postComments = ({ })() if (!comment) { - return Promise.resolve("予期しないイベントでした。") + return Result.failure("予期しないイベントでした。") } const draft = pr.draft if (draft) { - return Promise.resolve("プルリクエストが下書きでした。") + return Result.failure("プルリクエストが下書きでした。") } const status = (() => { @@ -83,9 +84,10 @@ export const postComments = ({ })() const body = { comment, ...status } - return axios - .patch(endpoint, new URLSearchParams(body).toString()) - .then((response) => { - return response - }) + const response = await axios.patch( + endpoint, + new URLSearchParams(body).toString(), + ) + + return Result.success(response.statusText) } From 6379c3af70752f6f02438d6dd9290446a64c171a Mon Sep 17 00:00:00 2001 From: Takanori Oishi Date: Sat, 4 Nov 2023 13:22:37 +0900 Subject: [PATCH 02/14] fix: Replace axios to Fetch API #82 --- dist/index.js | 234 ++++++++++++++++++++++++++++++++++++-- dist/index.js.LICENSE.txt | 125 ++++++++++++++++++++ 2 files changed, 348 insertions(+), 11 deletions(-) diff --git a/dist/index.js b/dist/index.js index a57d720..80debbc 100644 --- a/dist/index.js +++ b/dist/index.js @@ -7152,6 +7152,220 @@ function getEnv(key) { exports.getProxyForUrl = getProxyForUrl; +/***/ }), + +/***/ 6556: +/***/ ((module) => { + +"use strict"; + +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/index.ts +var src_exports = {}; +__export(src_exports, { + Result: () => Result, + prototype: () => prototype +}); +module.exports = __toCommonJS(src_exports); +function getOrThrow() { + if (this.isSuccess) + return this.value; + throw this.error; +} +function toUnion() { + if (this.isSuccess) + return this.value; + return this.error; +} +function ifSuccess(f) { + if (this.isFailure) + return void 0; + return f(this.value); +} +function ifFailure(f) { + if (this.isSuccess) + return void 0; + return f(this.error); +} +function match(f, g) { + if (this.isSuccess) + return f(this.value); + return g(this.error); +} +function map(f) { + if (this.isFailure) + return this; + return Result.success(f(this.value)); +} +function mapError(f) { + if (this.isSuccess) + return this; + return Result.failure(f(this.error)); +} +function flatMap(f) { + if (this.isFailure) + return this; + return f(this.value); +} +function flatten() { + if (this.isFailure) + return this; + return this.value; +} +function assertErrorInstanceOf(constructor) { + if (this.isSuccess) + return this; + if (this.error instanceof constructor) + return this; + throw new TypeError(`Assertion failed: Expected error to be an instance of ${constructor.name}.`); +} +var prototype = { + /** + * Returns `this.value` if `this` is a successful result, otherwise throws `this.error`. + * @example Returns the payload of a successful result. + * Result.success(123).getOrThrow() // 123 + * @example Throws the payload of a failed result. + * Result.failure('error').getOrThrow() // throws 'error' + */ + getOrThrow, + /** + * Returns the payload of the result. + * @example Returns the payload of a successful result. + * Result.success(123).toUnion() // 123 + * @example Returns the payload of a failed result. + * Result.failure('error').toUnion() // 'error' + */ + toUnion, + /** + * Applies the given function to this.value if it's a successful result, otherwise returns undefined. + * @example + * Result.success(123).ifSuccess((x) => x * 2) // 246 + * Result.failure('error').ifSuccess((x: number) => x * 2) // undefined + */ + ifSuccess, + /** + * Applies the given function to this.error if it's a failed result, otherwise returns undefined. + * @example + * Result.success(123).ifFailure((x: string) => x + '!') // undefined + * Result.failure('error').ifFailure((x) => x + '!') // 'error!' + */ + ifFailure, + /** + * Return the result of applying one of the given functions to the payload. + * @example + * Result.success(123).match((x) => x * 2, (x: string) => x + '!') // 246 + * Result.failure('error').match((x: number) => x * 2, (x) => x + '!') // 'error!' + */ + match, + /** + * Creates a Result value by modifying the payload of the successful result using the given function. + * @example + * Result.success(123).map((x) => x * 2) // Result.success(246) + * Result.failure('error').map((x: number) => x * 2) // Result.failure('error') + */ + map, + /** + * Creates a Result value by modifying the payload of the failed result using the given function. + * @example + * Result.success(123).mapError((x: string) => x + '!') // Result.success(123) + * Result.failure('error').mapError((x) => x + '!') // Result.failure('error!') + */ + mapError, + /** + * Maps the payload of the successful result and flattens the nested Result type. + * @example + * Result.success(123).flatMap((x) => Result.success(x * 2)) // Result.success(246) + * Result.success(123).flatMap((x) => Result.failure('error')) // Result.failure('error') + * Result.failure('error').flatMap((x: number) => Result.success(x * 2)) // Result.failure('error') + * Result.failure('error').flatMap((x) => Result.failure('failure')) // Result.failure('error') + */ + flatMap, + /** + * Flattens the nested Result type. + * @example + * Result.success(Result.success(123)).flatten() // Result.success(123) + * Result.success(Result.failure('error')).flatten() // Result.failure('error') + * Result.failure('error').flatten() // Result.failure('error') + */ + flatten, + /** + * Perform a safe cast of the error type to the given class. If the payload of the failed result is not instance of constructor, throws TypeError. + * @example + * const result: Result = Result.tryCatch(() => { + * if (Math.random() >= 0) { + * throw new Error('error') + * } else { + * return 123 + * } + * }).assertErrorInstanceOf(Error) + */ + assertErrorInstanceOf +}; +var Result; +((Result2) => { + function success(value) { + return withPrototype({ value, isSuccess: true, isFailure: false }, prototype); + } + Result2.success = success; + function failure(error) { + return withPrototype({ error, isSuccess: false, isFailure: true }, prototype); + } + Result2.failure = failure; + function tryCatch(f) { + try { + return success(f()); + } catch (error) { + return failure(error); + } + } + Result2.tryCatch = tryCatch; + async function fromPromise(promise) { + try { + return success(await promise); + } catch (error) { + return failure(error); + } + } + Result2.fromPromise = fromPromise; + function fromNullish(value) { + return value != null ? success(value) : failure(value); + } + Result2.fromNullish = fromNullish; + function all(results) { + const values = []; + for (const result of results) { + if (result.isFailure) + return result; + values.push(result.value); + } + return success(values); + } + Result2.all = all; +})(Result || (Result = {})); +function withPrototype(target, prototype2) { + return Object.assign(Object.create(prototype2), target); +} +// Annotate the CommonJS export names for ESM import in node: +0 && (0); + + /***/ }), /***/ 9318: @@ -8439,7 +8653,7 @@ const pr = async ({ event, projectKey, fixKeywords, closeKeywords, fixStatusId, } (0, core_1.endGroup)(); (0, core_1.startGroup)(`コメント送信中`); - const response = await (0, postComments_1.postComments)({ + const result = await (0, postComments_1.postComments)({ parsedPullRequest, fixStatusId, closeStatusId, @@ -8451,8 +8665,8 @@ const pr = async ({ event, projectKey, fixKeywords, closeKeywords, fixStatusId, apiHost, apiKey, }); - if (typeof response === "string") { - return response; + if (result.isFailure) { + return result.error; } (0, core_1.startGroup)(`${parsedPullRequest.issueKey}:`); (0, core_1.info)(parsedPullRequest.title); @@ -8524,6 +8738,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.postComments = void 0; +const result_type_ts_1 = __nccwpck_require__(6556); const url_1 = __nccwpck_require__(7310); const axios_1 = __importDefault(__nccwpck_require__(8757)); const lodash_template_1 = __importDefault(__nccwpck_require__(417)); @@ -8533,7 +8748,7 @@ const updateIssueApiUrlTemplate = (0, lodash_template_1.default)("https://<%=api /** * Post the comment to Backlog API */ -const postComments = ({ parsedPullRequest, fixStatusId, closeStatusId, prOpenedCommentTemplate, prReopenedCommentTemplate, prReadyForReviewCommentTemplate, prClosedCommentTemplate, prMergedCommentTemplate, apiHost, apiKey, }) => { +const postComments = async ({ parsedPullRequest, fixStatusId, closeStatusId, prOpenedCommentTemplate, prReopenedCommentTemplate, prReadyForReviewCommentTemplate, prClosedCommentTemplate, prMergedCommentTemplate, apiHost, apiKey, }) => { const { issueKey, isFix, isClose, action, pr } = parsedPullRequest; const endpoint = updateIssueApiUrlTemplate({ apiHost, @@ -8560,11 +8775,11 @@ const postComments = ({ parsedPullRequest, fixStatusId, closeStatusId, prOpenedC } })(); if (!comment) { - return Promise.resolve("予期しないイベントでした。"); + return result_type_ts_1.Result.failure("予期しないイベントでした。"); } const draft = pr.draft; if (draft) { - return Promise.resolve("プルリクエストが下書きでした。"); + return result_type_ts_1.Result.failure("プルリクエストが下書きでした。"); } const status = (() => { if (pr.merged && isFix) @@ -8575,11 +8790,8 @@ const postComments = ({ parsedPullRequest, fixStatusId, closeStatusId, prOpenedC return undefined; })(); const body = { comment, ...status }; - return axios_1.default - .patch(endpoint, new url_1.URLSearchParams(body).toString()) - .then((response) => { - return response; - }); + const response = await axios_1.default.patch(endpoint, new url_1.URLSearchParams(body).toString()); + return result_type_ts_1.Result.success(response.statusText); }; exports.postComments = postComments; diff --git a/dist/index.js.LICENSE.txt b/dist/index.js.LICENSE.txt index 862a642..a144ca0 100644 --- a/dist/index.js.LICENSE.txt +++ b/dist/index.js.LICENSE.txt @@ -430,6 +430,131 @@ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +result-type-ts +CC0-1.0 +Creative Commons Legal Code + +CC0 1.0 Universal + + CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE + LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN + ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS + INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES + REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS + PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM + THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED + HEREUNDER. + +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator +and subsequent owner(s) (each and all, an "owner") of an original work of +authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for +the purpose of contributing to a commons of creative, cultural and +scientific works ("Commons") that the public can reliably and without fear +of later claims of infringement build upon, modify, incorporate in other +works, reuse and redistribute as freely as possible in any form whatsoever +and for any purposes, including without limitation commercial purposes. +These owners may contribute to the Commons to promote the ideal of a free +culture and the further production of creative, cultural and scientific +works, or to gain reputation or greater distribution for their Work in +part through the use and efforts of others. + +For these and/or other purposes and motivations, and without any +expectation of additional consideration or compensation, the person +associating CC0 with a Work (the "Affirmer"), to the extent that he or she +is an owner of Copyright and Related Rights in the Work, voluntarily +elects to apply CC0 to the Work and publicly distribute the Work under its +terms, with knowledge of his or her Copyright and Related Rights in the +Work and the meaning and intended legal effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be +protected by copyright and related or neighboring rights ("Copyright and +Related Rights"). Copyright and Related Rights include, but are not +limited to, the following: + + i. the right to reproduce, adapt, distribute, perform, display, + communicate, and translate a Work; + ii. moral rights retained by the original author(s) and/or performer(s); +iii. publicity and privacy rights pertaining to a person's image or + likeness depicted in a Work; + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + v. rights protecting the extraction, dissemination, use and reuse of data + in a Work; + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation + thereof, including any amended or successor version of such + directive); and +vii. other similar, equivalent or corresponding rights throughout the + world based on applicable law or treaty, and any national + implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention +of, applicable law, Affirmer hereby overtly, fully, permanently, +irrevocably and unconditionally waives, abandons, and surrenders all of +Affirmer's Copyright and Related Rights and associated claims and causes +of action, whether now known or unknown (including existing as well as +future claims and causes of action), in the Work (i) in all territories +worldwide, (ii) for the maximum duration provided by applicable law or +treaty (including future time extensions), (iii) in any current or future +medium and for any number of copies, and (iv) for any purpose whatsoever, +including without limitation commercial, advertising or promotional +purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each +member of the public at large and to the detriment of Affirmer's heirs and +successors, fully intending that such Waiver shall not be subject to +revocation, rescission, cancellation, termination, or any other legal or +equitable action to disrupt the quiet enjoyment of the Work by the public +as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason +be judged legally invalid or ineffective under applicable law, then the +Waiver shall be preserved to the maximum extent permitted taking into +account Affirmer's express Statement of Purpose. In addition, to the +extent the Waiver is so judged Affirmer hereby grants to each affected +person a royalty-free, non transferable, non sublicensable, non exclusive, +irrevocable and unconditional license to exercise Affirmer's Copyright and +Related Rights in the Work (i) in all territories worldwide, (ii) for the +maximum duration provided by applicable law or treaty (including future +time extensions), (iii) in any current or future medium and for any number +of copies, and (iv) for any purpose whatsoever, including without +limitation commercial, advertising or promotional purposes (the +"License"). The License shall be deemed effective as of the date CC0 was +applied by Affirmer to the Work. Should any part of the License for any +reason be judged legally invalid or ineffective under applicable law, such +partial invalidity or ineffectiveness shall not invalidate the remainder +of the License, and in such case Affirmer hereby affirms that he or she +will not (i) exercise any of his or her remaining Copyright and Related +Rights in the Work or (ii) assert any associated claims and causes of +action with respect to the Work, in either case contrary to Affirmer's +express Statement of Purpose. + +4. Limitations and Disclaimers. + + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + b. Affirmer offers the Work as-is and makes no representations or + warranties of any kind concerning the Work, express, implied, + statutory or otherwise, including without limitation warranties of + title, merchantability, fitness for a particular purpose, non + infringement, or the absence of latent or other defects, accuracy, or + the present or absence of errors, whether or not discoverable, all to + the greatest extent permissible under applicable law. + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person's Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the + Work. + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to + this CC0 or use of the Work. + + supports-color MIT MIT License From 35bd85d717e2ed8eb45825d79c58c09966381cf8 Mon Sep 17 00:00:00 2001 From: Takanori Oishi Date: Sat, 4 Nov 2023 13:57:18 +0900 Subject: [PATCH 03/14] fix: Replace axios to Fetch API #82 --- src/push/index.spec.ts | 11 ----------- src/push/postComments.ts | 7 +++---- src/push/postCommits.spec.ts | 5 ----- 3 files changed, 3 insertions(+), 20 deletions(-) diff --git a/src/push/index.spec.ts b/src/push/index.spec.ts index 56261fb..fa5fe56 100644 --- a/src/push/index.spec.ts +++ b/src/push/index.spec.ts @@ -2,7 +2,6 @@ import { info, setFailed } from "@actions/core" import { mocked } from "jest-mock" import webhooks from "@octokit/webhooks-examples" -import type { AxiosResponse } from "axios" import type { PushEvent } from "@octokit/webhooks-types" import { push } from "./" @@ -30,20 +29,10 @@ const configs = { closeStatusId: "closeStatusId", } -const axiosResponse: AxiosResponse = { - data: {}, - status: 200, - statusText: "OK", - headers: {}, - config: {}, - request: {}, -} - const message = "message" const issueKey = "issueKey" const basePostCommentsResponse: Response = { - response: axiosResponse, commits: [ { message, diff --git a/src/push/postComments.ts b/src/push/postComments.ts index ac21649..32eb5e0 100644 --- a/src/push/postComments.ts +++ b/src/push/postComments.ts @@ -1,5 +1,5 @@ import { URLSearchParams } from "url" -import axios, { AxiosResponse } from "axios" +import axios from "axios" import template from "lodash.template" import { ParsedCommits, ParsedCommit } from "./parseCommits" import { ParsedRef } from "./parseRef" @@ -11,7 +11,6 @@ const updateIssueApiUrlTemplate = template( ) export type Response = { - response: AxiosResponse> commits: ParsedCommit[] issueKey: string isFix: boolean @@ -100,7 +99,7 @@ const createPatchCommentRequest = ({ return axios .patch(endpoint, new URLSearchParams(body).toString()) - .then((response) => { - return { response, commits, issueKey, isFix, isClose } + .then(() => { + return { commits, issueKey, isFix, isClose } }) } diff --git a/src/push/postCommits.spec.ts b/src/push/postCommits.spec.ts index 80196b6..1948a30 100644 --- a/src/push/postCommits.spec.ts +++ b/src/push/postCommits.spec.ts @@ -86,7 +86,6 @@ describe("postComments", () => { } const params = new url.URLSearchParams(body).toString() const response: Response = { - response: axiosResponse, commits: parsedCommits[issueKey], issueKey: issueKey, isFix: false, @@ -133,7 +132,6 @@ describe("postComments", () => { } const params = new url.URLSearchParams(body).toString() const response: Response = { - response: axiosResponse, commits: parsedCommits[issueKey], issueKey: issueKey, isFix: true, @@ -180,7 +178,6 @@ describe("postComments", () => { } const params = new url.URLSearchParams(body).toString() const response: Response = { - response: axiosResponse, commits: parsedCommits[issueKey], issueKey: issueKey, isFix: false, @@ -227,14 +224,12 @@ describe("postComments", () => { } const parsedRef: ParsedRef = baseParsedRef const response1: Response = { - response: axiosResponse, commits: parsedCommits[`${projectKey}-1`], issueKey: `${projectKey}-1`, isFix: false, isClose: false, } const response2: Response = { - response: axiosResponse, commits: parsedCommits[`${projectKey}-2`], issueKey: `${projectKey}-2`, isFix: false, From d9ffcc9f02a0c99d94687ba5dad4770ce6df8a52 Mon Sep 17 00:00:00 2001 From: Takanori Oishi Date: Sat, 4 Nov 2023 13:57:42 +0900 Subject: [PATCH 04/14] fix: Replace axios to Fetch API #82 --- dist/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/index.js b/dist/index.js index 80debbc..e2b2da2 100644 --- a/dist/index.js +++ b/dist/index.js @@ -9023,8 +9023,8 @@ const createPatchCommentRequest = ({ commits, ref, issueKey, fixStatusId, closeS const body = { comment, ...status }; return axios_1.default .patch(endpoint, new url_1.URLSearchParams(body).toString()) - .then((response) => { - return { response, commits, issueKey, isFix, isClose }; + .then(() => { + return { commits, issueKey, isFix, isClose }; }); }; From 32697e373d2521b946f91ef2630cb16548e78b96 Mon Sep 17 00:00:00 2001 From: Takanori Oishi Date: Sat, 4 Nov 2023 15:17:12 +0900 Subject: [PATCH 05/14] fix: Replace axios to Fetch API #82 --- package-lock.json | 82 -------------------------- package.json | 1 - src/pr/postComments.spec.ts | 108 ++++++++++++++-------------------- src/pr/postComments.ts | 17 +++--- src/push/postComments.ts | 21 ++++--- src/push/postCommits.spec.ts | 110 ++++++++++++++++++----------------- 6 files changed, 124 insertions(+), 215 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7dbacaf..aa389c9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,6 @@ "license": "MIT", "dependencies": { "@actions/core": "1.10.1", - "axios": "1.1.3", "lodash.template": "4.5.0", "result-type-ts": "2.1.3" }, @@ -1841,10 +1840,6 @@ "dev": true, "license": "MIT" }, - "node_modules/asynckit": { - "version": "0.4.0", - "license": "MIT" - }, "node_modules/available-typed-arrays": { "version": "1.0.5", "dev": true, @@ -1856,15 +1851,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/axios": { - "version": "1.1.3", - "license": "MIT", - "dependencies": { - "follow-redirects": "^1.15.0", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, "node_modules/babel-jest": { "version": "29.7.0", "dev": true, @@ -2181,16 +2167,6 @@ "dev": true, "license": "MIT" }, - "node_modules/combined-stream": { - "version": "1.0.8", - "license": "MIT", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/comment-parser": { "version": "1.4.0", "dev": true, @@ -2325,13 +2301,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/detect-newline": { "version": "3.1.0", "dev": true, @@ -3089,24 +3058,6 @@ "dev": true, "license": "ISC" }, - "node_modules/follow-redirects": { - "version": "1.15.2", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "license": "MIT", - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, "node_modules/for-each": { "version": "0.3.3", "dev": true, @@ -3115,18 +3066,6 @@ "is-callable": "^1.1.3" } }, - "node_modules/form-data": { - "version": "4.0.0", - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/fs.realpath": { "version": "1.0.0", "dev": true, @@ -4672,23 +4611,6 @@ "node": ">=8.6" } }, - "node_modules/mime-db": { - "version": "1.52.0", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/mimic-fn": { "version": "2.1.0", "dev": true, @@ -5166,10 +5088,6 @@ "node": ">= 6" } }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "license": "MIT" - }, "node_modules/punycode": { "version": "2.3.0", "dev": true, diff --git a/package.json b/package.json index 76f1ed8..377f9c6 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,6 @@ "license": "MIT", "dependencies": { "@actions/core": "1.10.1", - "axios": "1.1.3", "lodash.template": "4.5.0", "result-type-ts": "2.1.3" }, diff --git a/src/pr/postComments.spec.ts b/src/pr/postComments.spec.ts index 6fcdf98..39f7be6 100644 --- a/src/pr/postComments.spec.ts +++ b/src/pr/postComments.spec.ts @@ -1,14 +1,9 @@ /* eslint-disable @typescript-eslint/naming-convention */ -import url from "url" -import axios from "axios" -import { postComments, PostCommentsProps, Response } from "./postComments" +import { postComments, PostCommentsProps } from "./postComments" import { ParsedPullRequest } from "./parsePullRequest" import { PullRequestEvent } from "@octokit/webhooks-types" import webhooks from "@octokit/webhooks-examples" -jest.mock("axios") -const mockedAxios = axios as jest.Mocked - const login = "login" const html_url = "html_url" const fixStatusId = "fixStatusId" @@ -100,25 +95,28 @@ const getConfigs = ( ...configs, }) -const getResponse = (response?: Partial): Response => ({ - data: {}, - status: 200, - statusText, - headers: {}, - config: {}, - request: {}, - ...response, -}) - -const getRequestParams = (comment: string, params?: Record) => - new url.URLSearchParams({ +const getFetchOptions = ( + comment: string, + params?: Record, +) => ({ + method: "PATCH", + body: new URLSearchParams({ comment, ...params, - }).toString() + }), +}) describe("postComments", () => { + let fetchSpy = jest.spyOn(global, "fetch") + beforeEach(() => { - mockedAxios.patch.mockImplementation(() => Promise.resolve(getResponse())) + fetchSpy = jest.spyOn(global, "fetch") + fetchSpy.mockImplementation(() => + Promise.resolve({ + ok: true, + statusText: statusText, + } as Response), + ) }) describe.each(openedEvents)( @@ -134,10 +132,10 @@ describe("postComments", () => { expect(result.isSuccess).toEqual(true) expect(result.value).toEqual(statusText) - expect(mockedAxios.patch).toHaveBeenCalledTimes(1) - expect(mockedAxios.patch).toHaveBeenCalledWith( + expect(fetchSpy).toHaveBeenCalledTimes(1) + expect(fetchSpy).toHaveBeenCalledWith( endpoint, - getRequestParams(comment), + getFetchOptions(comment), ) }) it("post a comment only when change to fixed", async () => { @@ -147,10 +145,10 @@ describe("postComments", () => { expect(result.isSuccess).toEqual(true) expect(result.value).toEqual(statusText) - expect(mockedAxios.patch).toHaveBeenCalledTimes(1) - expect(mockedAxios.patch).toHaveBeenCalledWith( + expect(fetchSpy).toHaveBeenCalledTimes(1) + expect(fetchSpy).toHaveBeenCalledWith( endpoint, - getRequestParams(comment), + getFetchOptions(comment), ) }) it("post a comment only when change to close", async () => { @@ -160,10 +158,10 @@ describe("postComments", () => { expect(result.isSuccess).toEqual(true) expect(result.value).toEqual(statusText) - expect(mockedAxios.patch).toHaveBeenCalledTimes(1) - expect(mockedAxios.patch).toHaveBeenCalledWith( + expect(fetchSpy).toHaveBeenCalledTimes(1) + expect(fetchSpy).toHaveBeenCalledWith( endpoint, - getRequestParams(comment), + getFetchOptions(comment), ) }) it("not continue and return message if pr is draft", async () => { @@ -177,8 +175,7 @@ describe("postComments", () => { expect(result.isSuccess).toEqual(false) expect(result.error).toEqual("プルリクエストが下書きでした。") - - expect(mockedAxios.patch).toHaveBeenCalledTimes(0) + expect(fetchSpy).toHaveBeenCalledTimes(0) }) }, ) @@ -197,11 +194,8 @@ describe("postComments", () => { expect(result.isSuccess).toEqual(true) expect(result.value).toEqual(statusText) - expect(mockedAxios.patch).toHaveBeenCalledTimes(1) - expect(mockedAxios.patch).toHaveBeenCalledWith( - endpoint, - getRequestParams(comment), - ) + expect(fetchSpy).toHaveBeenCalledTimes(1) + expect(fetchSpy).toHaveBeenCalledWith(endpoint, getFetchOptions(comment)) }) it("post a comment and change status when change to fixed", async () => { const parsedPullRequest = getParsedPullRequest(event, { isFix: true }) @@ -210,10 +204,10 @@ describe("postComments", () => { expect(result.isSuccess).toEqual(true) expect(result.value).toEqual(statusText) - expect(mockedAxios.patch).toHaveBeenCalledTimes(1) - expect(mockedAxios.patch).toHaveBeenCalledWith( + expect(fetchSpy).toHaveBeenCalledTimes(1) + expect(fetchSpy).toHaveBeenCalledWith( endpoint, - getRequestParams(comment, { statusId: fixStatusId }), + getFetchOptions(comment, { statusId: fixStatusId }), ) }) it("post a comment and change status when change to close", async () => { @@ -223,10 +217,10 @@ describe("postComments", () => { expect(result.isSuccess).toEqual(true) expect(result.value).toEqual(statusText) - expect(mockedAxios.patch).toHaveBeenCalledTimes(1) - expect(mockedAxios.patch).toHaveBeenCalledWith( + expect(fetchSpy).toHaveBeenCalledTimes(1) + expect(fetchSpy).toHaveBeenCalledWith( endpoint, - getRequestParams(comment, { statusId: closeStatusId }), + getFetchOptions(comment, { statusId: closeStatusId }), ) }) it("not continue and return message if pr is draft", async () => { @@ -240,8 +234,7 @@ describe("postComments", () => { expect(result.isSuccess).toEqual(false) expect(result.error).toEqual("プルリクエストが下書きでした。") - - expect(mockedAxios.patch).toHaveBeenCalledTimes(0) + expect(fetchSpy).toHaveBeenCalledTimes(0) }) }) @@ -256,11 +249,8 @@ describe("postComments", () => { expect(result.isSuccess).toEqual(true) expect(result.value).toEqual(statusText) - expect(mockedAxios.patch).toHaveBeenCalledTimes(1) - expect(mockedAxios.patch).toHaveBeenCalledWith( - endpoint, - getRequestParams(comment), - ) + expect(fetchSpy).toHaveBeenCalledTimes(1) + expect(fetchSpy).toHaveBeenCalledWith(endpoint, getFetchOptions(comment)) }) it("post a comment only when change to fixed", async () => { const parsedPullRequest = getParsedPullRequest(event, { isFix: true }) @@ -269,11 +259,8 @@ describe("postComments", () => { expect(result.isSuccess).toEqual(true) expect(result.value).toEqual(statusText) - expect(mockedAxios.patch).toHaveBeenCalledTimes(1) - expect(mockedAxios.patch).toHaveBeenCalledWith( - endpoint, - getRequestParams(comment), - ) + expect(fetchSpy).toHaveBeenCalledTimes(1) + expect(fetchSpy).toHaveBeenCalledWith(endpoint, getFetchOptions(comment)) }) it("post a comment only when change to close", async () => { const parsedPullRequest = getParsedPullRequest(event, { isClose: true }) @@ -282,11 +269,8 @@ describe("postComments", () => { expect(result.isSuccess).toEqual(true) expect(result.value).toEqual(statusText) - expect(mockedAxios.patch).toHaveBeenCalledTimes(1) - expect(mockedAxios.patch).toHaveBeenCalledWith( - endpoint, - getRequestParams(comment), - ) + expect(fetchSpy).toHaveBeenCalledTimes(1) + expect(fetchSpy).toHaveBeenCalledWith(endpoint, getFetchOptions(comment)) }) it("not continue and return message if pr is draft", async () => { const event = getEvent({ @@ -299,8 +283,7 @@ describe("postComments", () => { expect(result.isSuccess).toEqual(false) expect(result.error).toEqual("プルリクエストが下書きでした。") - - expect(mockedAxios.patch).toHaveBeenCalledTimes(0) + expect(fetchSpy).toHaveBeenCalledTimes(0) }) }) @@ -313,8 +296,7 @@ describe("postComments", () => { expect(result.isSuccess).toEqual(false) expect(result.error).toEqual("予期しないイベントでした。") - - expect(mockedAxios.patch).toHaveBeenCalledTimes(0) + expect(fetchSpy).toHaveBeenCalledTimes(0) }) }) }) diff --git a/src/pr/postComments.ts b/src/pr/postComments.ts index 8a25bdf..6ddf114 100644 --- a/src/pr/postComments.ts +++ b/src/pr/postComments.ts @@ -1,6 +1,5 @@ import { Result } from "result-type-ts" import { URLSearchParams } from "url" -import axios, { AxiosResponse } from "axios" import template from "lodash.template" import { ParsedPullRequest } from "./parsePullRequest" @@ -10,8 +9,6 @@ const updateIssueApiUrlTemplate = template( "https://<%=apiHost%>/api/v2/issues/<%=issueKey%>?apiKey=<%=apiKey%>", ) -export type Response = AxiosResponse> - export type PostCommentsProps = { parsedPullRequest: ParsedPullRequest fixStatusId: string @@ -84,10 +81,16 @@ export const postComments = async ({ })() const body = { comment, ...status } - const response = await axios.patch( - endpoint, - new URLSearchParams(body).toString(), - ) + const fetchOptions: RequestInit = { + method: "PATCH", + body: new URLSearchParams(body), + } + + const response = await fetch(endpoint, fetchOptions) + + if (!response.ok) { + throw new Error(response.statusText) + } return Result.success(response.statusText) } diff --git a/src/push/postComments.ts b/src/push/postComments.ts index 32eb5e0..0824dfa 100644 --- a/src/push/postComments.ts +++ b/src/push/postComments.ts @@ -1,5 +1,3 @@ -import { URLSearchParams } from "url" -import axios from "axios" import template from "lodash.template" import { ParsedCommits, ParsedCommit } from "./parseCommits" import { ParsedRef } from "./parseRef" @@ -71,7 +69,7 @@ type CreatePatchCommentRequestProps = { apiKey: string } -const createPatchCommentRequest = ({ +const createPatchCommentRequest = async ({ commits, ref, issueKey, @@ -97,9 +95,16 @@ const createPatchCommentRequest = ({ })() const body = { comment, ...status } - return axios - .patch(endpoint, new URLSearchParams(body).toString()) - .then(() => { - return { commits, issueKey, isFix, isClose } - }) + const fetchOptions: RequestInit = { + method: "PATCH", + body: new URLSearchParams(body), + } + + const response = await fetch(endpoint, fetchOptions) + + if (!response.ok) { + throw new Error(response.statusText) + } + + return { commits, issueKey, isFix, isClose } } diff --git a/src/push/postCommits.spec.ts b/src/push/postCommits.spec.ts index 1948a30..9e53595 100644 --- a/src/push/postCommits.spec.ts +++ b/src/push/postCommits.spec.ts @@ -1,12 +1,8 @@ -import url from "url" -import axios, { AxiosResponse } from "axios" +/* eslint-disable @typescript-eslint/naming-convention */ import { ParsedCommits } from "./parseCommits" import { postComments, Response } from "./postComments" import { ParsedRef } from "./parseRef" -jest.mock("axios") -const mockedAxios = axios as jest.Mocked - const fixStatusId = "fixStatusId" const closeStatusId = "closeStatusId" const pushCommentTemplate = @@ -58,33 +54,34 @@ const baseParsedRef: ParsedRef = { name: "branch-name", url: "https://example.com/foo/bar/tree/branch-name", } -const axiosResponse: AxiosResponse = { - data: {}, - status: 200, - statusText: "OK", - headers: {}, - config: {}, - request: {}, -} + +const getFetchOptions = ( + comment: string, + params?: Record, +) => ({ + method: "PATCH", + body: new URLSearchParams({ + comment, + ...params, + }), +}) describe("postComments", () => { + let fetchSpy = jest.spyOn(global, "fetch") + beforeEach(() => { - mockedAxios.patch.mockImplementation(() => Promise.resolve(axiosResponse)) + fetchSpy = jest.spyOn(global, "fetch") + fetchSpy.mockImplementation(() => + Promise.resolve({ + ok: true, + } as NodeJS.fetch.Response), + ) }) test("parseCommits post a comment to Backlog API", () => { const endpoint = `https://${apiHost}/api/v2/issues/${issueKey}?apiKey=${apiKey}` const parsedCommits: ParsedCommits = baseCommits const parsedRef: ParsedRef = baseParsedRef - const body = { - comment: - `${baseCommit.author.name}さんが[${baseParsedRef.name}](${baseParsedRef.url})にプッシュしました` + - "\n" + - "\n" + - `+ ${baseCommit.comment} ` + - `([${baseCommit.id.slice(0, 7).slice(0, 7)}](${baseCommit.url}))`, - } - const params = new url.URLSearchParams(body).toString() const response: Response = { commits: parsedCommits[issueKey], issueKey: issueKey, @@ -103,9 +100,17 @@ describe("postComments", () => { apiKey, }), ).resolves.toStrictEqual([response]) - expect(mockedAxios.patch).toHaveBeenCalled() - expect(mockedAxios.patch).toHaveBeenCalledTimes(1) - expect(mockedAxios.patch).toHaveBeenCalledWith(endpoint, params) + expect(fetchSpy).toHaveBeenCalledTimes(1) + expect(fetchSpy).toHaveBeenCalledWith( + endpoint, + getFetchOptions( + `${baseCommit.author.name}さんが[${baseParsedRef.name}](${baseParsedRef.url})にプッシュしました` + + "\n" + + "\n" + + `+ ${baseCommit.comment} ` + + `([${baseCommit.id.slice(0, 7).slice(0, 7)}](${baseCommit.url}))`, + ), + ) }) test("parseCommits post a comment and change status when change to fixed", () => { @@ -121,16 +126,6 @@ describe("postComments", () => { ], } const parsedRef: ParsedRef = baseParsedRef - const body = { - comment: - `${baseCommit.author.name}さんが[${baseParsedRef.name}](${baseParsedRef.url})にプッシュしました` + - "\n" + - "\n" + - `+ ${baseCommit.comment} ` + - `([${baseCommit.id.slice(0, 7)}](${baseCommit.url}))`, - statusId: fixStatusId, - } - const params = new url.URLSearchParams(body).toString() const response: Response = { commits: parsedCommits[issueKey], issueKey: issueKey, @@ -149,9 +144,18 @@ describe("postComments", () => { apiKey, }), ).resolves.toStrictEqual([response]) - expect(mockedAxios.patch).toHaveBeenCalled() - expect(mockedAxios.patch).toHaveBeenCalledTimes(1) - expect(mockedAxios.patch).toHaveBeenCalledWith(endpoint, params) + expect(fetchSpy).toHaveBeenCalledTimes(1) + expect(fetchSpy).toHaveBeenCalledWith( + endpoint, + getFetchOptions( + `${baseCommit.author.name}さんが[${baseParsedRef.name}](${baseParsedRef.url})にプッシュしました` + + "\n" + + "\n" + + `+ ${baseCommit.comment} ` + + `([${baseCommit.id.slice(0, 7)}](${baseCommit.url}))`, + { statusId: fixStatusId }, + ), + ) }) test("parseCommits post a comment and change status when change to close", () => { @@ -167,16 +171,6 @@ describe("postComments", () => { ], } const parsedRef: ParsedRef = baseParsedRef - const body = { - comment: - `${baseCommit.author.name}さんが[${baseParsedRef.name}](${baseParsedRef.url})にプッシュしました` + - "\n" + - "\n" + - `+ ${baseCommit.comment} ` + - `([${baseCommit.id.slice(0, 7)}](${baseCommit.url}))`, - statusId: closeStatusId, - } - const params = new url.URLSearchParams(body).toString() const response: Response = { commits: parsedCommits[issueKey], issueKey: issueKey, @@ -195,9 +189,18 @@ describe("postComments", () => { apiKey, }), ).resolves.toStrictEqual([response]) - expect(mockedAxios.patch).toHaveBeenCalled() - expect(mockedAxios.patch).toHaveBeenCalledTimes(1) - expect(mockedAxios.patch).toHaveBeenCalledWith(endpoint, params) + expect(fetchSpy).toHaveBeenCalledTimes(1) + expect(fetchSpy).toHaveBeenCalledWith( + endpoint, + getFetchOptions( + `${baseCommit.author.name}さんが[${baseParsedRef.name}](${baseParsedRef.url})にプッシュしました` + + "\n" + + "\n" + + `+ ${baseCommit.comment} ` + + `([${baseCommit.id.slice(0, 7)}](${baseCommit.url}))`, + { statusId: closeStatusId }, + ), + ) }) test("parseCommits post 2 comments to Backlog API when 2 issueKeys", () => { @@ -247,7 +250,6 @@ describe("postComments", () => { apiKey, }), ).resolves.toStrictEqual([response1, response2]) - expect(mockedAxios.patch).toHaveBeenCalled() - expect(mockedAxios.patch).toHaveBeenCalledTimes(2) + expect(fetchSpy).toHaveBeenCalledTimes(2) }) }) From c943d265d20fb53f4b23f2e7ab3191c4df0847ef Mon Sep 17 00:00:00 2001 From: Takanori Oishi Date: Sat, 4 Nov 2023 15:19:04 +0900 Subject: [PATCH 06/14] fix: Replace axios to Fetch API #82 --- dist/index.js | 13476 +++++++++--------------------------- dist/index.js.LICENSE.txt | 280 - 2 files changed, 3116 insertions(+), 10640 deletions(-) diff --git a/dist/index.js b/dist/index.js index e2b2da2..fdcc8d0 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1777,11157 +1777,3913 @@ function isLoopbackAddress(host) { /***/ }), -/***/ 4812: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -module.exports = -{ - parallel : __nccwpck_require__(8210), - serial : __nccwpck_require__(445), - serialOrdered : __nccwpck_require__(3578) -}; - - -/***/ }), - -/***/ 1700: +/***/ 6008: /***/ ((module) => { -// API -module.exports = abort; - /** - * Aborts leftover active jobs - * - * @param {object} state - current state object + * lodash 3.0.0 (Custom Build) + * Build: `lodash modern modularize exports="npm" -o ./` + * Copyright 2012-2015 The Dojo Foundation + * Based on Underscore.js 1.7.0 + * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license */ -function abort(state) -{ - Object.keys(state.jobs).forEach(clean.bind(state)); - // reset leftover jobs - state.jobs = {}; -} +/** Used to match template delimiters. */ +var reInterpolate = /<%=([\s\S]+?)%>/g; -/** - * Cleans up leftover job by invoking abort function for the provided job id - * - * @this state - * @param {string|number} key - job id to abort - */ -function clean(key) -{ - if (typeof this.jobs[key] == 'function') - { - this.jobs[key](); - } -} +module.exports = reInterpolate; /***/ }), -/***/ 2794: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var defer = __nccwpck_require__(5295); - -// API -module.exports = async; +/***/ 417: +/***/ ((module, exports, __nccwpck_require__) => { +/* module decorator */ module = __nccwpck_require__.nmd(module); /** - * Runs provided callback asynchronously - * even if callback itself is not - * - * @param {function} callback - callback to invoke - * @returns {function} - augmented callback + * Lodash (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright OpenJS Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors */ -function async(callback) -{ - var isAsync = false; - - // check if async happened - defer(function() { isAsync = true; }); - - return function async_callback(err, result) - { - if (isAsync) - { - callback(err, result); - } - else - { - defer(function nextTick_callback() - { - callback(err, result); - }); - } - }; -} +var reInterpolate = __nccwpck_require__(6008), + templateSettings = __nccwpck_require__(5477); +/** Used to detect hot functions by number of calls within a span of milliseconds. */ +var HOT_COUNT = 800, + HOT_SPAN = 16; -/***/ }), +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0, + MAX_SAFE_INTEGER = 9007199254740991; -/***/ 5295: -/***/ ((module) => { +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + asyncTag = '[object AsyncFunction]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + domExcTag = '[object DOMException]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + mapTag = '[object Map]', + numberTag = '[object Number]', + nullTag = '[object Null]', + objectTag = '[object Object]', + proxyTag = '[object Proxy]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]', + undefinedTag = '[object Undefined]', + weakMapTag = '[object WeakMap]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; -module.exports = defer; +/** Used to match empty string literals in compiled template source. */ +var reEmptyStringLeading = /\b__p \+= '';/g, + reEmptyStringMiddle = /\b(__p \+=) '' \+/g, + reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; /** - * Runs provided function on next iteration of the event loop - * - * @param {function} fn - function to run + * Used to match `RegExp` + * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). */ -function defer(fn) -{ - var nextTick = typeof setImmediate == 'function' - ? setImmediate - : ( - typeof process == 'object' && typeof process.nextTick == 'function' - ? process.nextTick - : null - ); - - if (nextTick) - { - nextTick(fn); - } - else - { - setTimeout(fn, 0); - } -} - - -/***/ }), - -/***/ 9023: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var async = __nccwpck_require__(2794) - , abort = __nccwpck_require__(1700) - ; - -// API -module.exports = iterate; +var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; /** - * Iterates over each job object - * - * @param {array|object} list - array or object (named list) to iterate over - * @param {function} iterator - iterator to run - * @param {object} state - current job status - * @param {function} callback - invoked when all elements processed + * Used to match + * [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components). */ -function iterate(list, iterator, state, callback) -{ - // store current index - var key = state['keyedList'] ? state['keyedList'][state.index] : state.index; - - state.jobs[key] = runJob(iterator, key, list[key], function(error, output) - { - // don't repeat yourself - // skip secondary callbacks - if (!(key in state.jobs)) - { - return; - } +var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; - // clean up jobs - delete state.jobs[key]; +/** Used to detect host constructors (Safari). */ +var reIsHostCtor = /^\[object .+?Constructor\]$/; - if (error) - { - // don't process rest of the results - // stop still active jobs - // and reset the list - abort(state); - } - else - { - state.results[key] = output; - } +/** Used to detect unsigned integer values. */ +var reIsUint = /^(?:0|[1-9]\d*)$/; - // return salvaged results - callback(error, state.results); - }); -} +/** Used to ensure capturing order of template delimiters. */ +var reNoMatch = /($^)/; -/** - * Runs iterator over provided job element - * - * @param {function} iterator - iterator to invoke - * @param {string|number} key - key/index of the element in the list of jobs - * @param {mixed} item - job description - * @param {function} callback - invoked after iterator is done with the job - * @returns {function|mixed} - job abort function or something else - */ -function runJob(iterator, key, item, callback) -{ - var aborter; - - // allow shortcut if iterator expects only two arguments - if (iterator.length == 2) - { - aborter = iterator(item, async(callback)); - } - // otherwise go with full three arguments - else - { - aborter = iterator(item, key, async(callback)); - } +/** Used to match unescaped characters in compiled string literals. */ +var reUnescapedString = /['\n\r\u2028\u2029\\]/g; - return aborter; -} +/** Used to identify `toStringTag` values of typed arrays. */ +var typedArrayTags = {}; +typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = +typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = +typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = +typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = +typedArrayTags[uint32Tag] = true; +typedArrayTags[argsTag] = typedArrayTags[arrayTag] = +typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = +typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = +typedArrayTags[errorTag] = typedArrayTags[funcTag] = +typedArrayTags[mapTag] = typedArrayTags[numberTag] = +typedArrayTags[objectTag] = typedArrayTags[regexpTag] = +typedArrayTags[setTag] = typedArrayTags[stringTag] = +typedArrayTags[weakMapTag] = false; +/** Used to escape characters for inclusion in compiled string literals. */ +var stringEscapes = { + '\\': '\\', + "'": "'", + '\n': 'n', + '\r': 'r', + '\u2028': 'u2028', + '\u2029': 'u2029' +}; -/***/ }), +/** Detect free variable `global` from Node.js. */ +var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; -/***/ 2474: -/***/ ((module) => { +/** Detect free variable `self`. */ +var freeSelf = typeof self == 'object' && self && self.Object === Object && self; -// API -module.exports = state; +/** Used as a reference to the global object. */ +var root = freeGlobal || freeSelf || Function('return this')(); -/** - * Creates initial state object - * for iteration over list - * - * @param {array|object} list - list to iterate over - * @param {function|null} sortMethod - function to use for keys sort, - * or `null` to keep them as is - * @returns {object} - initial state object - */ -function state(list, sortMethod) -{ - var isNamedList = !Array.isArray(list) - , initState = - { - index : 0, - keyedList: isNamedList || sortMethod ? Object.keys(list) : null, - jobs : {}, - results : isNamedList ? {} : [], - size : isNamedList ? Object.keys(list).length : list.length - } - ; - - if (sortMethod) - { - // sort array keys based on it's values - // sort object's keys just on own merit - initState.keyedList.sort(isNamedList ? sortMethod : function(a, b) - { - return sortMethod(list[a], list[b]); - }); - } +/** Detect free variable `exports`. */ +var freeExports = true && exports && !exports.nodeType && exports; - return initState; -} +/** Detect free variable `module`. */ +var freeModule = freeExports && "object" == 'object' && module && !module.nodeType && module; +/** Detect the popular CommonJS extension `module.exports`. */ +var moduleExports = freeModule && freeModule.exports === freeExports; -/***/ }), +/** Detect free variable `process` from Node.js. */ +var freeProcess = moduleExports && freeGlobal.process; -/***/ 7942: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/** Used to access faster Node.js helpers. */ +var nodeUtil = (function() { + try { + // Use `util.types` for Node.js 10+. + var types = freeModule && freeModule.require && freeModule.require('util').types; + + if (types) { + return types; + } -var abort = __nccwpck_require__(1700) - , async = __nccwpck_require__(2794) - ; + // Legacy `process.binding('util')` for Node.js < 10. + return freeProcess && freeProcess.binding && freeProcess.binding('util'); + } catch (e) {} +}()); -// API -module.exports = terminator; +/* Node.js helper references. */ +var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray; /** - * Terminates jobs in the attached state context + * A faster alternative to `Function#apply`, this function invokes `func` + * with the `this` binding of `thisArg` and the arguments of `args`. * - * @this AsyncKitState# - * @param {function} callback - final callback to invoke after termination + * @private + * @param {Function} func The function to invoke. + * @param {*} thisArg The `this` binding of `func`. + * @param {Array} args The arguments to invoke `func` with. + * @returns {*} Returns the result of `func`. */ -function terminator(callback) -{ - if (!Object.keys(this.jobs).length) - { - return; +function apply(func, thisArg, args) { + switch (args.length) { + case 0: return func.call(thisArg); + case 1: return func.call(thisArg, args[0]); + case 2: return func.call(thisArg, args[0], args[1]); + case 3: return func.call(thisArg, args[0], args[1], args[2]); } - - // fast forward iteration index - this.index = this.size; - - // abort jobs - abort(this); - - // send back results we have so far - async(callback)(null, this.results); + return func.apply(thisArg, args); } - -/***/ }), - -/***/ 8210: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var iterate = __nccwpck_require__(9023) - , initState = __nccwpck_require__(2474) - , terminator = __nccwpck_require__(7942) - ; - -// Public API -module.exports = parallel; - /** - * Runs iterator over provided array elements in parallel + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. * - * @param {array|object} list - array or object (named list) to iterate over - * @param {function} iterator - iterator to run - * @param {function} callback - invoked when all elements processed - * @returns {function} - jobs terminator + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. */ -function parallel(list, iterator, callback) -{ - var state = initState(list); - - while (state.index < (state['keyedList'] || list).length) - { - iterate(list, iterator, state, function(error, result) - { - if (error) - { - callback(error, result); - return; - } - - // looks like it's the last one - if (Object.keys(state.jobs).length === 0) - { - callback(null, state.results); - return; - } - }); +function arrayMap(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length, + result = Array(length); - state.index++; + while (++index < length) { + result[index] = iteratee(array[index], index, array); } - - return terminator.bind(state, callback); + return result; } - -/***/ }), - -/***/ 445: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var serialOrdered = __nccwpck_require__(3578); - -// Public API -module.exports = serial; - /** - * Runs iterator over provided array elements in series + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. * - * @param {array|object} list - array or object (named list) to iterate over - * @param {function} iterator - iterator to run - * @param {function} callback - invoked when all elements processed - * @returns {function} - jobs terminator + * @private + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. */ -function serial(list, iterator, callback) -{ - return serialOrdered(list, iterator, null, callback); -} +function baseTimes(n, iteratee) { + var index = -1, + result = Array(n); - -/***/ }), - -/***/ 3578: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var iterate = __nccwpck_require__(9023) - , initState = __nccwpck_require__(2474) - , terminator = __nccwpck_require__(7942) - ; - -// Public API -module.exports = serialOrdered; -// sorting helpers -module.exports.ascending = ascending; -module.exports.descending = descending; + while (++index < n) { + result[index] = iteratee(index); + } + return result; +} /** - * Runs iterator over provided sorted array elements in series + * The base implementation of `_.unary` without support for storing metadata. * - * @param {array|object} list - array or object (named list) to iterate over - * @param {function} iterator - iterator to run - * @param {function} sortMethod - custom sort function - * @param {function} callback - invoked when all elements processed - * @returns {function} - jobs terminator + * @private + * @param {Function} func The function to cap arguments for. + * @returns {Function} Returns the new capped function. */ -function serialOrdered(list, iterator, sortMethod, callback) -{ - var state = initState(list, sortMethod); - - iterate(list, iterator, state, function iteratorHandler(error, result) - { - if (error) - { - callback(error, result); - return; - } - - state.index++; - - // are we there yet? - if (state.index < (state['keyedList'] || list).length) - { - iterate(list, iterator, state, iteratorHandler); - return; - } - - // done here - callback(null, state.results); - }); - - return terminator.bind(state, callback); +function baseUnary(func) { + return function(value) { + return func(value); + }; } -/* - * -- Sort methods +/** + * The base implementation of `_.values` and `_.valuesIn` which creates an + * array of `object` property values corresponding to the property names + * of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the array of property values. */ +function baseValues(object, props) { + return arrayMap(props, function(key) { + return object[key]; + }); +} /** - * sort helper to sort array elements in ascending order + * Used by `_.template` to escape characters for inclusion in compiled string literals. * - * @param {mixed} a - an item to compare - * @param {mixed} b - an item to compare - * @returns {number} - comparison result + * @private + * @param {string} chr The matched character to escape. + * @returns {string} Returns the escaped character. */ -function ascending(a, b) -{ - return a < b ? -1 : a > b ? 1 : 0; +function escapeStringChar(chr) { + return '\\' + stringEscapes[chr]; } /** - * sort helper to sort array elements in descending order + * Gets the value at `key` of `object`. * - * @param {mixed} a - an item to compare - * @param {mixed} b - an item to compare - * @returns {number} - comparison result + * @private + * @param {Object} [object] The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. */ -function descending(a, b) -{ - return -1 * ascending(a, b); +function getValue(object, key) { + return object == null ? undefined : object[key]; } - -/***/ }), - -/***/ 5443: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var util = __nccwpck_require__(3837); -var Stream = (__nccwpck_require__(2781).Stream); -var DelayedStream = __nccwpck_require__(8611); - -module.exports = CombinedStream; -function CombinedStream() { - this.writable = false; - this.readable = true; - this.dataSize = 0; - this.maxDataSize = 2 * 1024 * 1024; - this.pauseStreams = true; - - this._released = false; - this._streams = []; - this._currentStream = null; - this._insideLoop = false; - this._pendingNext = false; +/** + * Creates a unary function that invokes `func` with its argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ +function overArg(func, transform) { + return function(arg) { + return func(transform(arg)); + }; } -util.inherits(CombinedStream, Stream); - -CombinedStream.create = function(options) { - var combinedStream = new this(); - - options = options || {}; - for (var option in options) { - combinedStream[option] = options[option]; - } - - return combinedStream; -}; -CombinedStream.isStreamLike = function(stream) { - return (typeof stream !== 'function') - && (typeof stream !== 'string') - && (typeof stream !== 'boolean') - && (typeof stream !== 'number') - && (!Buffer.isBuffer(stream)); -}; +/** Used for built-in method references. */ +var funcProto = Function.prototype, + objectProto = Object.prototype; -CombinedStream.prototype.append = function(stream) { - var isStreamLike = CombinedStream.isStreamLike(stream); +/** Used to detect overreaching core-js shims. */ +var coreJsData = root['__core-js_shared__']; - if (isStreamLike) { - if (!(stream instanceof DelayedStream)) { - var newStream = DelayedStream.create(stream, { - maxDataSize: Infinity, - pauseStream: this.pauseStreams, - }); - stream.on('data', this._checkDataSize.bind(this)); - stream = newStream; - } +/** Used to resolve the decompiled source of functions. */ +var funcToString = funcProto.toString; - this._handleErrors(stream); +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; - if (this.pauseStreams) { - stream.pause(); - } - } +/** Used to detect methods masquerading as native. */ +var maskSrcKey = (function() { + var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); + return uid ? ('Symbol(src)_1.' + uid) : ''; +}()); - this._streams.push(stream); - return this; -}; +/** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ +var nativeObjectToString = objectProto.toString; -CombinedStream.prototype.pipe = function(dest, options) { - Stream.prototype.pipe.call(this, dest, options); - this.resume(); - return dest; -}; +/** Used to infer the `Object` constructor. */ +var objectCtorString = funcToString.call(Object); -CombinedStream.prototype._getNext = function() { - this._currentStream = null; +/** Used to detect if a method is native. */ +var reIsNative = RegExp('^' + + funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' +); - if (this._insideLoop) { - this._pendingNext = true; - return; // defer call - } +/** Built-in value references. */ +var Buffer = moduleExports ? root.Buffer : undefined, + Symbol = root.Symbol, + getPrototype = overArg(Object.getPrototypeOf, Object), + propertyIsEnumerable = objectProto.propertyIsEnumerable, + symToStringTag = Symbol ? Symbol.toStringTag : undefined; - this._insideLoop = true; +var defineProperty = (function() { try { - do { - this._pendingNext = false; - this._realGetNext(); - } while (this._pendingNext); - } finally { - this._insideLoop = false; - } -}; - -CombinedStream.prototype._realGetNext = function() { - var stream = this._streams.shift(); - - - if (typeof stream == 'undefined') { - this.end(); - return; - } - - if (typeof stream !== 'function') { - this._pipeNext(stream); - return; - } - - var getStream = stream; - getStream(function(stream) { - var isStreamLike = CombinedStream.isStreamLike(stream); - if (isStreamLike) { - stream.on('data', this._checkDataSize.bind(this)); - this._handleErrors(stream); - } - - this._pipeNext(stream); - }.bind(this)); -}; - -CombinedStream.prototype._pipeNext = function(stream) { - this._currentStream = stream; - - var isStreamLike = CombinedStream.isStreamLike(stream); - if (isStreamLike) { - stream.on('end', this._getNext.bind(this)); - stream.pipe(this, {end: false}); - return; - } - - var value = stream; - this.write(value); - this._getNext(); -}; - -CombinedStream.prototype._handleErrors = function(stream) { - var self = this; - stream.on('error', function(err) { - self._emitError(err); - }); -}; - -CombinedStream.prototype.write = function(data) { - this.emit('data', data); -}; - -CombinedStream.prototype.pause = function() { - if (!this.pauseStreams) { - return; - } - - if(this.pauseStreams && this._currentStream && typeof(this._currentStream.pause) == 'function') this._currentStream.pause(); - this.emit('pause'); -}; - -CombinedStream.prototype.resume = function() { - if (!this._released) { - this._released = true; - this.writable = true; - this._getNext(); - } - - if(this.pauseStreams && this._currentStream && typeof(this._currentStream.resume) == 'function') this._currentStream.resume(); - this.emit('resume'); -}; - -CombinedStream.prototype.end = function() { - this._reset(); - this.emit('end'); -}; - -CombinedStream.prototype.destroy = function() { - this._reset(); - this.emit('close'); -}; - -CombinedStream.prototype._reset = function() { - this.writable = false; - this._streams = []; - this._currentStream = null; -}; - -CombinedStream.prototype._checkDataSize = function() { - this._updateDataSize(); - if (this.dataSize <= this.maxDataSize) { - return; - } - - var message = - 'DelayedStream#maxDataSize of ' + this.maxDataSize + ' bytes exceeded.'; - this._emitError(new Error(message)); -}; - -CombinedStream.prototype._updateDataSize = function() { - this.dataSize = 0; - - var self = this; - this._streams.forEach(function(stream) { - if (!stream.dataSize) { - return; - } - - self.dataSize += stream.dataSize; - }); - - if (this._currentStream && this._currentStream.dataSize) { - this.dataSize += this._currentStream.dataSize; - } -}; - -CombinedStream.prototype._emitError = function(err) { - this._reset(); - this.emit('error', err); -}; - - -/***/ }), - -/***/ 8222: -/***/ ((module, exports, __nccwpck_require__) => { - -/* eslint-env browser */ - -/** - * This is the web browser implementation of `debug()`. - */ - -exports.formatArgs = formatArgs; -exports.save = save; -exports.load = load; -exports.useColors = useColors; -exports.storage = localstorage(); -exports.destroy = (() => { - let warned = false; - - return () => { - if (!warned) { - warned = true; - console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.'); - } - }; -})(); + var func = getNative(Object, 'defineProperty'); + func({}, '', {}); + return func; + } catch (e) {} +}()); -/** - * Colors. - */ +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined, + nativeKeys = overArg(Object.keys, Object), + nativeMax = Math.max, + nativeNow = Date.now; -exports.colors = [ - '#0000CC', - '#0000FF', - '#0033CC', - '#0033FF', - '#0066CC', - '#0066FF', - '#0099CC', - '#0099FF', - '#00CC00', - '#00CC33', - '#00CC66', - '#00CC99', - '#00CCCC', - '#00CCFF', - '#3300CC', - '#3300FF', - '#3333CC', - '#3333FF', - '#3366CC', - '#3366FF', - '#3399CC', - '#3399FF', - '#33CC00', - '#33CC33', - '#33CC66', - '#33CC99', - '#33CCCC', - '#33CCFF', - '#6600CC', - '#6600FF', - '#6633CC', - '#6633FF', - '#66CC00', - '#66CC33', - '#9900CC', - '#9900FF', - '#9933CC', - '#9933FF', - '#99CC00', - '#99CC33', - '#CC0000', - '#CC0033', - '#CC0066', - '#CC0099', - '#CC00CC', - '#CC00FF', - '#CC3300', - '#CC3333', - '#CC3366', - '#CC3399', - '#CC33CC', - '#CC33FF', - '#CC6600', - '#CC6633', - '#CC9900', - '#CC9933', - '#CCCC00', - '#CCCC33', - '#FF0000', - '#FF0033', - '#FF0066', - '#FF0099', - '#FF00CC', - '#FF00FF', - '#FF3300', - '#FF3333', - '#FF3366', - '#FF3399', - '#FF33CC', - '#FF33FF', - '#FF6600', - '#FF6633', - '#FF9900', - '#FF9933', - '#FFCC00', - '#FFCC33' -]; +/** Used to convert symbols to primitives and strings. */ +var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolToString = symbolProto ? symbolProto.toString : undefined; /** - * Currently only WebKit-based Web Inspectors, Firefox >= v31, - * and the Firebug extension (any Firefox version) are known - * to support "%c" CSS customizations. + * Creates an array of the enumerable property names of the array-like `value`. * - * TODO: add a `localStorage` variable to explicitly enable/disable colors + * @private + * @param {*} value The value to query. + * @param {boolean} inherited Specify returning inherited property names. + * @returns {Array} Returns the array of property names. */ +function arrayLikeKeys(value, inherited) { + var isArr = isArray(value), + isArg = !isArr && isArguments(value), + isBuff = !isArr && !isArg && isBuffer(value), + isType = !isArr && !isArg && !isBuff && isTypedArray(value), + skipIndexes = isArr || isArg || isBuff || isType, + result = skipIndexes ? baseTimes(value.length, String) : [], + length = result.length; -// eslint-disable-next-line complexity -function useColors() { - // NB: In an Electron preload script, document will be defined but not fully - // initialized. Since we know we're in Chrome, we'll just detect this case - // explicitly - if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) { - return true; - } - - // Internet Explorer and Edge do not support colors. - if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) { - return false; - } - - // Is webkit? http://stackoverflow.com/a/16459606/376773 - // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632 - return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) || - // Is firebug? http://stackoverflow.com/a/398120/376773 - (typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) || - // Is firefox >= v31? - // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages - (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) || - // Double check webkit in userAgent just in case we are in a worker - (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)); + for (var key in value) { + if ((inherited || hasOwnProperty.call(value, key)) && + !(skipIndexes && ( + // Safari 9 has enumerable `arguments.length` in strict mode. + key == 'length' || + // Node.js 0.10 has enumerable non-index properties on buffers. + (isBuff && (key == 'offset' || key == 'parent')) || + // PhantomJS 2 has enumerable non-index properties on typed arrays. + (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) || + // Skip index properties. + isIndex(key, length) + ))) { + result.push(key); + } + } + return result; } /** - * Colorize log arguments if enabled. + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. * - * @api public + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. */ - -function formatArgs(args) { - args[0] = (this.useColors ? '%c' : '') + - this.namespace + - (this.useColors ? ' %c' : ' ') + - args[0] + - (this.useColors ? '%c ' : ' ') + - '+' + module.exports.humanize(this.diff); - - if (!this.useColors) { - return; - } - - const c = 'color: ' + this.color; - args.splice(1, 0, c, 'color: inherit'); - - // The final "%c" is somewhat tricky, because there could be other - // arguments passed either before or after the %c, so we need to - // figure out the correct index to insert the CSS into - let index = 0; - let lastC = 0; - args[0].replace(/%[a-zA-Z%]/g, match => { - if (match === '%%') { - return; - } - index++; - if (match === '%c') { - // We only are interested in the *last* %c - // (the user may have provided their own) - lastC = index; - } - }); - - args.splice(lastC, 0, c); +function assignValue(object, key, value) { + var objValue = object[key]; + if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || + (value === undefined && !(key in object))) { + baseAssignValue(object, key, value); + } } /** - * Invokes `console.debug()` when available. - * No-op when `console.debug` is not a "function". - * If `console.debug` is not available, falls back - * to `console.log`. - * - * @api public - */ -exports.log = console.debug || console.log || (() => {}); - -/** - * Save `namespaces`. + * The base implementation of `assignValue` and `assignMergeValue` without + * value checks. * - * @param {String} namespaces - * @api private + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. */ -function save(namespaces) { - try { - if (namespaces) { - exports.storage.setItem('debug', namespaces); - } else { - exports.storage.removeItem('debug'); - } - } catch (error) { - // Swallow - // XXX (@Qix-) should we be logging these? - } -} - -/** - * Load `namespaces`. - * - * @return {String} returns the previously persisted debug modes - * @api private - */ -function load() { - let r; - try { - r = exports.storage.getItem('debug'); - } catch (error) { - // Swallow - // XXX (@Qix-) should we be logging these? - } - - // If debug isn't set in LS, and we're in Electron, try to load $DEBUG - if (!r && typeof process !== 'undefined' && 'env' in process) { - r = process.env.DEBUG; - } - - return r; +function baseAssignValue(object, key, value) { + if (key == '__proto__' && defineProperty) { + defineProperty(object, key, { + 'configurable': true, + 'enumerable': true, + 'value': value, + 'writable': true + }); + } else { + object[key] = value; + } } /** - * Localstorage attempts to return the localstorage. - * - * This is necessary because safari throws - * when a user disables cookies/localstorage - * and you attempt to access it. + * The base implementation of `getTag` without fallbacks for buggy environments. * - * @return {LocalStorage} - * @api private + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. */ - -function localstorage() { - try { - // TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context - // The Browser also has localStorage in the global context. - return localStorage; - } catch (error) { - // Swallow - // XXX (@Qix-) should we be logging these? - } +function baseGetTag(value) { + if (value == null) { + return value === undefined ? undefinedTag : nullTag; + } + return (symToStringTag && symToStringTag in Object(value)) + ? getRawTag(value) + : objectToString(value); } -module.exports = __nccwpck_require__(6243)(exports); - -const {formatters} = module.exports; - /** - * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. + * The base implementation of `_.isArguments`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, */ - -formatters.j = function (v) { - try { - return JSON.stringify(v); - } catch (error) { - return '[UnexpectedJSONParseError]: ' + error.message; - } -}; - - -/***/ }), - -/***/ 6243: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - +function baseIsArguments(value) { + return isObjectLike(value) && baseGetTag(value) == argsTag; +} /** - * This is the common logic for both the Node.js and web browser - * implementations of `debug()`. + * The base implementation of `_.isNative` without bad shim checks. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. */ - -function setup(env) { - createDebug.debug = createDebug; - createDebug.default = createDebug; - createDebug.coerce = coerce; - createDebug.disable = disable; - createDebug.enable = enable; - createDebug.enabled = enabled; - createDebug.humanize = __nccwpck_require__(900); - createDebug.destroy = destroy; - - Object.keys(env).forEach(key => { - createDebug[key] = env[key]; - }); - - /** - * The currently active debug mode names, and names to skip. - */ - - createDebug.names = []; - createDebug.skips = []; - - /** - * Map of special "%n" handling functions, for the debug "format" argument. - * - * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N". - */ - createDebug.formatters = {}; - - /** - * Selects a color for a debug namespace - * @param {String} namespace The namespace string for the debug instance to be colored - * @return {Number|String} An ANSI color code for the given namespace - * @api private - */ - function selectColor(namespace) { - let hash = 0; - - for (let i = 0; i < namespace.length; i++) { - hash = ((hash << 5) - hash) + namespace.charCodeAt(i); - hash |= 0; // Convert to 32bit integer - } - - return createDebug.colors[Math.abs(hash) % createDebug.colors.length]; - } - createDebug.selectColor = selectColor; - - /** - * Create a debugger with the given `namespace`. - * - * @param {String} namespace - * @return {Function} - * @api public - */ - function createDebug(namespace) { - let prevTime; - let enableOverride = null; - let namespacesCache; - let enabledCache; - - function debug(...args) { - // Disabled? - if (!debug.enabled) { - return; - } - - const self = debug; - - // Set `diff` timestamp - const curr = Number(new Date()); - const ms = curr - (prevTime || curr); - self.diff = ms; - self.prev = prevTime; - self.curr = curr; - prevTime = curr; - - args[0] = createDebug.coerce(args[0]); - - if (typeof args[0] !== 'string') { - // Anything else let's inspect with %O - args.unshift('%O'); - } - - // Apply any `formatters` transformations - let index = 0; - args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => { - // If we encounter an escaped % then don't increase the array index - if (match === '%%') { - return '%'; - } - index++; - const formatter = createDebug.formatters[format]; - if (typeof formatter === 'function') { - const val = args[index]; - match = formatter.call(self, val); - - // Now we need to remove `args[index]` since it's inlined in the `format` - args.splice(index, 1); - index--; - } - return match; - }); - - // Apply env-specific formatting (colors, etc.) - createDebug.formatArgs.call(self, args); - - const logFn = self.log || createDebug.log; - logFn.apply(self, args); - } - - debug.namespace = namespace; - debug.useColors = createDebug.useColors(); - debug.color = createDebug.selectColor(namespace); - debug.extend = extend; - debug.destroy = createDebug.destroy; // XXX Temporary. Will be removed in the next major release. - - Object.defineProperty(debug, 'enabled', { - enumerable: true, - configurable: false, - get: () => { - if (enableOverride !== null) { - return enableOverride; - } - if (namespacesCache !== createDebug.namespaces) { - namespacesCache = createDebug.namespaces; - enabledCache = createDebug.enabled(namespace); - } - - return enabledCache; - }, - set: v => { - enableOverride = v; - } - }); - - // Env-specific initialization logic for debug instances - if (typeof createDebug.init === 'function') { - createDebug.init(debug); - } - - return debug; - } - - function extend(namespace, delimiter) { - const newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace); - newDebug.log = this.log; - return newDebug; - } - - /** - * Enables a debug mode by namespaces. This can include modes - * separated by a colon and wildcards. - * - * @param {String} namespaces - * @api public - */ - function enable(namespaces) { - createDebug.save(namespaces); - createDebug.namespaces = namespaces; - - createDebug.names = []; - createDebug.skips = []; - - let i; - const split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/); - const len = split.length; - - for (i = 0; i < len; i++) { - if (!split[i]) { - // ignore empty strings - continue; - } - - namespaces = split[i].replace(/\*/g, '.*?'); - - if (namespaces[0] === '-') { - createDebug.skips.push(new RegExp('^' + namespaces.slice(1) + '$')); - } else { - createDebug.names.push(new RegExp('^' + namespaces + '$')); - } - } - } - - /** - * Disable debug output. - * - * @return {String} namespaces - * @api public - */ - function disable() { - const namespaces = [ - ...createDebug.names.map(toNamespace), - ...createDebug.skips.map(toNamespace).map(namespace => '-' + namespace) - ].join(','); - createDebug.enable(''); - return namespaces; - } - - /** - * Returns true if the given mode name is enabled, false otherwise. - * - * @param {String} name - * @return {Boolean} - * @api public - */ - function enabled(name) { - if (name[name.length - 1] === '*') { - return true; - } - - let i; - let len; - - for (i = 0, len = createDebug.skips.length; i < len; i++) { - if (createDebug.skips[i].test(name)) { - return false; - } - } - - for (i = 0, len = createDebug.names.length; i < len; i++) { - if (createDebug.names[i].test(name)) { - return true; - } - } - - return false; - } - - /** - * Convert regexp to namespace - * - * @param {RegExp} regxep - * @return {String} namespace - * @api private - */ - function toNamespace(regexp) { - return regexp.toString() - .substring(2, regexp.toString().length - 2) - .replace(/\.\*\?$/, '*'); - } - - /** - * Coerce `val`. - * - * @param {Mixed} val - * @return {Mixed} - * @api private - */ - function coerce(val) { - if (val instanceof Error) { - return val.stack || val.message; - } - return val; - } - - /** - * XXX DO NOT USE. This is a temporary stub function. - * XXX It WILL be removed in the next major release. - */ - function destroy() { - console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.'); - } - - createDebug.enable(createDebug.load()); - - return createDebug; -} - -module.exports = setup; - - -/***/ }), - -/***/ 8237: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +function baseIsNative(value) { + if (!isObject(value) || isMasked(value)) { + return false; + } + var pattern = isFunction(value) ? reIsNative : reIsHostCtor; + return pattern.test(toSource(value)); +} /** - * Detect Electron renderer / nwjs process, which is node, but we should - * treat as a browser. + * The base implementation of `_.isTypedArray` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. */ - -if (typeof process === 'undefined' || process.type === 'renderer' || process.browser === true || process.__nwjs) { - module.exports = __nccwpck_require__(8222); -} else { - module.exports = __nccwpck_require__(4874); +function baseIsTypedArray(value) { + return isObjectLike(value) && + isLength(value.length) && !!typedArrayTags[baseGetTag(value)]; } - -/***/ }), - -/***/ 4874: -/***/ ((module, exports, __nccwpck_require__) => { - /** - * Module dependencies. + * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. */ - -const tty = __nccwpck_require__(6224); -const util = __nccwpck_require__(3837); +function baseKeys(object) { + if (!isPrototype(object)) { + return nativeKeys(object); + } + var result = []; + for (var key in Object(object)) { + if (hasOwnProperty.call(object, key) && key != 'constructor') { + result.push(key); + } + } + return result; +} /** - * This is the Node.js implementation of `debug()`. + * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. */ +function baseKeysIn(object) { + if (!isObject(object)) { + return nativeKeysIn(object); + } + var isProto = isPrototype(object), + result = []; -exports.init = init; -exports.log = log; -exports.formatArgs = formatArgs; -exports.save = save; -exports.load = load; -exports.useColors = useColors; -exports.destroy = util.deprecate( - () => {}, - 'Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.' -); + for (var key in object) { + if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { + result.push(key); + } + } + return result; +} /** - * Colors. + * The base implementation of `_.rest` which doesn't validate or coerce arguments. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @returns {Function} Returns the new function. */ - -exports.colors = [6, 2, 3, 4, 5, 1]; - -try { - // Optional dependency (as in, doesn't need to be installed, NOT like optionalDependencies in package.json) - // eslint-disable-next-line import/no-extraneous-dependencies - const supportsColor = __nccwpck_require__(9318); - - if (supportsColor && (supportsColor.stderr || supportsColor).level >= 2) { - exports.colors = [ - 20, - 21, - 26, - 27, - 32, - 33, - 38, - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 56, - 57, - 62, - 63, - 68, - 69, - 74, - 75, - 76, - 77, - 78, - 79, - 80, - 81, - 92, - 93, - 98, - 99, - 112, - 113, - 128, - 129, - 134, - 135, - 148, - 149, - 160, - 161, - 162, - 163, - 164, - 165, - 166, - 167, - 168, - 169, - 170, - 171, - 172, - 173, - 178, - 179, - 184, - 185, - 196, - 197, - 198, - 199, - 200, - 201, - 202, - 203, - 204, - 205, - 206, - 207, - 208, - 209, - 214, - 215, - 220, - 221 - ]; - } -} catch (error) { - // Swallow - we only care if `supports-color` is available; it doesn't have to be. +function baseRest(func, start) { + return setToString(overRest(func, start, identity), func + ''); } /** - * Build up the default `inspectOpts` object from the environment variables. + * The base implementation of `setToString` without support for hot loop shorting. * - * $ DEBUG_COLORS=no DEBUG_DEPTH=10 DEBUG_SHOW_HIDDEN=enabled node script.js + * @private + * @param {Function} func The function to modify. + * @param {Function} string The `toString` result. + * @returns {Function} Returns `func`. */ - -exports.inspectOpts = Object.keys(process.env).filter(key => { - return /^debug_/i.test(key); -}).reduce((obj, key) => { - // Camel-case - const prop = key - .substring(6) - .toLowerCase() - .replace(/_([a-z])/g, (_, k) => { - return k.toUpperCase(); - }); - - // Coerce string value into JS value - let val = process.env[key]; - if (/^(yes|on|true|enabled)$/i.test(val)) { - val = true; - } else if (/^(no|off|false|disabled)$/i.test(val)) { - val = false; - } else if (val === 'null') { - val = null; - } else { - val = Number(val); - } - - obj[prop] = val; - return obj; -}, {}); +var baseSetToString = !defineProperty ? identity : function(func, string) { + return defineProperty(func, 'toString', { + 'configurable': true, + 'enumerable': false, + 'value': constant(string), + 'writable': true + }); +}; /** - * Is stdout a TTY? Colored output is enabled when `true`. + * The base implementation of `_.toString` which doesn't convert nullish + * values to empty strings. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. */ - -function useColors() { - return 'colors' in exports.inspectOpts ? - Boolean(exports.inspectOpts.colors) : - tty.isatty(process.stderr.fd); +function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + if (isArray(value)) { + // Recursively convert values (susceptible to call stack limits). + return arrayMap(value, baseToString) + ''; + } + if (isSymbol(value)) { + return symbolToString ? symbolToString.call(value) : ''; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; } /** - * Adds ANSI color escape codes if enabled. + * Copies properties of `source` to `object`. * - * @api public + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property identifiers to copy. + * @param {Object} [object={}] The object to copy properties to. + * @param {Function} [customizer] The function to customize copied values. + * @returns {Object} Returns `object`. */ +function copyObject(source, props, object, customizer) { + var isNew = !object; + object || (object = {}); -function formatArgs(args) { - const {namespace: name, useColors} = this; + var index = -1, + length = props.length; - if (useColors) { - const c = this.color; - const colorCode = '\u001B[3' + (c < 8 ? c : '8;5;' + c); - const prefix = ` ${colorCode};1m${name} \u001B[0m`; + while (++index < length) { + var key = props[index]; - args[0] = prefix + args[0].split('\n').join('\n' + prefix); - args.push(colorCode + 'm+' + module.exports.humanize(this.diff) + '\u001B[0m'); - } else { - args[0] = getDate() + name + ' ' + args[0]; - } -} + var newValue = customizer + ? customizer(object[key], source[key], key, object, source) + : undefined; -function getDate() { - if (exports.inspectOpts.hideDate) { - return ''; - } - return new Date().toISOString() + ' '; + if (newValue === undefined) { + newValue = source[key]; + } + if (isNew) { + baseAssignValue(object, key, newValue); + } else { + assignValue(object, key, newValue); + } + } + return object; } /** - * Invokes `util.format()` with the specified arguments and writes to stderr. + * Creates a function like `_.assign`. + * + * @private + * @param {Function} assigner The function to assign values. + * @returns {Function} Returns the new assigner function. */ +function createAssigner(assigner) { + return baseRest(function(object, sources) { + var index = -1, + length = sources.length, + customizer = length > 1 ? sources[length - 1] : undefined, + guard = length > 2 ? sources[2] : undefined; + + customizer = (assigner.length > 3 && typeof customizer == 'function') + ? (length--, customizer) + : undefined; -function log(...args) { - return process.stderr.write(util.format(...args) + '\n'); + if (guard && isIterateeCall(sources[0], sources[1], guard)) { + customizer = length < 3 ? undefined : customizer; + length = 1; + } + object = Object(object); + while (++index < length) { + var source = sources[index]; + if (source) { + assigner(object, source, index, customizer); + } + } + return object; + }); } /** - * Save `namespaces`. + * Used by `_.defaults` to customize its `_.assignIn` use to assign properties + * of source objects to the destination object for all destination properties + * that resolve to `undefined`. * - * @param {String} namespaces - * @api private + * @private + * @param {*} objValue The destination value. + * @param {*} srcValue The source value. + * @param {string} key The key of the property to assign. + * @param {Object} object The parent object of `objValue`. + * @returns {*} Returns the value to assign. */ -function save(namespaces) { - if (namespaces) { - process.env.DEBUG = namespaces; - } else { - // If you set a process.env field to null or undefined, it gets cast to the - // string 'null' or 'undefined'. Just delete instead. - delete process.env.DEBUG; - } +function customDefaultsAssignIn(objValue, srcValue, key, object) { + if (objValue === undefined || + (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) { + return srcValue; + } + return objValue; } /** - * Load `namespaces`. + * Gets the native function at `key` of `object`. * - * @return {String} returns the previously persisted debug modes - * @api private + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. */ - -function load() { - return process.env.DEBUG; +function getNative(object, key) { + var value = getValue(object, key); + return baseIsNative(value) ? value : undefined; } /** - * Init logic for `debug` instances. + * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. * - * Create a new `inspectOpts` object in case `useColors` is set - * differently for a particular `debug` instance. + * @private + * @param {*} value The value to query. + * @returns {string} Returns the raw `toStringTag`. */ +function getRawTag(value) { + var isOwn = hasOwnProperty.call(value, symToStringTag), + tag = value[symToStringTag]; -function init(debug) { - debug.inspectOpts = {}; - - const keys = Object.keys(exports.inspectOpts); - for (let i = 0; i < keys.length; i++) { - debug.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]]; - } -} - -module.exports = __nccwpck_require__(6243)(exports); + try { + value[symToStringTag] = undefined; + var unmasked = true; + } catch (e) {} -const {formatters} = module.exports; + var result = nativeObjectToString.call(value); + if (unmasked) { + if (isOwn) { + value[symToStringTag] = tag; + } else { + delete value[symToStringTag]; + } + } + return result; +} /** - * Map %o to `util.inspect()`, all on a single line. + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. */ +function isIndex(value, length) { + var type = typeof value; + length = length == null ? MAX_SAFE_INTEGER : length; -formatters.o = function (v) { - this.inspectOpts.colors = this.useColors; - return util.inspect(v, this.inspectOpts) - .split('\n') - .map(str => str.trim()) - .join(' '); -}; + return !!length && + (type == 'number' || + (type != 'symbol' && reIsUint.test(value))) && + (value > -1 && value % 1 == 0 && value < length); +} /** - * Map %O to `util.inspect()`, allowing multiple lines if needed. + * Checks if the given arguments are from an iteratee call. + * + * @private + * @param {*} value The potential iteratee value argument. + * @param {*} index The potential iteratee index or key argument. + * @param {*} object The potential iteratee object argument. + * @returns {boolean} Returns `true` if the arguments are from an iteratee call, + * else `false`. */ - -formatters.O = function (v) { - this.inspectOpts.colors = this.useColors; - return util.inspect(v, this.inspectOpts); -}; - - -/***/ }), - -/***/ 8611: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var Stream = (__nccwpck_require__(2781).Stream); -var util = __nccwpck_require__(3837); - -module.exports = DelayedStream; -function DelayedStream() { - this.source = null; - this.dataSize = 0; - this.maxDataSize = 1024 * 1024; - this.pauseStream = true; - - this._maxDataSizeExceeded = false; - this._released = false; - this._bufferedEvents = []; -} -util.inherits(DelayedStream, Stream); - -DelayedStream.create = function(source, options) { - var delayedStream = new this(); - - options = options || {}; - for (var option in options) { - delayedStream[option] = options[option]; - } - - delayedStream.source = source; - - var realEmit = source.emit; - source.emit = function() { - delayedStream._handleEmit(arguments); - return realEmit.apply(source, arguments); - }; - - source.on('error', function() {}); - if (delayedStream.pauseStream) { - source.pause(); - } - - return delayedStream; -}; - -Object.defineProperty(DelayedStream.prototype, 'readable', { - configurable: true, - enumerable: true, - get: function() { - return this.source.readable; - } -}); - -DelayedStream.prototype.setEncoding = function() { - return this.source.setEncoding.apply(this.source, arguments); -}; - -DelayedStream.prototype.resume = function() { - if (!this._released) { - this.release(); +function isIterateeCall(value, index, object) { + if (!isObject(object)) { + return false; } - - this.source.resume(); -}; - -DelayedStream.prototype.pause = function() { - this.source.pause(); -}; - -DelayedStream.prototype.release = function() { - this._released = true; - - this._bufferedEvents.forEach(function(args) { - this.emit.apply(this, args); - }.bind(this)); - this._bufferedEvents = []; -}; - -DelayedStream.prototype.pipe = function() { - var r = Stream.prototype.pipe.apply(this, arguments); - this.resume(); - return r; -}; - -DelayedStream.prototype._handleEmit = function(args) { - if (this._released) { - this.emit.apply(this, args); - return; + var type = typeof index; + if (type == 'number' + ? (isArrayLike(object) && isIndex(index, object.length)) + : (type == 'string' && index in object) + ) { + return eq(object[index], value); } + return false; +} - if (args[0] === 'data') { - this.dataSize += args[1].length; - this._checkIfMaxDataSizeExceeded(); - } +/** + * Checks if `func` has its source masked. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` is masked, else `false`. + */ +function isMasked(func) { + return !!maskSrcKey && (maskSrcKey in func); +} - this._bufferedEvents.push(args); -}; +/** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ +function isPrototype(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; -DelayedStream.prototype._checkIfMaxDataSizeExceeded = function() { - if (this._maxDataSizeExceeded) { - return; - } + return value === proto; +} - if (this.dataSize <= this.maxDataSize) { - return; +/** + * This function is like + * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * except that it includes inherited enumerable properties. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ +function nativeKeysIn(object) { + var result = []; + if (object != null) { + for (var key in Object(object)) { + result.push(key); + } } + return result; +} - this._maxDataSizeExceeded = true; - var message = - 'DelayedStream#maxDataSize of ' + this.maxDataSize + ' bytes exceeded.' - this.emit('error', new Error(message)); -}; - - -/***/ }), - -/***/ 1133: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/** + * Converts `value` to a string using `Object.prototype.toString`. + * + * @private + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + */ +function objectToString(value) { + return nativeObjectToString.call(value); +} -var debug; +/** + * A specialized version of `baseRest` which transforms the rest array. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @param {Function} transform The rest array transform. + * @returns {Function} Returns the new function. + */ +function overRest(func, start, transform) { + start = nativeMax(start === undefined ? (func.length - 1) : start, 0); + return function() { + var args = arguments, + index = -1, + length = nativeMax(args.length - start, 0), + array = Array(length); -module.exports = function () { - if (!debug) { - try { - /* eslint global-require: off */ - debug = __nccwpck_require__(8237)("follow-redirects"); + while (++index < length) { + array[index] = args[start + index]; } - catch (error) { /* */ } - if (typeof debug !== "function") { - debug = function () { /* */ }; + index = -1; + var otherArgs = Array(start + 1); + while (++index < start) { + otherArgs[index] = args[index]; } - } - debug.apply(null, arguments); -}; - - -/***/ }), - -/***/ 7707: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var url = __nccwpck_require__(7310); -var URL = url.URL; -var http = __nccwpck_require__(3685); -var https = __nccwpck_require__(5687); -var Writable = (__nccwpck_require__(2781).Writable); -var assert = __nccwpck_require__(9491); -var debug = __nccwpck_require__(1133); - -// Create handlers that pass events from native requests -var events = ["abort", "aborted", "connect", "error", "socket", "timeout"]; -var eventHandlers = Object.create(null); -events.forEach(function (event) { - eventHandlers[event] = function (arg1, arg2, arg3) { - this._redirectable.emit(event, arg1, arg2, arg3); - }; -}); - -var InvalidUrlError = createErrorType( - "ERR_INVALID_URL", - "Invalid URL", - TypeError -); -// Error types with codes -var RedirectionError = createErrorType( - "ERR_FR_REDIRECTION_FAILURE", - "Redirected request failed" -); -var TooManyRedirectsError = createErrorType( - "ERR_FR_TOO_MANY_REDIRECTS", - "Maximum number of redirects exceeded" -); -var MaxBodyLengthExceededError = createErrorType( - "ERR_FR_MAX_BODY_LENGTH_EXCEEDED", - "Request body larger than maxBodyLength limit" -); -var WriteAfterEndError = createErrorType( - "ERR_STREAM_WRITE_AFTER_END", - "write after end" -); - -// An HTTP(S) request that can be redirected -function RedirectableRequest(options, responseCallback) { - // Initialize the request - Writable.call(this); - this._sanitizeOptions(options); - this._options = options; - this._ended = false; - this._ending = false; - this._redirectCount = 0; - this._redirects = []; - this._requestBodyLength = 0; - this._requestBodyBuffers = []; - - // Attach a callback if passed - if (responseCallback) { - this.on("response", responseCallback); - } - - // React to responses of native requests - var self = this; - this._onNativeResponse = function (response) { - self._processResponse(response); + otherArgs[start] = transform(array); + return apply(func, this, otherArgs); }; - - // Perform the first request - this._performRequest(); } -RedirectableRequest.prototype = Object.create(Writable.prototype); -RedirectableRequest.prototype.abort = function () { - abortRequest(this._currentRequest); - this.emit("abort"); -}; +/** + * Sets the `toString` method of `func` to return `string`. + * + * @private + * @param {Function} func The function to modify. + * @param {Function} string The `toString` result. + * @returns {Function} Returns `func`. + */ +var setToString = shortOut(baseSetToString); -// Writes buffered data to the current native request -RedirectableRequest.prototype.write = function (data, encoding, callback) { - // Writing is not allowed if end has been called - if (this._ending) { - throw new WriteAfterEndError(); - } +/** + * Creates a function that'll short out and invoke `identity` instead + * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN` + * milliseconds. + * + * @private + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new shortable function. + */ +function shortOut(func) { + var count = 0, + lastCalled = 0; - // Validate input and shift parameters if necessary - if (!isString(data) && !isBuffer(data)) { - throw new TypeError("data should be a string, Buffer or Uint8Array"); - } - if (isFunction(encoding)) { - callback = encoding; - encoding = null; - } + return function() { + var stamp = nativeNow(), + remaining = HOT_SPAN - (stamp - lastCalled); - // Ignore empty buffers, since writing them doesn't invoke the callback - // https://github.com/nodejs/node/issues/22066 - if (data.length === 0) { - if (callback) { - callback(); + lastCalled = stamp; + if (remaining > 0) { + if (++count >= HOT_COUNT) { + return arguments[0]; + } + } else { + count = 0; } - return; - } - // Only write when we don't exceed the maximum body length - if (this._requestBodyLength + data.length <= this._options.maxBodyLength) { - this._requestBodyLength += data.length; - this._requestBodyBuffers.push({ data: data, encoding: encoding }); - this._currentRequest.write(data, encoding, callback); - } - // Error when we exceed the maximum body length - else { - this.emit("error", new MaxBodyLengthExceededError()); - this.abort(); - } -}; + return func.apply(undefined, arguments); + }; +} -// Ends the current native request -RedirectableRequest.prototype.end = function (data, encoding, callback) { - // Shift parameters if necessary - if (isFunction(data)) { - callback = data; - data = encoding = null; - } - else if (isFunction(encoding)) { - callback = encoding; - encoding = null; +/** + * Converts `func` to its source code. + * + * @private + * @param {Function} func The function to convert. + * @returns {string} Returns the source code. + */ +function toSource(func) { + if (func != null) { + try { + return funcToString.call(func); + } catch (e) {} + try { + return (func + ''); + } catch (e) {} } + return ''; +} - // Write data if needed and end - if (!data) { - this._ended = this._ending = true; - this._currentRequest.end(null, null, callback); - } - else { - var self = this; - var currentRequest = this._currentRequest; - this.write(data, encoding, function () { - self._ended = true; - currentRequest.end(null, null, callback); - }); - this._ending = true; - } -}; - -// Sets a header value on the current native request -RedirectableRequest.prototype.setHeader = function (name, value) { - this._options.headers[name] = value; - this._currentRequest.setHeader(name, value); -}; +/** + * Performs a + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ +function eq(value, other) { + return value === other || (value !== value && other !== other); +} -// Clears a header value on the current native request -RedirectableRequest.prototype.removeHeader = function (name) { - delete this._options.headers[name]; - this._currentRequest.removeHeader(name); +/** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ +var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) { + return isObjectLike(value) && hasOwnProperty.call(value, 'callee') && + !propertyIsEnumerable.call(value, 'callee'); }; -// Global timeout for all underlying requests -RedirectableRequest.prototype.setTimeout = function (msecs, callback) { - var self = this; - - // Destroys the socket on timeout - function destroyOnTimeout(socket) { - socket.setTimeout(msecs); - socket.removeListener("timeout", socket.destroy); - socket.addListener("timeout", socket.destroy); - } - - // Sets up a timer to trigger a timeout event - function startTimer(socket) { - if (self._timeout) { - clearTimeout(self._timeout); - } - self._timeout = setTimeout(function () { - self.emit("timeout"); - clearTimer(); - }, msecs); - destroyOnTimeout(socket); - } +/** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ +var isArray = Array.isArray; - // Stops a timeout from triggering - function clearTimer() { - // Clear the timeout - if (self._timeout) { - clearTimeout(self._timeout); - self._timeout = null; - } +/** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ +function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); +} - // Clean up all attached listeners - self.removeListener("abort", clearTimer); - self.removeListener("error", clearTimer); - self.removeListener("response", clearTimer); - if (callback) { - self.removeListener("timeout", callback); - } - if (!self.socket) { - self._currentRequest.removeListener("socket", startTimer); - } - } +/** + * Checks if `value` is a buffer. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. + * @example + * + * _.isBuffer(new Buffer(2)); + * // => true + * + * _.isBuffer(new Uint8Array(2)); + * // => false + */ +var isBuffer = nativeIsBuffer || stubFalse; - // Attach callback if passed - if (callback) { - this.on("timeout", callback); +/** + * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`, + * `SyntaxError`, `TypeError`, or `URIError` object. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an error object, else `false`. + * @example + * + * _.isError(new Error); + * // => true + * + * _.isError(Error); + * // => false + */ +function isError(value) { + if (!isObjectLike(value)) { + return false; } + var tag = baseGetTag(value); + return tag == errorTag || tag == domExcTag || + (typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value)); +} - // Start the timer if or when the socket is opened - if (this.socket) { - startTimer(this.socket); - } - else { - this._currentRequest.once("socket", startTimer); +/** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ +function isFunction(value) { + if (!isObject(value)) { + return false; } + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 9 which returns 'object' for typed arrays and other constructors. + var tag = baseGetTag(value); + return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; +} - // Clean up on events - this.on("socket", destroyOnTimeout); - this.on("abort", clearTimer); - this.on("error", clearTimer); - this.on("response", clearTimer); - - return this; -}; +/** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ +function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; +} -// Proxy all other public ClientRequest methods -[ - "flushHeaders", "getHeader", - "setNoDelay", "setSocketKeepAlive", -].forEach(function (method) { - RedirectableRequest.prototype[method] = function (a, b) { - return this._currentRequest[method](a, b); - }; -}); +/** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ +function isObject(value) { + var type = typeof value; + return value != null && (type == 'object' || type == 'function'); +} -// Proxy all public ClientRequest properties -["aborted", "connection", "socket"].forEach(function (property) { - Object.defineProperty(RedirectableRequest.prototype, property, { - get: function () { return this._currentRequest[property]; }, - }); -}); - -RedirectableRequest.prototype._sanitizeOptions = function (options) { - // Ensure headers are always present - if (!options.headers) { - options.headers = {}; - } - - // Since http.request treats host as an alias of hostname, - // but the url module interprets host as hostname plus port, - // eliminate the host property to avoid confusion. - if (options.host) { - // Use hostname if set, because it has precedence - if (!options.hostname) { - options.hostname = options.host; - } - delete options.host; - } - - // Complete the URL object when necessary - if (!options.pathname && options.path) { - var searchPos = options.path.indexOf("?"); - if (searchPos < 0) { - options.pathname = options.path; - } - else { - options.pathname = options.path.substring(0, searchPos); - options.search = options.path.substring(searchPos); - } - } -}; - - -// Executes the next native request (initial or redirect) -RedirectableRequest.prototype._performRequest = function () { - // Load the native protocol - var protocol = this._options.protocol; - var nativeProtocol = this._options.nativeProtocols[protocol]; - if (!nativeProtocol) { - this.emit("error", new TypeError("Unsupported protocol " + protocol)); - return; - } - - // If specified, use the agent corresponding to the protocol - // (HTTP and HTTPS use different types of agents) - if (this._options.agents) { - var scheme = protocol.slice(0, -1); - this._options.agent = this._options.agents[scheme]; - } - - // Create the native request and set up its event handlers - var request = this._currentRequest = - nativeProtocol.request(this._options, this._onNativeResponse); - request._redirectable = this; - for (var event of events) { - request.on(event, eventHandlers[event]); - } - - // RFC7230§5.3.1: When making a request directly to an origin server, […] - // a client MUST send only the absolute path […] as the request-target. - this._currentUrl = /^\//.test(this._options.path) ? - url.format(this._options) : - // When making a request to a proxy, […] - // a client MUST send the target URI in absolute-form […]. - this._options.path; - - // End a redirected request - // (The first request must be ended explicitly with RedirectableRequest#end) - if (this._isRedirect) { - // Write the request entity and end - var i = 0; - var self = this; - var buffers = this._requestBodyBuffers; - (function writeNext(error) { - // Only write if this request has not been redirected yet - /* istanbul ignore else */ - if (request === self._currentRequest) { - // Report any write errors - /* istanbul ignore if */ - if (error) { - self.emit("error", error); - } - // Write the next buffer if there are still left - else if (i < buffers.length) { - var buffer = buffers[i++]; - /* istanbul ignore else */ - if (!request.finished) { - request.write(buffer.data, buffer.encoding, writeNext); - } - } - // End the request if `end` has been called on us - else if (self._ended) { - request.end(); - } - } - }()); - } -}; - -// Processes a response from the current native request -RedirectableRequest.prototype._processResponse = function (response) { - // Store the redirected response - var statusCode = response.statusCode; - if (this._options.trackRedirects) { - this._redirects.push({ - url: this._currentUrl, - headers: response.headers, - statusCode: statusCode, - }); - } - - // RFC7231§6.4: The 3xx (Redirection) class of status code indicates - // that further action needs to be taken by the user agent in order to - // fulfill the request. If a Location header field is provided, - // the user agent MAY automatically redirect its request to the URI - // referenced by the Location field value, - // even if the specific status code is not understood. - - // If the response is not a redirect; return it as-is - var location = response.headers.location; - if (!location || this._options.followRedirects === false || - statusCode < 300 || statusCode >= 400) { - response.responseUrl = this._currentUrl; - response.redirects = this._redirects; - this.emit("response", response); - - // Clean up - this._requestBodyBuffers = []; - return; - } - - // The response is a redirect, so abort the current request - abortRequest(this._currentRequest); - // Discard the remainder of the response to avoid waiting for data - response.destroy(); - - // RFC7231§6.4: A client SHOULD detect and intervene - // in cyclical redirections (i.e., "infinite" redirection loops). - if (++this._redirectCount > this._options.maxRedirects) { - this.emit("error", new TooManyRedirectsError()); - return; - } - - // Store the request headers if applicable - var requestHeaders; - var beforeRedirect = this._options.beforeRedirect; - if (beforeRedirect) { - requestHeaders = Object.assign({ - // The Host header was set by nativeProtocol.request - Host: response.req.getHeader("host"), - }, this._options.headers); - } - - // RFC7231§6.4: Automatic redirection needs to done with - // care for methods not known to be safe, […] - // RFC7231§6.4.2–3: For historical reasons, a user agent MAY change - // the request method from POST to GET for the subsequent request. - var method = this._options.method; - if ((statusCode === 301 || statusCode === 302) && this._options.method === "POST" || - // RFC7231§6.4.4: The 303 (See Other) status code indicates that - // the server is redirecting the user agent to a different resource […] - // A user agent can perform a retrieval request targeting that URI - // (a GET or HEAD request if using HTTP) […] - (statusCode === 303) && !/^(?:GET|HEAD)$/.test(this._options.method)) { - this._options.method = "GET"; - // Drop a possible entity and headers related to it - this._requestBodyBuffers = []; - removeMatchingHeaders(/^content-/i, this._options.headers); - } - - // Drop the Host header, as the redirect might lead to a different host - var currentHostHeader = removeMatchingHeaders(/^host$/i, this._options.headers); - - // If the redirect is relative, carry over the host of the last request - var currentUrlParts = url.parse(this._currentUrl); - var currentHost = currentHostHeader || currentUrlParts.host; - var currentUrl = /^\w+:/.test(location) ? this._currentUrl : - url.format(Object.assign(currentUrlParts, { host: currentHost })); - - // Determine the URL of the redirection - var redirectUrl; - try { - redirectUrl = url.resolve(currentUrl, location); - } - catch (cause) { - this.emit("error", new RedirectionError({ cause: cause })); - return; - } - - // Create the redirected request - debug("redirecting to", redirectUrl); - this._isRedirect = true; - var redirectUrlParts = url.parse(redirectUrl); - Object.assign(this._options, redirectUrlParts); - - // Drop confidential headers when redirecting to a less secure protocol - // or to a different domain that is not a superdomain - if (redirectUrlParts.protocol !== currentUrlParts.protocol && - redirectUrlParts.protocol !== "https:" || - redirectUrlParts.host !== currentHost && - !isSubdomain(redirectUrlParts.host, currentHost)) { - removeMatchingHeaders(/^(?:authorization|cookie)$/i, this._options.headers); - } - - // Evaluate the beforeRedirect callback - if (isFunction(beforeRedirect)) { - var responseDetails = { - headers: response.headers, - statusCode: statusCode, - }; - var requestDetails = { - url: currentUrl, - method: method, - headers: requestHeaders, - }; - try { - beforeRedirect(this._options, responseDetails, requestDetails); - } - catch (err) { - this.emit("error", err); - return; - } - this._sanitizeOptions(this._options); - } - - // Perform the redirected request - try { - this._performRequest(); - } - catch (cause) { - this.emit("error", new RedirectionError({ cause: cause })); - } -}; - -// Wraps the key/value object of protocols with redirect functionality -function wrap(protocols) { - // Default settings - var exports = { - maxRedirects: 21, - maxBodyLength: 10 * 1024 * 1024, - }; - - // Wrap each protocol - var nativeProtocols = {}; - Object.keys(protocols).forEach(function (scheme) { - var protocol = scheme + ":"; - var nativeProtocol = nativeProtocols[protocol] = protocols[scheme]; - var wrappedProtocol = exports[scheme] = Object.create(nativeProtocol); - - // Executes a request, following redirects - function request(input, options, callback) { - // Parse parameters - if (isString(input)) { - var parsed; - try { - parsed = urlToOptions(new URL(input)); - } - catch (err) { - /* istanbul ignore next */ - parsed = url.parse(input); - } - if (!isString(parsed.protocol)) { - throw new InvalidUrlError({ input }); - } - input = parsed; - } - else if (URL && (input instanceof URL)) { - input = urlToOptions(input); - } - else { - callback = options; - options = input; - input = { protocol: protocol }; - } - if (isFunction(options)) { - callback = options; - options = null; - } - - // Set defaults - options = Object.assign({ - maxRedirects: exports.maxRedirects, - maxBodyLength: exports.maxBodyLength, - }, input, options); - options.nativeProtocols = nativeProtocols; - if (!isString(options.host) && !isString(options.hostname)) { - options.hostname = "::1"; - } - - assert.equal(options.protocol, protocol, "protocol mismatch"); - debug("options", options); - return new RedirectableRequest(options, callback); - } - - // Executes a GET request, following redirects - function get(input, options, callback) { - var wrappedRequest = wrappedProtocol.request(input, options, callback); - wrappedRequest.end(); - return wrappedRequest; - } - - // Expose the properties on the wrapped protocol - Object.defineProperties(wrappedProtocol, { - request: { value: request, configurable: true, enumerable: true, writable: true }, - get: { value: get, configurable: true, enumerable: true, writable: true }, - }); - }); - return exports; -} - -/* istanbul ignore next */ -function noop() { /* empty */ } - -// from https://github.com/nodejs/node/blob/master/lib/internal/url.js -function urlToOptions(urlObject) { - var options = { - protocol: urlObject.protocol, - hostname: urlObject.hostname.startsWith("[") ? - /* istanbul ignore next */ - urlObject.hostname.slice(1, -1) : - urlObject.hostname, - hash: urlObject.hash, - search: urlObject.search, - pathname: urlObject.pathname, - path: urlObject.pathname + urlObject.search, - href: urlObject.href, - }; - if (urlObject.port !== "") { - options.port = Number(urlObject.port); - } - return options; -} - -function removeMatchingHeaders(regex, headers) { - var lastValue; - for (var header in headers) { - if (regex.test(header)) { - lastValue = headers[header]; - delete headers[header]; - } - } - return (lastValue === null || typeof lastValue === "undefined") ? - undefined : String(lastValue).trim(); +/** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ +function isObjectLike(value) { + return value != null && typeof value == 'object'; } -function createErrorType(code, message, baseClass) { - // Create constructor - function CustomError(properties) { - Error.captureStackTrace(this, this.constructor); - Object.assign(this, properties || {}); - this.code = code; - this.message = this.cause ? message + ": " + this.cause.message : message; +/** + * Checks if `value` is a plain object, that is, an object created by the + * `Object` constructor or one with a `[[Prototype]]` of `null`. + * + * @static + * @memberOf _ + * @since 0.8.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * _.isPlainObject(new Foo); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'x': 0, 'y': 0 }); + * // => true + * + * _.isPlainObject(Object.create(null)); + * // => true + */ +function isPlainObject(value) { + if (!isObjectLike(value) || baseGetTag(value) != objectTag) { + return false; } - - // Attach constructor and set default properties - CustomError.prototype = new (baseClass || Error)(); - CustomError.prototype.constructor = CustomError; - CustomError.prototype.name = "Error [" + code + "]"; - return CustomError; -} - -function abortRequest(request) { - for (var event of events) { - request.removeListener(event, eventHandlers[event]); + var proto = getPrototype(value); + if (proto === null) { + return true; } - request.on("error", noop); - request.abort(); -} - -function isSubdomain(subdomain, domain) { - assert(isString(subdomain) && isString(domain)); - var dot = subdomain.length - domain.length - 1; - return dot > 0 && subdomain[dot] === "." && subdomain.endsWith(domain); -} - -function isString(value) { - return typeof value === "string" || value instanceof String; -} - -function isFunction(value) { - return typeof value === "function"; + var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor; + return typeof Ctor == 'function' && Ctor instanceof Ctor && + funcToString.call(Ctor) == objectCtorString; } -function isBuffer(value) { - return typeof value === "object" && ("length" in value); +/** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ +function isSymbol(value) { + return typeof value == 'symbol' || + (isObjectLike(value) && baseGetTag(value) == symbolTag); } -// Exports -module.exports = wrap({ http: http, https: https }); -module.exports.wrap = wrap; - - -/***/ }), - -/***/ 4334: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var CombinedStream = __nccwpck_require__(5443); -var util = __nccwpck_require__(3837); -var path = __nccwpck_require__(1017); -var http = __nccwpck_require__(3685); -var https = __nccwpck_require__(5687); -var parseUrl = (__nccwpck_require__(7310).parse); -var fs = __nccwpck_require__(7147); -var Stream = (__nccwpck_require__(2781).Stream); -var mime = __nccwpck_require__(3583); -var asynckit = __nccwpck_require__(4812); -var populate = __nccwpck_require__(7142); - -// Public API -module.exports = FormData; - -// make it a Stream -util.inherits(FormData, CombinedStream); - /** - * Create readable "multipart/form-data" streams. - * Can be used to submit forms - * and file uploads to other web applications. + * Checks if `value` is classified as a typed array. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. + * @example * - * @constructor - * @param {Object} options - Properties to be added/overriden for FormData and CombinedStream + * _.isTypedArray(new Uint8Array); + * // => true + * + * _.isTypedArray([]); + * // => false */ -function FormData(options) { - if (!(this instanceof FormData)) { - return new FormData(options); - } - - this._overheadLength = 0; - this._valueLength = 0; - this._valuesToMeasure = []; - - CombinedStream.call(this); +var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray; - options = options || {}; - for (var option in options) { - this[option] = options[option]; - } +/** + * Converts `value` to a string. An empty string is returned for `null` + * and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ +function toString(value) { + return value == null ? '' : baseToString(value); } -FormData.LINE_BREAK = '\r\n'; -FormData.DEFAULT_CONTENT_TYPE = 'application/octet-stream'; - -FormData.prototype.append = function(field, value, options) { - - options = options || {}; - - // allow filename as single option - if (typeof options == 'string') { - options = {filename: options}; - } - - var append = CombinedStream.prototype.append.bind(this); - - // all that streamy business can't handle numbers - if (typeof value == 'number') { - value = '' + value; - } - - // https://github.com/felixge/node-form-data/issues/38 - if (util.isArray(value)) { - // Please convert your array into string - // the way web server expects it - this._error(new Error('Arrays are not supported.')); - return; - } - - var header = this._multiPartHeader(field, value, options); - var footer = this._multiPartFooter(); - - append(header); - append(value); - append(footer); - - // pass along options.knownLength - this._trackLength(header, value, options); -}; - -FormData.prototype._trackLength = function(header, value, options) { - var valueLength = 0; - - // used w/ getLengthSync(), when length is known. - // e.g. for streaming directly from a remote server, - // w/ a known file a size, and not wanting to wait for - // incoming file to finish to get its size. - if (options.knownLength != null) { - valueLength += +options.knownLength; - } else if (Buffer.isBuffer(value)) { - valueLength = value.length; - } else if (typeof value === 'string') { - valueLength = Buffer.byteLength(value); - } - - this._valueLength += valueLength; - - // @check why add CRLF? does this account for custom/multiple CRLFs? - this._overheadLength += - Buffer.byteLength(header) + - FormData.LINE_BREAK.length; - - // empty or either doesn't have path or not an http response or not a stream - if (!value || ( !value.path && !(value.readable && value.hasOwnProperty('httpVersion')) && !(value instanceof Stream))) { - return; - } - - // no need to bother with the length - if (!options.knownLength) { - this._valuesToMeasure.push(value); - } -}; - -FormData.prototype._lengthRetriever = function(value, callback) { - - if (value.hasOwnProperty('fd')) { - - // take read range into a account - // `end` = Infinity –> read file till the end - // - // TODO: Looks like there is bug in Node fs.createReadStream - // it doesn't respect `end` options without `start` options - // Fix it when node fixes it. - // https://github.com/joyent/node/issues/7819 - if (value.end != undefined && value.end != Infinity && value.start != undefined) { - - // when end specified - // no need to calculate range - // inclusive, starts with 0 - callback(null, value.end + 1 - (value.start ? value.start : 0)); - - // not that fast snoopy - } else { - // still need to fetch file size from fs - fs.stat(value.path, function(err, stat) { - - var fileSize; - - if (err) { - callback(err); - return; - } - - // update final size based on the range options - fileSize = stat.size - (value.start ? value.start : 0); - callback(null, fileSize); - }); - } - - // or http response - } else if (value.hasOwnProperty('httpVersion')) { - callback(null, +value.headers['content-length']); - - // or request stream http://github.com/mikeal/request - } else if (value.hasOwnProperty('httpModule')) { - // wait till response come back - value.on('response', function(response) { - value.pause(); - callback(null, +response.headers['content-length']); - }); - value.resume(); - - // something else - } else { - callback('Unknown stream'); - } -}; - -FormData.prototype._multiPartHeader = function(field, value, options) { - // custom header specified (as string)? - // it becomes responsible for boundary - // (e.g. to handle extra CRLFs on .NET servers) - if (typeof options.header == 'string') { - return options.header; - } - - var contentDisposition = this._getContentDisposition(value, options); - var contentType = this._getContentType(value, options); - - var contents = ''; - var headers = { - // add custom disposition as third element or keep it two elements if not - 'Content-Disposition': ['form-data', 'name="' + field + '"'].concat(contentDisposition || []), - // if no content type. allow it to be empty array - 'Content-Type': [].concat(contentType || []) - }; - - // allow custom headers. - if (typeof options.header == 'object') { - populate(headers, options.header); - } - - var header; - for (var prop in headers) { - if (!headers.hasOwnProperty(prop)) continue; - header = headers[prop]; - - // skip nullish headers. - if (header == null) { - continue; - } - - // convert all headers to arrays. - if (!Array.isArray(header)) { - header = [header]; - } - - // add non-empty headers. - if (header.length) { - contents += prop + ': ' + header.join('; ') + FormData.LINE_BREAK; - } - } - - return '--' + this.getBoundary() + FormData.LINE_BREAK + contents + FormData.LINE_BREAK; -}; - -FormData.prototype._getContentDisposition = function(value, options) { - - var filename - , contentDisposition - ; - - if (typeof options.filepath === 'string') { - // custom filepath for relative paths - filename = path.normalize(options.filepath).replace(/\\/g, '/'); - } else if (options.filename || value.name || value.path) { - // custom filename take precedence - // formidable and the browser add a name property - // fs- and request- streams have path property - filename = path.basename(options.filename || value.name || value.path); - } else if (value.readable && value.hasOwnProperty('httpVersion')) { - // or try http response - filename = path.basename(value.client._httpMessage.path || ''); - } - - if (filename) { - contentDisposition = 'filename="' + filename + '"'; - } - - return contentDisposition; -}; - -FormData.prototype._getContentType = function(value, options) { - - // use custom content-type above all - var contentType = options.contentType; - - // or try `name` from formidable, browser - if (!contentType && value.name) { - contentType = mime.lookup(value.name); - } - - // or try `path` from fs-, request- streams - if (!contentType && value.path) { - contentType = mime.lookup(value.path); - } - - // or if it's http-reponse - if (!contentType && value.readable && value.hasOwnProperty('httpVersion')) { - contentType = value.headers['content-type']; - } - - // or guess it from the filepath or filename - if (!contentType && (options.filepath || options.filename)) { - contentType = mime.lookup(options.filepath || options.filename); - } - - // fallback to the default content type if `value` is not simple value - if (!contentType && typeof value == 'object') { - contentType = FormData.DEFAULT_CONTENT_TYPE; - } - - return contentType; -}; - -FormData.prototype._multiPartFooter = function() { - return function(next) { - var footer = FormData.LINE_BREAK; - - var lastPart = (this._streams.length === 0); - if (lastPart) { - footer += this._lastBoundary(); - } - - next(footer); - }.bind(this); -}; - -FormData.prototype._lastBoundary = function() { - return '--' + this.getBoundary() + '--' + FormData.LINE_BREAK; -}; - -FormData.prototype.getHeaders = function(userHeaders) { - var header; - var formHeaders = { - 'content-type': 'multipart/form-data; boundary=' + this.getBoundary() - }; - - for (header in userHeaders) { - if (userHeaders.hasOwnProperty(header)) { - formHeaders[header.toLowerCase()] = userHeaders[header]; - } - } - - return formHeaders; -}; - -FormData.prototype.setBoundary = function(boundary) { - this._boundary = boundary; -}; - -FormData.prototype.getBoundary = function() { - if (!this._boundary) { - this._generateBoundary(); - } - - return this._boundary; -}; - -FormData.prototype.getBuffer = function() { - var dataBuffer = new Buffer.alloc( 0 ); - var boundary = this.getBoundary(); - - // Create the form content. Add Line breaks to the end of data. - for (var i = 0, len = this._streams.length; i < len; i++) { - if (typeof this._streams[i] !== 'function') { - - // Add content to the buffer. - if(Buffer.isBuffer(this._streams[i])) { - dataBuffer = Buffer.concat( [dataBuffer, this._streams[i]]); - }else { - dataBuffer = Buffer.concat( [dataBuffer, Buffer.from(this._streams[i])]); - } - - // Add break after content. - if (typeof this._streams[i] !== 'string' || this._streams[i].substring( 2, boundary.length + 2 ) !== boundary) { - dataBuffer = Buffer.concat( [dataBuffer, Buffer.from(FormData.LINE_BREAK)] ); - } - } - } - - // Add the footer and return the Buffer object. - return Buffer.concat( [dataBuffer, Buffer.from(this._lastBoundary())] ); -}; - -FormData.prototype._generateBoundary = function() { - // This generates a 50 character boundary similar to those used by Firefox. - // They are optimized for boyer-moore parsing. - var boundary = '--------------------------'; - for (var i = 0; i < 24; i++) { - boundary += Math.floor(Math.random() * 10).toString(16); - } - - this._boundary = boundary; -}; - -// Note: getLengthSync DOESN'T calculate streams length -// As workaround one can calculate file size manually -// and add it as knownLength option -FormData.prototype.getLengthSync = function() { - var knownLength = this._overheadLength + this._valueLength; - - // Don't get confused, there are 3 "internal" streams for each keyval pair - // so it basically checks if there is any value added to the form - if (this._streams.length) { - knownLength += this._lastBoundary().length; - } - - // https://github.com/form-data/form-data/issues/40 - if (!this.hasKnownLength()) { - // Some async length retrievers are present - // therefore synchronous length calculation is false. - // Please use getLength(callback) to get proper length - this._error(new Error('Cannot calculate proper length in synchronous way.')); - } - - return knownLength; -}; - -// Public API to check if length of added values is known -// https://github.com/form-data/form-data/issues/196 -// https://github.com/form-data/form-data/issues/262 -FormData.prototype.hasKnownLength = function() { - var hasKnownLength = true; - - if (this._valuesToMeasure.length) { - hasKnownLength = false; - } - - return hasKnownLength; -}; - -FormData.prototype.getLength = function(cb) { - var knownLength = this._overheadLength + this._valueLength; - - if (this._streams.length) { - knownLength += this._lastBoundary().length; - } - - if (!this._valuesToMeasure.length) { - process.nextTick(cb.bind(this, null, knownLength)); - return; - } - - asynckit.parallel(this._valuesToMeasure, this._lengthRetriever, function(err, values) { - if (err) { - cb(err); - return; - } - - values.forEach(function(length) { - knownLength += length; - }); - - cb(null, knownLength); - }); -}; - -FormData.prototype.submit = function(params, cb) { - var request - , options - , defaults = {method: 'post'} - ; - - // parse provided url if it's string - // or treat it as options object - if (typeof params == 'string') { - - params = parseUrl(params); - options = populate({ - port: params.port, - path: params.pathname, - host: params.hostname, - protocol: params.protocol - }, defaults); - - // use custom params - } else { - - options = populate(params, defaults); - // if no port provided use default one - if (!options.port) { - options.port = options.protocol == 'https:' ? 443 : 80; - } - } - - // put that good code in getHeaders to some use - options.headers = this.getHeaders(params.headers); - - // https if specified, fallback to http in any other case - if (options.protocol == 'https:') { - request = https.request(options); - } else { - request = http.request(options); - } - - // get content length and fire away - this.getLength(function(err, length) { - if (err && err !== 'Unknown stream') { - this._error(err); - return; - } - - // add content length - if (length) { - request.setHeader('Content-Length', length); - } - - this.pipe(request); - if (cb) { - var onResponse; - - var callback = function (error, responce) { - request.removeListener('error', callback); - request.removeListener('response', onResponse); - - return cb.call(this, error, responce); - }; - - onResponse = callback.bind(this, null); - - request.on('error', callback); - request.on('response', onResponse); - } - }.bind(this)); - - return request; -}; - -FormData.prototype._error = function(err) { - if (!this.error) { - this.error = err; - this.pause(); - this.emit('error', err); - } -}; - -FormData.prototype.toString = function () { - return '[object FormData]'; -}; - - -/***/ }), - -/***/ 7142: -/***/ ((module) => { - -// populates missing values -module.exports = function(dst, src) { - - Object.keys(src).forEach(function(prop) - { - dst[prop] = dst[prop] || src[prop]; - }); - - return dst; -}; - - -/***/ }), - -/***/ 1621: -/***/ ((module) => { - -"use strict"; - - -module.exports = (flag, argv = process.argv) => { - const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--'); - const position = argv.indexOf(prefix + flag); - const terminatorPosition = argv.indexOf('--'); - return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition); -}; - - -/***/ }), - -/***/ 6008: -/***/ ((module) => { - -/** - * lodash 3.0.0 (Custom Build) - * Build: `lodash modern modularize exports="npm" -o ./` - * Copyright 2012-2015 The Dojo Foundation - * Based on Underscore.js 1.7.0 - * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ - -/** Used to match template delimiters. */ -var reInterpolate = /<%=([\s\S]+?)%>/g; - -module.exports = reInterpolate; - - -/***/ }), - -/***/ 417: -/***/ ((module, exports, __nccwpck_require__) => { - -/* module decorator */ module = __nccwpck_require__.nmd(module); -/** - * Lodash (Custom Build) - * Build: `lodash modularize exports="npm" -o ./` - * Copyright OpenJS Foundation and other contributors - * Released under MIT license - * Based on Underscore.js 1.8.3 - * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - */ -var reInterpolate = __nccwpck_require__(6008), - templateSettings = __nccwpck_require__(5477); - -/** Used to detect hot functions by number of calls within a span of milliseconds. */ -var HOT_COUNT = 800, - HOT_SPAN = 16; - -/** Used as references for various `Number` constants. */ -var INFINITY = 1 / 0, - MAX_SAFE_INTEGER = 9007199254740991; - -/** `Object#toString` result references. */ -var argsTag = '[object Arguments]', - arrayTag = '[object Array]', - asyncTag = '[object AsyncFunction]', - boolTag = '[object Boolean]', - dateTag = '[object Date]', - domExcTag = '[object DOMException]', - errorTag = '[object Error]', - funcTag = '[object Function]', - genTag = '[object GeneratorFunction]', - mapTag = '[object Map]', - numberTag = '[object Number]', - nullTag = '[object Null]', - objectTag = '[object Object]', - proxyTag = '[object Proxy]', - regexpTag = '[object RegExp]', - setTag = '[object Set]', - stringTag = '[object String]', - symbolTag = '[object Symbol]', - undefinedTag = '[object Undefined]', - weakMapTag = '[object WeakMap]'; - -var arrayBufferTag = '[object ArrayBuffer]', - dataViewTag = '[object DataView]', - float32Tag = '[object Float32Array]', - float64Tag = '[object Float64Array]', - int8Tag = '[object Int8Array]', - int16Tag = '[object Int16Array]', - int32Tag = '[object Int32Array]', - uint8Tag = '[object Uint8Array]', - uint8ClampedTag = '[object Uint8ClampedArray]', - uint16Tag = '[object Uint16Array]', - uint32Tag = '[object Uint32Array]'; - -/** Used to match empty string literals in compiled template source. */ -var reEmptyStringLeading = /\b__p \+= '';/g, - reEmptyStringMiddle = /\b(__p \+=) '' \+/g, - reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; - -/** - * Used to match `RegExp` - * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). - */ -var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; - -/** - * Used to match - * [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components). - */ -var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; - -/** Used to detect host constructors (Safari). */ -var reIsHostCtor = /^\[object .+?Constructor\]$/; - -/** Used to detect unsigned integer values. */ -var reIsUint = /^(?:0|[1-9]\d*)$/; - -/** Used to ensure capturing order of template delimiters. */ -var reNoMatch = /($^)/; - -/** Used to match unescaped characters in compiled string literals. */ -var reUnescapedString = /['\n\r\u2028\u2029\\]/g; - -/** Used to identify `toStringTag` values of typed arrays. */ -var typedArrayTags = {}; -typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = -typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = -typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = -typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = -typedArrayTags[uint32Tag] = true; -typedArrayTags[argsTag] = typedArrayTags[arrayTag] = -typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = -typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = -typedArrayTags[errorTag] = typedArrayTags[funcTag] = -typedArrayTags[mapTag] = typedArrayTags[numberTag] = -typedArrayTags[objectTag] = typedArrayTags[regexpTag] = -typedArrayTags[setTag] = typedArrayTags[stringTag] = -typedArrayTags[weakMapTag] = false; - -/** Used to escape characters for inclusion in compiled string literals. */ -var stringEscapes = { - '\\': '\\', - "'": "'", - '\n': 'n', - '\r': 'r', - '\u2028': 'u2028', - '\u2029': 'u2029' -}; - -/** Detect free variable `global` from Node.js. */ -var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; - -/** Detect free variable `self`. */ -var freeSelf = typeof self == 'object' && self && self.Object === Object && self; - -/** Used as a reference to the global object. */ -var root = freeGlobal || freeSelf || Function('return this')(); - -/** Detect free variable `exports`. */ -var freeExports = true && exports && !exports.nodeType && exports; - -/** Detect free variable `module`. */ -var freeModule = freeExports && "object" == 'object' && module && !module.nodeType && module; - -/** Detect the popular CommonJS extension `module.exports`. */ -var moduleExports = freeModule && freeModule.exports === freeExports; - -/** Detect free variable `process` from Node.js. */ -var freeProcess = moduleExports && freeGlobal.process; - -/** Used to access faster Node.js helpers. */ -var nodeUtil = (function() { - try { - // Use `util.types` for Node.js 10+. - var types = freeModule && freeModule.require && freeModule.require('util').types; - - if (types) { - return types; - } - - // Legacy `process.binding('util')` for Node.js < 10. - return freeProcess && freeProcess.binding && freeProcess.binding('util'); - } catch (e) {} -}()); - -/* Node.js helper references. */ -var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray; - -/** - * A faster alternative to `Function#apply`, this function invokes `func` - * with the `this` binding of `thisArg` and the arguments of `args`. - * - * @private - * @param {Function} func The function to invoke. - * @param {*} thisArg The `this` binding of `func`. - * @param {Array} args The arguments to invoke `func` with. - * @returns {*} Returns the result of `func`. - */ -function apply(func, thisArg, args) { - switch (args.length) { - case 0: return func.call(thisArg); - case 1: return func.call(thisArg, args[0]); - case 2: return func.call(thisArg, args[0], args[1]); - case 3: return func.call(thisArg, args[0], args[1], args[2]); - } - return func.apply(thisArg, args); -} - -/** - * A specialized version of `_.map` for arrays without support for iteratee - * shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - */ -function arrayMap(array, iteratee) { - var index = -1, - length = array == null ? 0 : array.length, - result = Array(length); - - while (++index < length) { - result[index] = iteratee(array[index], index, array); - } - return result; -} - -/** - * The base implementation of `_.times` without support for iteratee shorthands - * or max array length checks. - * - * @private - * @param {number} n The number of times to invoke `iteratee`. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the array of results. - */ -function baseTimes(n, iteratee) { - var index = -1, - result = Array(n); - - while (++index < n) { - result[index] = iteratee(index); - } - return result; -} - -/** - * The base implementation of `_.unary` without support for storing metadata. - * - * @private - * @param {Function} func The function to cap arguments for. - * @returns {Function} Returns the new capped function. - */ -function baseUnary(func) { - return function(value) { - return func(value); - }; -} - -/** - * The base implementation of `_.values` and `_.valuesIn` which creates an - * array of `object` property values corresponding to the property names - * of `props`. - * - * @private - * @param {Object} object The object to query. - * @param {Array} props The property names to get values for. - * @returns {Object} Returns the array of property values. - */ -function baseValues(object, props) { - return arrayMap(props, function(key) { - return object[key]; - }); -} - -/** - * Used by `_.template` to escape characters for inclusion in compiled string literals. - * - * @private - * @param {string} chr The matched character to escape. - * @returns {string} Returns the escaped character. - */ -function escapeStringChar(chr) { - return '\\' + stringEscapes[chr]; -} - -/** - * Gets the value at `key` of `object`. - * - * @private - * @param {Object} [object] The object to query. - * @param {string} key The key of the property to get. - * @returns {*} Returns the property value. - */ -function getValue(object, key) { - return object == null ? undefined : object[key]; -} - -/** - * Creates a unary function that invokes `func` with its argument transformed. - * - * @private - * @param {Function} func The function to wrap. - * @param {Function} transform The argument transform. - * @returns {Function} Returns the new function. - */ -function overArg(func, transform) { - return function(arg) { - return func(transform(arg)); - }; -} - -/** Used for built-in method references. */ -var funcProto = Function.prototype, - objectProto = Object.prototype; - -/** Used to detect overreaching core-js shims. */ -var coreJsData = root['__core-js_shared__']; - -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - -/** Used to detect methods masquerading as native. */ -var maskSrcKey = (function() { - var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); - return uid ? ('Symbol(src)_1.' + uid) : ''; -}()); - -/** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ -var nativeObjectToString = objectProto.toString; - -/** Used to infer the `Object` constructor. */ -var objectCtorString = funcToString.call(Object); - -/** Used to detect if a method is native. */ -var reIsNative = RegExp('^' + - funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') - .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' -); - -/** Built-in value references. */ -var Buffer = moduleExports ? root.Buffer : undefined, - Symbol = root.Symbol, - getPrototype = overArg(Object.getPrototypeOf, Object), - propertyIsEnumerable = objectProto.propertyIsEnumerable, - symToStringTag = Symbol ? Symbol.toStringTag : undefined; - -var defineProperty = (function() { - try { - var func = getNative(Object, 'defineProperty'); - func({}, '', {}); - return func; - } catch (e) {} -}()); - -/* Built-in method references for those with the same name as other `lodash` methods. */ -var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined, - nativeKeys = overArg(Object.keys, Object), - nativeMax = Math.max, - nativeNow = Date.now; - -/** Used to convert symbols to primitives and strings. */ -var symbolProto = Symbol ? Symbol.prototype : undefined, - symbolToString = symbolProto ? symbolProto.toString : undefined; - -/** - * Creates an array of the enumerable property names of the array-like `value`. - * - * @private - * @param {*} value The value to query. - * @param {boolean} inherited Specify returning inherited property names. - * @returns {Array} Returns the array of property names. - */ -function arrayLikeKeys(value, inherited) { - var isArr = isArray(value), - isArg = !isArr && isArguments(value), - isBuff = !isArr && !isArg && isBuffer(value), - isType = !isArr && !isArg && !isBuff && isTypedArray(value), - skipIndexes = isArr || isArg || isBuff || isType, - result = skipIndexes ? baseTimes(value.length, String) : [], - length = result.length; - - for (var key in value) { - if ((inherited || hasOwnProperty.call(value, key)) && - !(skipIndexes && ( - // Safari 9 has enumerable `arguments.length` in strict mode. - key == 'length' || - // Node.js 0.10 has enumerable non-index properties on buffers. - (isBuff && (key == 'offset' || key == 'parent')) || - // PhantomJS 2 has enumerable non-index properties on typed arrays. - (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) || - // Skip index properties. - isIndex(key, length) - ))) { - result.push(key); - } - } - return result; -} - -/** - * Assigns `value` to `key` of `object` if the existing value is not equivalent - * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * for equality comparisons. - * - * @private - * @param {Object} object The object to modify. - * @param {string} key The key of the property to assign. - * @param {*} value The value to assign. - */ -function assignValue(object, key, value) { - var objValue = object[key]; - if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || - (value === undefined && !(key in object))) { - baseAssignValue(object, key, value); - } -} - -/** - * The base implementation of `assignValue` and `assignMergeValue` without - * value checks. - * - * @private - * @param {Object} object The object to modify. - * @param {string} key The key of the property to assign. - * @param {*} value The value to assign. - */ -function baseAssignValue(object, key, value) { - if (key == '__proto__' && defineProperty) { - defineProperty(object, key, { - 'configurable': true, - 'enumerable': true, - 'value': value, - 'writable': true - }); - } else { - object[key] = value; - } -} - -/** - * The base implementation of `getTag` without fallbacks for buggy environments. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the `toStringTag`. - */ -function baseGetTag(value) { - if (value == null) { - return value === undefined ? undefinedTag : nullTag; - } - return (symToStringTag && symToStringTag in Object(value)) - ? getRawTag(value) - : objectToString(value); -} - -/** - * The base implementation of `_.isArguments`. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an `arguments` object, - */ -function baseIsArguments(value) { - return isObjectLike(value) && baseGetTag(value) == argsTag; -} - -/** - * The base implementation of `_.isNative` without bad shim checks. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a native function, - * else `false`. - */ -function baseIsNative(value) { - if (!isObject(value) || isMasked(value)) { - return false; - } - var pattern = isFunction(value) ? reIsNative : reIsHostCtor; - return pattern.test(toSource(value)); -} - -/** - * The base implementation of `_.isTypedArray` without Node.js optimizations. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. - */ -function baseIsTypedArray(value) { - return isObjectLike(value) && - isLength(value.length) && !!typedArrayTags[baseGetTag(value)]; -} - -/** - * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - */ -function baseKeys(object) { - if (!isPrototype(object)) { - return nativeKeys(object); - } - var result = []; - for (var key in Object(object)) { - if (hasOwnProperty.call(object, key) && key != 'constructor') { - result.push(key); - } - } - return result; -} - -/** - * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - */ -function baseKeysIn(object) { - if (!isObject(object)) { - return nativeKeysIn(object); - } - var isProto = isPrototype(object), - result = []; - - for (var key in object) { - if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { - result.push(key); - } - } - return result; -} - -/** - * The base implementation of `_.rest` which doesn't validate or coerce arguments. - * - * @private - * @param {Function} func The function to apply a rest parameter to. - * @param {number} [start=func.length-1] The start position of the rest parameter. - * @returns {Function} Returns the new function. - */ -function baseRest(func, start) { - return setToString(overRest(func, start, identity), func + ''); -} - -/** - * The base implementation of `setToString` without support for hot loop shorting. - * - * @private - * @param {Function} func The function to modify. - * @param {Function} string The `toString` result. - * @returns {Function} Returns `func`. - */ -var baseSetToString = !defineProperty ? identity : function(func, string) { - return defineProperty(func, 'toString', { - 'configurable': true, - 'enumerable': false, - 'value': constant(string), - 'writable': true - }); -}; - -/** - * The base implementation of `_.toString` which doesn't convert nullish - * values to empty strings. - * - * @private - * @param {*} value The value to process. - * @returns {string} Returns the string. - */ -function baseToString(value) { - // Exit early for strings to avoid a performance hit in some environments. - if (typeof value == 'string') { - return value; - } - if (isArray(value)) { - // Recursively convert values (susceptible to call stack limits). - return arrayMap(value, baseToString) + ''; - } - if (isSymbol(value)) { - return symbolToString ? symbolToString.call(value) : ''; - } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; -} - -/** - * Copies properties of `source` to `object`. - * - * @private - * @param {Object} source The object to copy properties from. - * @param {Array} props The property identifiers to copy. - * @param {Object} [object={}] The object to copy properties to. - * @param {Function} [customizer] The function to customize copied values. - * @returns {Object} Returns `object`. - */ -function copyObject(source, props, object, customizer) { - var isNew = !object; - object || (object = {}); - - var index = -1, - length = props.length; - - while (++index < length) { - var key = props[index]; - - var newValue = customizer - ? customizer(object[key], source[key], key, object, source) - : undefined; - - if (newValue === undefined) { - newValue = source[key]; - } - if (isNew) { - baseAssignValue(object, key, newValue); - } else { - assignValue(object, key, newValue); - } - } - return object; -} - -/** - * Creates a function like `_.assign`. - * - * @private - * @param {Function} assigner The function to assign values. - * @returns {Function} Returns the new assigner function. - */ -function createAssigner(assigner) { - return baseRest(function(object, sources) { - var index = -1, - length = sources.length, - customizer = length > 1 ? sources[length - 1] : undefined, - guard = length > 2 ? sources[2] : undefined; - - customizer = (assigner.length > 3 && typeof customizer == 'function') - ? (length--, customizer) - : undefined; - - if (guard && isIterateeCall(sources[0], sources[1], guard)) { - customizer = length < 3 ? undefined : customizer; - length = 1; - } - object = Object(object); - while (++index < length) { - var source = sources[index]; - if (source) { - assigner(object, source, index, customizer); - } - } - return object; - }); -} - -/** - * Used by `_.defaults` to customize its `_.assignIn` use to assign properties - * of source objects to the destination object for all destination properties - * that resolve to `undefined`. - * - * @private - * @param {*} objValue The destination value. - * @param {*} srcValue The source value. - * @param {string} key The key of the property to assign. - * @param {Object} object The parent object of `objValue`. - * @returns {*} Returns the value to assign. - */ -function customDefaultsAssignIn(objValue, srcValue, key, object) { - if (objValue === undefined || - (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) { - return srcValue; - } - return objValue; -} - -/** - * Gets the native function at `key` of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {string} key The key of the method to get. - * @returns {*} Returns the function if it's native, else `undefined`. - */ -function getNative(object, key) { - var value = getValue(object, key); - return baseIsNative(value) ? value : undefined; -} - -/** - * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the raw `toStringTag`. - */ -function getRawTag(value) { - var isOwn = hasOwnProperty.call(value, symToStringTag), - tag = value[symToStringTag]; - - try { - value[symToStringTag] = undefined; - var unmasked = true; - } catch (e) {} - - var result = nativeObjectToString.call(value); - if (unmasked) { - if (isOwn) { - value[symToStringTag] = tag; - } else { - delete value[symToStringTag]; - } - } - return result; -} - -/** - * Checks if `value` is a valid array-like index. - * - * @private - * @param {*} value The value to check. - * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. - * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. - */ -function isIndex(value, length) { - var type = typeof value; - length = length == null ? MAX_SAFE_INTEGER : length; - - return !!length && - (type == 'number' || - (type != 'symbol' && reIsUint.test(value))) && - (value > -1 && value % 1 == 0 && value < length); -} - -/** - * Checks if the given arguments are from an iteratee call. - * - * @private - * @param {*} value The potential iteratee value argument. - * @param {*} index The potential iteratee index or key argument. - * @param {*} object The potential iteratee object argument. - * @returns {boolean} Returns `true` if the arguments are from an iteratee call, - * else `false`. - */ -function isIterateeCall(value, index, object) { - if (!isObject(object)) { - return false; - } - var type = typeof index; - if (type == 'number' - ? (isArrayLike(object) && isIndex(index, object.length)) - : (type == 'string' && index in object) - ) { - return eq(object[index], value); - } - return false; -} - -/** - * Checks if `func` has its source masked. - * - * @private - * @param {Function} func The function to check. - * @returns {boolean} Returns `true` if `func` is masked, else `false`. - */ -function isMasked(func) { - return !!maskSrcKey && (maskSrcKey in func); -} - -/** - * Checks if `value` is likely a prototype object. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. - */ -function isPrototype(value) { - var Ctor = value && value.constructor, - proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; - - return value === proto; -} - -/** - * This function is like - * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) - * except that it includes inherited enumerable properties. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - */ -function nativeKeysIn(object) { - var result = []; - if (object != null) { - for (var key in Object(object)) { - result.push(key); - } - } - return result; -} - -/** - * Converts `value` to a string using `Object.prototype.toString`. - * - * @private - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - */ -function objectToString(value) { - return nativeObjectToString.call(value); -} - -/** - * A specialized version of `baseRest` which transforms the rest array. - * - * @private - * @param {Function} func The function to apply a rest parameter to. - * @param {number} [start=func.length-1] The start position of the rest parameter. - * @param {Function} transform The rest array transform. - * @returns {Function} Returns the new function. - */ -function overRest(func, start, transform) { - start = nativeMax(start === undefined ? (func.length - 1) : start, 0); - return function() { - var args = arguments, - index = -1, - length = nativeMax(args.length - start, 0), - array = Array(length); - - while (++index < length) { - array[index] = args[start + index]; - } - index = -1; - var otherArgs = Array(start + 1); - while (++index < start) { - otherArgs[index] = args[index]; - } - otherArgs[start] = transform(array); - return apply(func, this, otherArgs); - }; -} - -/** - * Sets the `toString` method of `func` to return `string`. - * - * @private - * @param {Function} func The function to modify. - * @param {Function} string The `toString` result. - * @returns {Function} Returns `func`. - */ -var setToString = shortOut(baseSetToString); - -/** - * Creates a function that'll short out and invoke `identity` instead - * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN` - * milliseconds. - * - * @private - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new shortable function. - */ -function shortOut(func) { - var count = 0, - lastCalled = 0; - - return function() { - var stamp = nativeNow(), - remaining = HOT_SPAN - (stamp - lastCalled); - - lastCalled = stamp; - if (remaining > 0) { - if (++count >= HOT_COUNT) { - return arguments[0]; - } - } else { - count = 0; - } - return func.apply(undefined, arguments); - }; -} - -/** - * Converts `func` to its source code. - * - * @private - * @param {Function} func The function to convert. - * @returns {string} Returns the source code. - */ -function toSource(func) { - if (func != null) { - try { - return funcToString.call(func); - } catch (e) {} - try { - return (func + ''); - } catch (e) {} - } - return ''; -} - -/** - * Performs a - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * comparison between two values to determine if they are equivalent. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * var object = { 'a': 1 }; - * var other = { 'a': 1 }; - * - * _.eq(object, object); - * // => true - * - * _.eq(object, other); - * // => false - * - * _.eq('a', 'a'); - * // => true - * - * _.eq('a', Object('a')); - * // => false - * - * _.eq(NaN, NaN); - * // => true - */ -function eq(value, other) { - return value === other || (value !== value && other !== other); -} - -/** - * Checks if `value` is likely an `arguments` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an `arguments` object, - * else `false`. - * @example - * - * _.isArguments(function() { return arguments; }()); - * // => true - * - * _.isArguments([1, 2, 3]); - * // => false - */ -var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) { - return isObjectLike(value) && hasOwnProperty.call(value, 'callee') && - !propertyIsEnumerable.call(value, 'callee'); -}; - -/** - * Checks if `value` is classified as an `Array` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array, else `false`. - * @example - * - * _.isArray([1, 2, 3]); - * // => true - * - * _.isArray(document.body.children); - * // => false - * - * _.isArray('abc'); - * // => false - * - * _.isArray(_.noop); - * // => false - */ -var isArray = Array.isArray; - -/** - * Checks if `value` is array-like. A value is considered array-like if it's - * not a function and has a `value.length` that's an integer greater than or - * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is array-like, else `false`. - * @example - * - * _.isArrayLike([1, 2, 3]); - * // => true - * - * _.isArrayLike(document.body.children); - * // => true - * - * _.isArrayLike('abc'); - * // => true - * - * _.isArrayLike(_.noop); - * // => false - */ -function isArrayLike(value) { - return value != null && isLength(value.length) && !isFunction(value); -} - -/** - * Checks if `value` is a buffer. - * - * @static - * @memberOf _ - * @since 4.3.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. - * @example - * - * _.isBuffer(new Buffer(2)); - * // => true - * - * _.isBuffer(new Uint8Array(2)); - * // => false - */ -var isBuffer = nativeIsBuffer || stubFalse; - -/** - * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`, - * `SyntaxError`, `TypeError`, or `URIError` object. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an error object, else `false`. - * @example - * - * _.isError(new Error); - * // => true - * - * _.isError(Error); - * // => false - */ -function isError(value) { - if (!isObjectLike(value)) { - return false; - } - var tag = baseGetTag(value); - return tag == errorTag || tag == domExcTag || - (typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value)); -} - -/** - * Checks if `value` is classified as a `Function` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a function, else `false`. - * @example - * - * _.isFunction(_); - * // => true - * - * _.isFunction(/abc/); - * // => false - */ -function isFunction(value) { - if (!isObject(value)) { - return false; - } - // The use of `Object#toString` avoids issues with the `typeof` operator - // in Safari 9 which returns 'object' for typed arrays and other constructors. - var tag = baseGetTag(value); - return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; -} - -/** - * Checks if `value` is a valid array-like length. - * - * **Note:** This method is loosely based on - * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. - * @example - * - * _.isLength(3); - * // => true - * - * _.isLength(Number.MIN_VALUE); - * // => false - * - * _.isLength(Infinity); - * // => false - * - * _.isLength('3'); - * // => false - */ -function isLength(value) { - return typeof value == 'number' && - value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; -} - -/** - * Checks if `value` is the - * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) - * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(_.noop); - * // => true - * - * _.isObject(null); - * // => false - */ -function isObject(value) { - var type = typeof value; - return value != null && (type == 'object' || type == 'function'); -} - -/** - * Checks if `value` is object-like. A value is object-like if it's not `null` - * and has a `typeof` result of "object". - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is object-like, else `false`. - * @example - * - * _.isObjectLike({}); - * // => true - * - * _.isObjectLike([1, 2, 3]); - * // => true - * - * _.isObjectLike(_.noop); - * // => false - * - * _.isObjectLike(null); - * // => false - */ -function isObjectLike(value) { - return value != null && typeof value == 'object'; -} - -/** - * Checks if `value` is a plain object, that is, an object created by the - * `Object` constructor or one with a `[[Prototype]]` of `null`. - * - * @static - * @memberOf _ - * @since 0.8.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. - * @example - * - * function Foo() { - * this.a = 1; - * } - * - * _.isPlainObject(new Foo); - * // => false - * - * _.isPlainObject([1, 2, 3]); - * // => false - * - * _.isPlainObject({ 'x': 0, 'y': 0 }); - * // => true - * - * _.isPlainObject(Object.create(null)); - * // => true - */ -function isPlainObject(value) { - if (!isObjectLike(value) || baseGetTag(value) != objectTag) { - return false; - } - var proto = getPrototype(value); - if (proto === null) { - return true; - } - var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor; - return typeof Ctor == 'function' && Ctor instanceof Ctor && - funcToString.call(Ctor) == objectCtorString; -} - -/** - * Checks if `value` is classified as a `Symbol` primitive or object. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. - * @example - * - * _.isSymbol(Symbol.iterator); - * // => true - * - * _.isSymbol('abc'); - * // => false - */ -function isSymbol(value) { - return typeof value == 'symbol' || - (isObjectLike(value) && baseGetTag(value) == symbolTag); -} - -/** - * Checks if `value` is classified as a typed array. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. - * @example - * - * _.isTypedArray(new Uint8Array); - * // => true - * - * _.isTypedArray([]); - * // => false - */ -var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray; - -/** - * Converts `value` to a string. An empty string is returned for `null` - * and `undefined` values. The sign of `-0` is preserved. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - * @example - * - * _.toString(null); - * // => '' - * - * _.toString(-0); - * // => '-0' - * - * _.toString([1, 2, 3]); - * // => '1,2,3' - */ -function toString(value) { - return value == null ? '' : baseToString(value); -} - -/** - * This method is like `_.assignIn` except that it accepts `customizer` - * which is invoked to produce the assigned values. If `customizer` returns - * `undefined`, assignment is handled by the method instead. The `customizer` - * is invoked with five arguments: (objValue, srcValue, key, object, source). - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @alias extendWith - * @category Object - * @param {Object} object The destination object. - * @param {...Object} sources The source objects. - * @param {Function} [customizer] The function to customize assigned values. - * @returns {Object} Returns `object`. - * @see _.assignWith - * @example - * - * function customizer(objValue, srcValue) { - * return _.isUndefined(objValue) ? srcValue : objValue; - * } - * - * var defaults = _.partialRight(_.assignInWith, customizer); - * - * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); - * // => { 'a': 1, 'b': 2 } - */ -var assignInWith = createAssigner(function(object, source, srcIndex, customizer) { - copyObject(source, keysIn(source), object, customizer); -}); - -/** - * Creates an array of the own enumerable property names of `object`. - * - * **Note:** Non-object values are coerced to objects. See the - * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) - * for more details. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.keys(new Foo); - * // => ['a', 'b'] (iteration order is not guaranteed) - * - * _.keys('hi'); - * // => ['0', '1'] - */ -function keys(object) { - return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); -} - -/** - * Creates an array of the own and inherited enumerable property names of `object`. - * - * **Note:** Non-object values are coerced to objects. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.keysIn(new Foo); - * // => ['a', 'b', 'c'] (iteration order is not guaranteed) - */ -function keysIn(object) { - return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object); -} - -/** - * Creates a compiled template function that can interpolate data properties - * in "interpolate" delimiters, HTML-escape interpolated data properties in - * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data - * properties may be accessed as free variables in the template. If a setting - * object is given, it takes precedence over `_.templateSettings` values. - * - * **Note:** In the development build `_.template` utilizes - * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) - * for easier debugging. - * - * For more information on precompiling templates see - * [lodash's custom builds documentation](https://lodash.com/custom-builds). - * - * For more information on Chrome extension sandboxes see - * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval). - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category String - * @param {string} [string=''] The template string. - * @param {Object} [options={}] The options object. - * @param {RegExp} [options.escape=_.templateSettings.escape] - * The HTML "escape" delimiter. - * @param {RegExp} [options.evaluate=_.templateSettings.evaluate] - * The "evaluate" delimiter. - * @param {Object} [options.imports=_.templateSettings.imports] - * An object to import into the template as free variables. - * @param {RegExp} [options.interpolate=_.templateSettings.interpolate] - * The "interpolate" delimiter. - * @param {string} [options.sourceURL='templateSources[n]'] - * The sourceURL of the compiled template. - * @param {string} [options.variable='obj'] - * The data object variable name. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Function} Returns the compiled template function. - * @example - * - * // Use the "interpolate" delimiter to create a compiled template. - * var compiled = _.template('hello <%= user %>!'); - * compiled({ 'user': 'fred' }); - * // => 'hello fred!' - * - * // Use the HTML "escape" delimiter to escape data property values. - * var compiled = _.template('<%- value %>'); - * compiled({ 'value': '