From 94beed1b79e75c89813c30cae80053055699ee45 Mon Sep 17 00:00:00 2001 From: Luke Elmers Date: Thu, 20 Aug 2020 10:08:31 -0600 Subject: [PATCH 01/45] [expressions] Remove legacy APIs. (#75517) --- .../new_platform/new_platform.karma_mock.js | 11 -- src/plugins/expressions/kibana.json | 3 - src/plugins/expressions/public/loader.test.ts | 9 +- src/plugins/expressions/public/mocks.tsx | 27 +--- src/plugins/expressions/public/plugin.ts | 123 ++-------------- src/plugins/expressions/public/services.ts | 13 +- src/plugins/expressions/server/index.ts | 2 +- src/plugins/expressions/server/legacy.ts | 134 ------------------ src/plugins/expressions/server/mocks.ts | 14 +- src/plugins/expressions/server/plugin.ts | 54 ++----- .../core/create_kibana_utils_core.test.ts | 39 ----- .../public/core/create_kibana_utils_core.ts | 39 ----- src/plugins/kibana_utils/public/core/index.ts | 1 - .../public/core/saved_objects_client.ts | 35 ----- src/plugins/kibana_utils/public/core/state.ts | 23 --- .../public/services/stubs/expressions.ts | 4 +- 16 files changed, 27 insertions(+), 504 deletions(-) delete mode 100644 src/plugins/expressions/server/legacy.ts delete mode 100644 src/plugins/kibana_utils/public/core/create_kibana_utils_core.test.ts delete mode 100644 src/plugins/kibana_utils/public/core/create_kibana_utils_core.ts delete mode 100644 src/plugins/kibana_utils/public/core/saved_objects_client.ts delete mode 100644 src/plugins/kibana_utils/public/core/state.ts diff --git a/src/legacy/ui/public/new_platform/new_platform.karma_mock.js b/src/legacy/ui/public/new_platform/new_platform.karma_mock.js index 5ef1149146afe..b8d48b784dba7 100644 --- a/src/legacy/ui/public/new_platform/new_platform.karma_mock.js +++ b/src/legacy/ui/public/new_platform/new_platform.karma_mock.js @@ -221,17 +221,6 @@ export const npSetup = { registerFunction: sinon.fake(), registerRenderer: sinon.fake(), registerType: sinon.fake(), - __LEGACY: { - renderers: { - register: () => undefined, - get: () => null, - }, - getExecutor: () => ({ - interpreter: { - interpretAst: () => {}, - }, - }), - }, }, data: { autocomplete: { diff --git a/src/plugins/expressions/kibana.json b/src/plugins/expressions/kibana.json index 5163331088103..67bbf4b6e5454 100644 --- a/src/plugins/expressions/kibana.json +++ b/src/plugins/expressions/kibana.json @@ -3,9 +3,6 @@ "version": "kibana", "server": true, "ui": true, - "requiredPlugins": [ - "bfetch" - ], "extraPublicDirs": ["common", "common/fonts"], "requiredBundles": [ "kibanaUtils", diff --git a/src/plugins/expressions/public/loader.test.ts b/src/plugins/expressions/public/loader.test.ts index e07a22a5e1d60..bf8b442769563 100644 --- a/src/plugins/expressions/public/loader.test.ts +++ b/src/plugins/expressions/public/loader.test.ts @@ -20,7 +20,7 @@ import { first, skip, toArray } from 'rxjs/operators'; import { loader, ExpressionLoader } from './loader'; import { Observable } from 'rxjs'; -import { ExpressionAstExpression, parseExpression, IInterpreterRenderHandlers } from '../common'; +import { parseExpression, IInterpreterRenderHandlers } from '../common'; // eslint-disable-next-line const { __getLastExecution } = require('./services'); @@ -42,13 +42,6 @@ jest.mock('./services', () => { const moduleMock = { __execution: undefined, __getLastExecution: () => moduleMock.__execution, - getInterpreter: () => { - return { - interpretAst: async (expression: ExpressionAstExpression) => { - return { type: 'render', as: 'test' }; - }, - }; - }, getRenderersRegistry: () => ({ get: (id: string) => renderers[id], }), diff --git a/src/plugins/expressions/public/mocks.tsx b/src/plugins/expressions/public/mocks.tsx index 6e649c29ead7d..3865b4d20620a 100644 --- a/src/plugins/expressions/public/mocks.tsx +++ b/src/plugins/expressions/public/mocks.tsx @@ -21,7 +21,6 @@ import React from 'react'; import { ExpressionsSetup, ExpressionsStart, plugin as pluginInitializer } from '.'; import { coreMock } from '../../../core/public/mocks'; -import { bfetchPluginMock } from '../../bfetch/public/mocks'; export type Setup = jest.Mocked; export type Start = jest.Mocked; @@ -39,23 +38,6 @@ const createSetupContract = (): Setup => { registerRenderer: jest.fn(), registerType: jest.fn(), run: jest.fn(), - __LEGACY: { - functions: { - register: () => {}, - } as any, - renderers: { - register: () => {}, - } as any, - types: { - register: () => {}, - } as any, - getExecutor: () => ({ - interpreter: { - interpretAst: (() => {}) as any, - }, - }), - loadLegacyServerFunctionWrappers: () => Promise.resolve(), - }, }; return setupContract; }; @@ -84,9 +66,7 @@ const createPlugin = async () => { const coreSetup = coreMock.createSetup(); const coreStart = coreMock.createStart(); const plugin = pluginInitializer(pluginInitializerContext); - const setup = await plugin.setup(coreSetup, { - bfetch: bfetchPluginMock.createSetupContract(), - }); + const setup = await plugin.setup(coreSetup); return { pluginInitializerContext, @@ -94,10 +74,7 @@ const createPlugin = async () => { coreStart, plugin, setup, - doStart: async () => - await plugin.start(coreStart, { - bfetch: bfetchPluginMock.createStartContract(), - }), + doStart: async () => await plugin.start(coreStart), }; }; diff --git a/src/plugins/expressions/public/plugin.ts b/src/plugins/expressions/public/plugin.ts index ec60fbdf44c3a..9768ece899dd4 100644 --- a/src/plugins/expressions/public/plugin.ts +++ b/src/plugins/expressions/public/plugin.ts @@ -17,75 +17,19 @@ * under the License. */ -import { PluginInitializerContext, CoreSetup, CoreStart, Plugin } from '../../../core/public'; -import { ExpressionExecutor } from './types'; +import { PluginInitializerContext, CoreSetup, CoreStart, Plugin } from 'src/core/public'; import { - ExpressionRendererRegistry, - FunctionsRegistry, - serializeProvider, - TypesRegistry, ExpressionsService, ExpressionsServiceSetup, ExpressionsServiceStart, ExecutionContext, } from '../common'; -import { BfetchPublicSetup, BfetchPublicStart } from '../../bfetch/public'; -import { - setCoreStart, - setInterpreter, - setRenderersRegistry, - setNotifications, - setExpressionsService, -} from './services'; +import { setRenderersRegistry, setNotifications, setExpressionsService } from './services'; import { ReactExpressionRenderer } from './react_expression_renderer'; import { ExpressionLoader, loader } from './loader'; import { render, ExpressionRenderHandler } from './render'; -export interface ExpressionsSetupDeps { - bfetch: BfetchPublicSetup; -} - -export interface ExpressionsStartDeps { - bfetch: BfetchPublicStart; -} - -export interface ExpressionsSetup extends ExpressionsServiceSetup { - /** - * @todo Get rid of these `__LEGACY` APIs. - * - * `__LEGACY` APIs are used by Canvas. It should be possible to stop - * using all of them (except `loadLegacyServerFunctionWrappers`) and use - * Kibana Platform plugin contracts instead. - */ - __LEGACY: { - /** - * Use `registerType` and `getTypes` instead. - */ - types: TypesRegistry; - - /** - * Use `registerFunction` and `getFunctions` instead. - */ - functions: FunctionsRegistry; - - /** - * Use `registerRenderer` and `getRenderers`, and `getRenderer` instead. - */ - renderers: ExpressionRendererRegistry; - - /** - * Use `run` function instead. - */ - getExecutor: () => ExpressionExecutor; - - /** - * This function is used by Canvas to load server-side function and create - * browser-side "wrapper" for each one. This function can be removed once - * we enable expressions on server-side: https://github.com/elastic/kibana/issues/46906 - */ - loadLegacyServerFunctionWrappers: () => Promise; - }; -} +export type ExpressionsSetup = ExpressionsServiceSetup; export interface ExpressionsStart extends ExpressionsServiceStart { ExpressionLoader: typeof ExpressionLoader; @@ -95,9 +39,7 @@ export interface ExpressionsStart extends ExpressionsServiceStart { render: typeof render; } -export class ExpressionsPublicPlugin - implements - Plugin { +export class ExpressionsPublicPlugin implements Plugin { private readonly expressions: ExpressionsService = new ExpressionsService(); constructor(initializerContext: PluginInitializerContext) {} @@ -116,68 +58,21 @@ export class ExpressionsPublicPlugin }); } - public setup(core: CoreSetup, { bfetch }: ExpressionsSetupDeps): ExpressionsSetup { + public setup(core: CoreSetup): ExpressionsSetup { this.configureExecutor(core); const { expressions } = this; - const { executor, renderers } = expressions; + const { renderers } = expressions; setRenderersRegistry(renderers); - setExpressionsService(this.expressions); + setExpressionsService(expressions); - const expressionsSetup = expressions.setup(); - - // This is legacy. Should go away when we get rid of __LEGACY. - const getExecutor = (): ExpressionExecutor => { - return { interpreter: { interpretAst: expressionsSetup.run } }; - }; - - setInterpreter(getExecutor().interpreter); - - let cached: Promise | null = null; - const loadLegacyServerFunctionWrappers = async () => { - if (!cached) { - cached = (async () => { - const serverFunctionList = await core.http.get(`/api/interpreter/fns`); - const batchedFunction = bfetch.batchedFunction({ url: `/api/interpreter/fns` }); - const { serialize } = serializeProvider(executor.getTypes()); - - // For every sever-side function, register a client-side - // function that matches its definition, but which simply - // calls the server-side function endpoint. - Object.keys(serverFunctionList).forEach((functionName) => { - if (expressionsSetup.getFunction(functionName)) { - return; - } - const fn = () => ({ - ...serverFunctionList[functionName], - fn: (input: any, args: any) => { - return batchedFunction({ functionName, args, context: serialize(input) }); - }, - }); - expressionsSetup.registerFunction(fn); - }); - })(); - } - return cached; - }; - - const setup: ExpressionsSetup = { - ...expressionsSetup, - __LEGACY: { - types: executor.types, - functions: executor.functions, - renderers, - getExecutor, - loadLegacyServerFunctionWrappers, - }, - }; + const setup = expressions.setup(); return Object.freeze(setup); } - public start(core: CoreStart, { bfetch }: ExpressionsStartDeps): ExpressionsStart { - setCoreStart(core); + public start(core: CoreStart): ExpressionsStart { setNotifications(core.notifications); const { expressions } = this; diff --git a/src/plugins/expressions/public/services.ts b/src/plugins/expressions/public/services.ts index 016456c956666..e296566e661cd 100644 --- a/src/plugins/expressions/public/services.ts +++ b/src/plugins/expressions/public/services.ts @@ -18,22 +18,15 @@ */ import { NotificationsStart } from 'kibana/public'; -import { createKibanaUtilsCore, createGetterSetter } from '../../kibana_utils/public'; -import { ExpressionInterpreter } from './types'; -import { ExpressionsSetup } from './plugin'; -import { ExpressionsService } from '../common'; +import { createGetterSetter } from '../../kibana_utils/public'; +import { ExpressionsService, ExpressionRendererRegistry } from '../common'; -export const { getCoreStart, setCoreStart } = createKibanaUtilsCore(); - -export const [getInterpreter, setInterpreter] = createGetterSetter( - 'Interpreter' -); export const [getNotifications, setNotifications] = createGetterSetter( 'Notifications' ); export const [getRenderersRegistry, setRenderersRegistry] = createGetterSetter< - ExpressionsSetup['__LEGACY']['renderers'] + ExpressionRendererRegistry >('Renderers registry'); export const [getExpressionsService, setExpressionsService] = createGetterSetter< diff --git a/src/plugins/expressions/server/index.ts b/src/plugins/expressions/server/index.ts index 9b2f0b794258b..6785457321595 100644 --- a/src/plugins/expressions/server/index.ts +++ b/src/plugins/expressions/server/index.ts @@ -17,7 +17,7 @@ * under the License. */ -import { PluginInitializerContext } from '../../../core/server'; +import { PluginInitializerContext } from 'src/core/server'; import { ExpressionsServerPlugin } from './plugin'; export { ExpressionsServerSetup, ExpressionsServerStart } from './plugin'; diff --git a/src/plugins/expressions/server/legacy.ts b/src/plugins/expressions/server/legacy.ts deleted file mode 100644 index 8ff08542f18f8..0000000000000 --- a/src/plugins/expressions/server/legacy.ts +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/* eslint-disable max-classes-per-file */ - -// TODO: Remove this file once https://github.com/elastic/kibana/issues/46906 is complete. - -// @ts-ignore -import { register, registryFactory, Registry, Fn } from '@kbn/interpreter/common'; - -import Boom from 'boom'; -import { schema } from '@kbn/config-schema'; -import { CoreSetup, Logger, LegacyAPICaller } from 'src/core/server'; -import { ExpressionsServerSetupDependencies } from './plugin'; -import { typeSpecs, ExpressionType } from '../common'; -import { serializeProvider } from '../common'; - -export class TypesRegistry extends Registry { - wrapper(obj: any) { - return new (ExpressionType as any)(obj); - } -} - -export class FunctionsRegistry extends Registry { - wrapper(obj: any) { - return new Fn(obj); - } -} - -export const registries = { - types: new TypesRegistry(), - serverFunctions: new FunctionsRegistry(), -}; - -export interface LegacyInterpreterServerApi { - registries(): typeof registries; - register(specs: Record): typeof registries; -} - -export const createLegacyServerInterpreterApi = (): LegacyInterpreterServerApi => { - const api = registryFactory(registries); - - register(registries, { - types: typeSpecs, - }); - - return api; -}; - -export const createLegacyServerEndpoints = ( - api: LegacyInterpreterServerApi, - logger: Logger, - core: CoreSetup, - plugins: ExpressionsServerSetupDependencies -) => { - const router = core.http.createRouter(); - - /** - * Register the endpoint that returns the list of server-only functions. - */ - router.get( - { - path: `/api/interpreter/fns`, - validate: { - body: schema.any(), - }, - }, - async (context, request, response) => { - const functions = api.registries().serverFunctions.toJS(); - const body = JSON.stringify(functions); - return response.ok({ - body, - }); - } - ); - - /** - * Run a single Canvas function. - * - * @param {*} server - The Kibana server object - * @param {*} handlers - The Canvas handlers - * @param {*} fnCall - Describes the function being run `{ functionName, args, context }` - */ - async function runFunction( - handlers: { environment: string; elasticsearchClient: LegacyAPICaller }, - fnCall: any - ) { - const { functionName, args, context } = fnCall; - const { deserialize } = serializeProvider(registries.types.toJS()); - const fnDef = registries.serverFunctions.toJS()[functionName]; - if (!fnDef) throw Boom.notFound(`Function "${functionName}" could not be found.`); - const deserialized = deserialize(context); - const result = fnDef.fn(deserialized, args, handlers); - return result; - } - - /** - * Register an endpoint that executes a batch of functions, and streams the - * results back using ND-JSON. - */ - plugins.bfetch.addBatchProcessingRoute(`/api/interpreter/fns`, (request) => { - return { - onBatchItem: async (fnCall: any) => { - const [coreStart] = await core.getStartServices(); - const handlers = { - environment: 'server', - elasticsearchClient: coreStart.elasticsearch.legacy.client.asScoped(request) - .callAsCurrentUser, - }; - const result = await runFunction(handlers, fnCall); - if (typeof result === 'undefined') { - throw new Error(`Function ${fnCall.functionName} did not return anything.`); - } - return result; - }, - }; - }); -}; diff --git a/src/plugins/expressions/server/mocks.ts b/src/plugins/expressions/server/mocks.ts index e6b883e38f244..0512789d76ab0 100644 --- a/src/plugins/expressions/server/mocks.ts +++ b/src/plugins/expressions/server/mocks.ts @@ -20,7 +20,6 @@ import { ExpressionsServerSetup, ExpressionsServerStart } from '.'; import { plugin as pluginInitializer } from '.'; import { coreMock } from '../../../core/server/mocks'; -import { bfetchPluginMock } from '../../bfetch/server/mocks'; export type Setup = jest.Mocked; export type Start = jest.Mocked; @@ -38,10 +37,6 @@ const createSetupContract = (): Setup => { registerRenderer: jest.fn(), registerType: jest.fn(), run: jest.fn(), - __LEGACY: { - register: jest.fn(), - registries: jest.fn(), - }, }; return setupContract; }; @@ -67,9 +62,7 @@ const createPlugin = async () => { const coreSetup = coreMock.createSetup(); const coreStart = coreMock.createStart(); const plugin = pluginInitializer(pluginInitializerContext); - const setup = await plugin.setup(coreSetup, { - bfetch: bfetchPluginMock.createSetupContract(), - }); + const setup = await plugin.setup(coreSetup); return { pluginInitializerContext, @@ -77,10 +70,7 @@ const createPlugin = async () => { coreStart, plugin, setup, - doStart: async () => - await plugin.start(coreStart, { - bfetch: bfetchPluginMock.createStartContract(), - }), + doStart: async () => await plugin.start(coreStart), }; }; diff --git a/src/plugins/expressions/server/plugin.ts b/src/plugins/expressions/server/plugin.ts index b99958262c542..9e412f9b33342 100644 --- a/src/plugins/expressions/server/plugin.ts +++ b/src/plugins/expressions/server/plugin.ts @@ -17,68 +17,30 @@ * under the License. */ -import { CoreStart, PluginInitializerContext, CoreSetup, Plugin } from 'src/core/server'; -import { BfetchServerSetup, BfetchServerStart } from '../../bfetch/server'; -import { - LegacyInterpreterServerApi, - createLegacyServerInterpreterApi, - createLegacyServerEndpoints, -} from './legacy'; +import { CoreStart, CoreSetup, Plugin, PluginInitializerContext } from 'src/core/server'; import { ExpressionsService, ExpressionsServiceSetup, ExpressionsServiceStart } from '../common'; -export interface ExpressionsServerSetupDependencies { - bfetch: BfetchServerSetup; -} - -export interface ExpressionsServerStartDependencies { - bfetch: BfetchServerStart; -} - -export interface ExpressionsServerSetup extends ExpressionsServiceSetup { - __LEGACY: LegacyInterpreterServerApi; -} +export type ExpressionsServerSetup = ExpressionsServiceSetup; export type ExpressionsServerStart = ExpressionsServiceStart; export class ExpressionsServerPlugin - implements - Plugin< - ExpressionsServerSetup, - ExpressionsServerStart, - ExpressionsServerSetupDependencies, - ExpressionsServerStartDependencies - > { + implements Plugin { readonly expressions: ExpressionsService = new ExpressionsService(); - constructor(private readonly initializerContext: PluginInitializerContext) {} - - public setup( - core: CoreSetup, - plugins: ExpressionsServerSetupDependencies - ): ExpressionsServerSetup { - const logger = this.initializerContext.logger.get(); - const { expressions } = this; - const { executor } = expressions; + constructor(initializerContext: PluginInitializerContext) {} - executor.extendContext({ + public setup(core: CoreSetup): ExpressionsServerSetup { + this.expressions.executor.extendContext({ environment: 'server', }); - const legacyApi = createLegacyServerInterpreterApi(); - createLegacyServerEndpoints(legacyApi, logger, core, plugins); - - const setup = { - ...this.expressions.setup(), - __LEGACY: legacyApi, - }; + const setup = this.expressions.setup(); return Object.freeze(setup); } - public start( - core: CoreStart, - plugins: ExpressionsServerStartDependencies - ): ExpressionsServerStart { + public start(core: CoreStart): ExpressionsServerStart { const start = this.expressions.start(); return Object.freeze(start); diff --git a/src/plugins/kibana_utils/public/core/create_kibana_utils_core.test.ts b/src/plugins/kibana_utils/public/core/create_kibana_utils_core.test.ts deleted file mode 100644 index c5b23bdf0055f..0000000000000 --- a/src/plugins/kibana_utils/public/core/create_kibana_utils_core.test.ts +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { createKibanaUtilsCore } from './create_kibana_utils_core'; -import { CoreStart } from 'kibana/public'; - -describe('createKibanaUtilsCore', () => { - it('should allows to work with multiple instances', () => { - const core1 = {} as CoreStart; - const core2 = {} as CoreStart; - - const { setCoreStart: setCoreStart1, getCoreStart: getCoreStart1 } = createKibanaUtilsCore(); - const { setCoreStart: setCoreStart2, getCoreStart: getCoreStart2 } = createKibanaUtilsCore(); - - setCoreStart1(core1); - setCoreStart2(core2); - - expect(getCoreStart1()).toBe(core1); - expect(getCoreStart2()).toBe(core2); - - expect(getCoreStart1() !== getCoreStart2()).toBeTruthy(); - }); -}); diff --git a/src/plugins/kibana_utils/public/core/create_kibana_utils_core.ts b/src/plugins/kibana_utils/public/core/create_kibana_utils_core.ts deleted file mode 100644 index c528c68f29edb..0000000000000 --- a/src/plugins/kibana_utils/public/core/create_kibana_utils_core.ts +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { createGetterSetter, Get, Set } from '../../common'; -import { CoreStart } from '../../../../core/public'; -import { KUSavedObjectClient, createSavedObjectsClient } from './saved_objects_client'; - -interface Return { - getCoreStart: Get; - setCoreStart: Set; - savedObjects: KUSavedObjectClient; -} - -export const createKibanaUtilsCore = (): Return => { - const [getCoreStart, setCoreStart] = createGetterSetter('CoreStart'); - const savedObjects = createSavedObjectsClient(getCoreStart); - - return { - getCoreStart, - setCoreStart, - savedObjects, - }; -}; diff --git a/src/plugins/kibana_utils/public/core/index.ts b/src/plugins/kibana_utils/public/core/index.ts index 8bbb2129071f5..5fb557f651e3a 100644 --- a/src/plugins/kibana_utils/public/core/index.ts +++ b/src/plugins/kibana_utils/public/core/index.ts @@ -17,5 +17,4 @@ * under the License. */ -export * from './create_kibana_utils_core'; export * from './create_start_service_getter'; diff --git a/src/plugins/kibana_utils/public/core/saved_objects_client.ts b/src/plugins/kibana_utils/public/core/saved_objects_client.ts deleted file mode 100644 index 5262755a6a3ab..0000000000000 --- a/src/plugins/kibana_utils/public/core/saved_objects_client.ts +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { CoreStart } from '../../../../core/public'; -import { Get } from '../../common'; - -type CoreSavedObjectClient = CoreStart['savedObjects']['client']; - -export interface KUSavedObjectClient { - get: CoreSavedObjectClient['get']; -} - -export const createSavedObjectsClient = (getCoreStart: Get) => { - const savedObjectsClient: KUSavedObjectClient = { - get: (...args) => getCoreStart().savedObjects.client.get(...args), - }; - - return savedObjectsClient; -}; diff --git a/src/plugins/kibana_utils/public/core/state.ts b/src/plugins/kibana_utils/public/core/state.ts deleted file mode 100644 index 52c4d166d737e..0000000000000 --- a/src/plugins/kibana_utils/public/core/state.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { createGetterSetter } from '../../common'; -import { CoreStart } from '../../../../core/public'; - -export const [getCoreStart, setCoreStart] = createGetterSetter('CoreStart'); diff --git a/x-pack/plugins/canvas/public/services/stubs/expressions.ts b/x-pack/plugins/canvas/public/services/stubs/expressions.ts index ee332e20c4ca3..fd9b083964cb6 100644 --- a/x-pack/plugins/canvas/public/services/stubs/expressions.ts +++ b/x-pack/plugins/canvas/public/services/stubs/expressions.ts @@ -12,9 +12,7 @@ import { renderFunctions } from '../../../canvas_plugin_src/renderers/core'; const placeholder = {} as any; const expressionsPlugin = plugin(placeholder); -const setup = expressionsPlugin.setup(placeholder, { - inspector: {}, -} as any); +const setup = expressionsPlugin.setup(placeholder); export const expressionsService: ExpressionsService = setup.fork(); From 6376bab559f46178e0d8fabc1b3f0fe6dd0901cd Mon Sep 17 00:00:00 2001 From: Bhavya RM Date: Thu, 20 Aug 2020 12:40:18 -0400 Subject: [PATCH 02/45] adding additional tests for the awesome new nav by core ui team and checking off a flaky test' (#75494) --- test/functional/page_objects/home_page.ts | 15 +++++++++++++++ x-pack/test/accessibility/apps/home.ts | 21 +++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/test/functional/page_objects/home_page.ts b/test/functional/page_objects/home_page.ts index 2d78de49a4f94..bf0e0dd7f56f2 100644 --- a/test/functional/page_objects/home_page.ts +++ b/test/functional/page_objects/home_page.ts @@ -118,6 +118,21 @@ export function HomePageProvider({ getService, getPageObjects }: FtrProviderCont await testSubjects.click('onCloudTutorial'); } + // click on side nav toggle button to see all of side nav + async clickOnToggleNavButton() { + await testSubjects.click('toggleNavButton'); + } + + // collapse the observability side nav details + async collapseObservabibilitySideNav() { + await testSubjects.click('collapsibleNavGroup-observability'); + } + + // dock the side nav + async dockTheSideNav() { + await testSubjects.click('collapsible-nav-lock'); + } + async loadSavedObjects() { await retry.try(async () => { await testSubjects.click('loadSavedObjects'); diff --git a/x-pack/test/accessibility/apps/home.ts b/x-pack/test/accessibility/apps/home.ts index 1f05ff676e3a0..6018c4da2ddff 100644 --- a/x-pack/test/accessibility/apps/home.ts +++ b/x-pack/test/accessibility/apps/home.ts @@ -68,5 +68,26 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.home.clickOnCloudTutorial(); await a11y.testAppSnapshot(); }); + + it('click on side nav to see all the side nav menu', async () => { + await PageObjects.home.clickOnLogo(); + await PageObjects.home.clickOnToggleNavButton(); + await a11y.testAppSnapshot(); + }); + + it('Dock the side nav', async () => { + await PageObjects.home.dockTheSideNav(); + await a11y.testAppSnapshot(); + }); + + it('click on collapse on observability in side nav to test a11y of collapse button', async () => { + await PageObjects.home.collapseObservabibilitySideNav(); + await a11y.testAppSnapshot(); + }); + + it('unDock the side nav', async () => { + await PageObjects.home.dockTheSideNav(); + await a11y.testAppSnapshot(); + }); }); } From 7699f1c29a54d5665fb8324c2e1b23c95604fe4f Mon Sep 17 00:00:00 2001 From: Constance Date: Thu, 20 Aug 2020 09:41:43 -0700 Subject: [PATCH 03/45] [Enterprise Search][bug/tech debt] Fix route navigation (#75369) * Set up navigateToUrl context * Update RR link helpers to use navigateToUrl * Update breadcrumbs to use navigateToUrl + refactor generate_breadcrumbs: - Change base breadcrumb generator to a custom React useHook instead of passing history/context around - Change use{Product}Breadcrumbs helpers to mainly involve merging arrays - Update + simplify tests accordingly (test link behavior in main useBreadcrumb suite, not in subsequent helpers) set_chrome: - Update to use new breadcrumb hooks (requires pulling out of useEffect, hooks can't be used inside another hook) - Clean up/refactor tests * Update route redirects now that navigation works correctly --- .../__mocks__/kibana_context.mock.ts | 1 + .../public/applications/app_search/index.tsx | 4 +- .../public/applications/index.tsx | 10 +- .../generate_breadcrumbs.test.ts | 246 +++++++----------- .../kibana_chrome/generate_breadcrumbs.ts | 61 +++-- .../shared/kibana_chrome/set_chrome.test.tsx | 99 ++++--- .../shared/kibana_chrome/set_chrome.tsx | 23 +- .../react_router_helpers/eui_link.test.tsx | 10 +- .../shared/react_router_helpers/eui_link.tsx | 14 +- .../applications/workplace_search/index.tsx | 1 - 10 files changed, 209 insertions(+), 260 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/kibana_context.mock.ts b/x-pack/plugins/enterprise_search/public/applications/__mocks__/kibana_context.mock.ts index ef3bf54053b5c..890072ab42eb9 100644 --- a/x-pack/plugins/enterprise_search/public/applications/__mocks__/kibana_context.mock.ts +++ b/x-pack/plugins/enterprise_search/public/applications/__mocks__/kibana_context.mock.ts @@ -13,6 +13,7 @@ import { ExternalUrl } from '../shared/enterprise_search_url'; */ export const mockKibanaContext = { http: httpServiceMock.createSetupContract(), + navigateToUrl: jest.fn(), setBreadcrumbs: jest.fn(), setDocTitle: jest.fn(), config: { host: 'http://localhost:3002' }, diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx index 7ebd35ff35ee1..5856a13bf75b7 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx @@ -36,7 +36,6 @@ export const AppSearch: React.FC = () => { - {/* Kibana displays a blank page on redirect if this isn't included */} ); @@ -50,8 +49,7 @@ export const AppSearch: React.FC = () => { }> - {/* For some reason a Redirect to /engines just doesn't work here - it shows a blank page */} - + diff --git a/x-pack/plugins/enterprise_search/public/applications/index.tsx b/x-pack/plugins/enterprise_search/public/applications/index.tsx index f3ccbc126ae62..1b1f9ae43e7c1 100644 --- a/x-pack/plugins/enterprise_search/public/applications/index.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/index.tsx @@ -9,7 +9,13 @@ import ReactDOM from 'react-dom'; import { Router } from 'react-router-dom'; import { I18nProvider } from '@kbn/i18n/react'; -import { CoreStart, AppMountParameters, HttpSetup, ChromeBreadcrumb } from 'src/core/public'; +import { + AppMountParameters, + CoreStart, + ApplicationStart, + HttpSetup, + ChromeBreadcrumb, +} from 'src/core/public'; import { ClientConfigType, ClientData, PluginsSetup } from '../plugin'; import { LicenseProvider } from './shared/licensing'; import { IExternalUrl } from './shared/enterprise_search_url'; @@ -18,6 +24,7 @@ export interface IKibanaContext { config: { host?: string }; externalUrl: IExternalUrl; http: HttpSetup; + navigateToUrl: ApplicationStart['navigateToUrl']; setBreadcrumbs(crumbs: ChromeBreadcrumb[]): void; setDocTitle(title: string): void; } @@ -44,6 +51,7 @@ export const renderApp = ( value={{ config, http: core.http, + navigateToUrl: core.application.navigateToUrl, externalUrl: data.externalUrl, setBreadcrumbs: core.chrome.setBreadcrumbs, setDocTitle: core.chrome.docTitle.change, diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.test.ts b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.test.ts index 0f34bbb6b65bc..9e86b239432a7 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.test.ts @@ -4,140 +4,121 @@ * you may not use this file except in compliance with the Elastic License. */ -import { - generateBreadcrumb, - appSearchBreadcrumbs, - enterpriseSearchBreadcrumbs, - workplaceSearchBreadcrumbs, -} from './generate_breadcrumbs'; - -import { mockHistory as mockHistoryUntyped } from '../../__mocks__'; -const mockHistory = mockHistoryUntyped as any; +import '../../__mocks__/shallow_usecontext.mock'; +import '../../__mocks__/react_router_history.mock'; +import { mockKibanaContext, mockHistory } from '../../__mocks__'; jest.mock('../react_router_helpers', () => ({ letBrowserHandleEvent: jest.fn(() => false) })); import { letBrowserHandleEvent } from '../react_router_helpers'; -describe('generateBreadcrumb', () => { +import { + useBreadcrumbs, + useEnterpriseSearchBreadcrumbs, + useAppSearchBreadcrumbs, + useWorkplaceSearchBreadcrumbs, +} from './generate_breadcrumbs'; + +describe('useBreadcrumbs', () => { beforeEach(() => { jest.clearAllMocks(); }); - it("creates a breadcrumb object matching EUI's breadcrumb type", () => { - const breadcrumb = generateBreadcrumb({ - text: 'Hello World', - path: '/hello_world', - history: mockHistory, - }); - expect(breadcrumb).toEqual({ - text: 'Hello World', - href: '/enterprise_search/hello_world', - onClick: expect.any(Function), - }); + it('accepts an array of breadcrumbs and to the array correctly injects SPA link navigation props', () => { + const breadcrumb = useBreadcrumbs([ + { + text: 'Hello', + path: '/hello', + }, + { + text: 'World', + path: '/world', + }, + ]); + expect(breadcrumb).toEqual([ + { + text: 'Hello', + href: '/enterprise_search/hello', + onClick: expect.any(Function), + }, + { + text: 'World', + href: '/enterprise_search/world', + onClick: expect.any(Function), + }, + ]); }); it('prevents default navigation and uses React Router history on click', () => { - const breadcrumb = generateBreadcrumb({ text: '', path: '/', history: mockHistory }) as any; + const breadcrumb = useBreadcrumbs([{ text: '', path: '/' }])[0] as any; const event = { preventDefault: jest.fn() }; breadcrumb.onClick(event); - expect(mockHistory.push).toHaveBeenCalled(); + expect(mockKibanaContext.navigateToUrl).toHaveBeenCalled(); + expect(mockHistory.createHref).toHaveBeenCalled(); expect(event.preventDefault).toHaveBeenCalled(); }); it('does not prevent default browser behavior on new tab/window clicks', () => { - const breadcrumb = generateBreadcrumb({ text: '', path: '/', history: mockHistory }) as any; + const breadcrumb = useBreadcrumbs([{ text: '', path: '/' }])[0] as any; (letBrowserHandleEvent as jest.Mock).mockImplementationOnce(() => true); breadcrumb.onClick(); - expect(mockHistory.push).not.toHaveBeenCalled(); + expect(mockKibanaContext.navigateToUrl).not.toHaveBeenCalled(); }); it('does not generate link behavior if path is excluded', () => { - const breadcrumb = generateBreadcrumb({ text: 'Unclickable breadcrumb' }); + const breadcrumb = useBreadcrumbs([{ text: 'Unclickable breadcrumb' }])[0]; expect(breadcrumb.href).toBeUndefined(); expect(breadcrumb.onClick).toBeUndefined(); }); }); -describe('enterpriseSearchBreadcrumbs', () => { - const breadCrumbs = [ - { - text: 'Page 1', - path: '/page1', - }, - { - text: 'Page 2', - path: '/page2', - }, - ]; - +describe('useEnterpriseSearchBreadcrumbs', () => { beforeEach(() => { jest.clearAllMocks(); }); - const subject = () => enterpriseSearchBreadcrumbs(mockHistory)(breadCrumbs); + it('builds a chain of breadcrumbs with Enterprise Search at the root', () => { + const breadcrumbs = [ + { + text: 'Page 1', + path: '/page1', + }, + { + text: 'Page 2', + path: '/page2', + }, + ]; - it('Builds a chain of breadcrumbs with Enterprise Search at the root', () => { - expect(subject()).toEqual([ + expect(useEnterpriseSearchBreadcrumbs(breadcrumbs)).toEqual([ { text: 'Enterprise Search', }, { + text: 'Page 1', href: '/enterprise_search/page1', onClick: expect.any(Function), - text: 'Page 1', }, { + text: 'Page 2', href: '/enterprise_search/page2', onClick: expect.any(Function), - text: 'Page 2', }, ]); }); it('shows just the root if breadcrumbs is empty', () => { - expect(enterpriseSearchBreadcrumbs(mockHistory)()).toEqual([ + expect(useEnterpriseSearchBreadcrumbs()).toEqual([ { text: 'Enterprise Search', }, ]); }); - - describe('links', () => { - const eventMock = { - preventDefault: jest.fn(), - } as any; - - it('has Enterprise Search text first', () => { - expect(subject()[0].onClick).toBeUndefined(); - }); - - it('has a link to page 1 second', () => { - (subject()[1] as any).onClick(eventMock); - expect(mockHistory.push).toHaveBeenCalledWith('/page1'); - }); - - it('has a link to page 2 last', () => { - (subject()[2] as any).onClick(eventMock); - expect(mockHistory.push).toHaveBeenCalledWith('/page2'); - }); - }); }); -describe('appSearchBreadcrumbs', () => { - const breadCrumbs = [ - { - text: 'Page 1', - path: '/page1', - }, - { - text: 'Page 2', - path: '/page2', - }, - ]; - +describe('useAppSearchBreadcrumbs', () => { beforeEach(() => { jest.clearAllMocks(); mockHistory.createHref.mockImplementation( @@ -145,82 +126,55 @@ describe('appSearchBreadcrumbs', () => { ); }); - const subject = () => appSearchBreadcrumbs(mockHistory)(breadCrumbs); - it('Builds a chain of breadcrumbs with Enterprise Search and App Search at the root', () => { - expect(subject()).toEqual([ + const breadcrumbs = [ + { + text: 'Page 1', + path: '/page1', + }, + { + text: 'Page 2', + path: '/page2', + }, + ]; + + expect(useAppSearchBreadcrumbs(breadcrumbs)).toEqual([ { text: 'Enterprise Search', }, { + text: 'App Search', href: '/enterprise_search/app_search/', onClick: expect.any(Function), - text: 'App Search', }, { + text: 'Page 1', href: '/enterprise_search/app_search/page1', onClick: expect.any(Function), - text: 'Page 1', }, { + text: 'Page 2', href: '/enterprise_search/app_search/page2', onClick: expect.any(Function), - text: 'Page 2', }, ]); }); it('shows just the root if breadcrumbs is empty', () => { - expect(appSearchBreadcrumbs(mockHistory)()).toEqual([ + expect(useAppSearchBreadcrumbs()).toEqual([ { text: 'Enterprise Search', }, { + text: 'App Search', href: '/enterprise_search/app_search/', onClick: expect.any(Function), - text: 'App Search', }, ]); }); - - describe('links', () => { - const eventMock = { - preventDefault: jest.fn(), - } as any; - - it('has Enterprise Search text first', () => { - expect(subject()[0].onClick).toBeUndefined(); - }); - - it('has a link to App Search second', () => { - (subject()[1] as any).onClick(eventMock); - expect(mockHistory.push).toHaveBeenCalledWith('/'); - }); - - it('has a link to page 1 third', () => { - (subject()[2] as any).onClick(eventMock); - expect(mockHistory.push).toHaveBeenCalledWith('/page1'); - }); - - it('has a link to page 2 last', () => { - (subject()[3] as any).onClick(eventMock); - expect(mockHistory.push).toHaveBeenCalledWith('/page2'); - }); - }); }); -describe('workplaceSearchBreadcrumbs', () => { - const breadCrumbs = [ - { - text: 'Page 1', - path: '/page1', - }, - { - text: 'Page 2', - path: '/page2', - }, - ]; - +describe('useWorkplaceSearchBreadcrumbs', () => { beforeEach(() => { jest.clearAllMocks(); mockHistory.createHref.mockImplementation( @@ -228,66 +182,50 @@ describe('workplaceSearchBreadcrumbs', () => { ); }); - const subject = () => workplaceSearchBreadcrumbs(mockHistory)(breadCrumbs); - it('Builds a chain of breadcrumbs with Enterprise Search and Workplace Search at the root', () => { - expect(subject()).toEqual([ + const breadcrumbs = [ + { + text: 'Page 1', + path: '/page1', + }, + { + text: 'Page 2', + path: '/page2', + }, + ]; + + expect(useWorkplaceSearchBreadcrumbs(breadcrumbs)).toEqual([ { text: 'Enterprise Search', }, { + text: 'Workplace Search', href: '/enterprise_search/workplace_search/', onClick: expect.any(Function), - text: 'Workplace Search', }, { + text: 'Page 1', href: '/enterprise_search/workplace_search/page1', onClick: expect.any(Function), - text: 'Page 1', }, { + text: 'Page 2', href: '/enterprise_search/workplace_search/page2', onClick: expect.any(Function), - text: 'Page 2', }, ]); }); it('shows just the root if breadcrumbs is empty', () => { - expect(workplaceSearchBreadcrumbs(mockHistory)()).toEqual([ + expect(useWorkplaceSearchBreadcrumbs()).toEqual([ { text: 'Enterprise Search', }, { + text: 'Workplace Search', href: '/enterprise_search/workplace_search/', onClick: expect.any(Function), - text: 'Workplace Search', }, ]); }); - - describe('links', () => { - const eventMock = { - preventDefault: jest.fn(), - } as any; - - it('has Enterprise Search text first', () => { - expect(subject()[0].onClick).toBeUndefined(); - }); - - it('has a link to Workplace Search second', () => { - (subject()[1] as any).onClick(eventMock); - expect(mockHistory.push).toHaveBeenCalledWith('/'); - }); - - it('has a link to page 1 third', () => { - (subject()[2] as any).onClick(eventMock); - expect(mockHistory.push).toHaveBeenCalledWith('/page1'); - }); - - it('has a link to page 2 last', () => { - (subject()[3] as any).onClick(eventMock); - expect(mockHistory.push).toHaveBeenCalledWith('/page2'); - }); - }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.ts b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.ts index 82c0f78fb853f..6eab936719d01 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.ts @@ -4,8 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ +import { useContext } from 'react'; +import { useHistory } from 'react-router-dom'; import { EuiBreadcrumb } from '@elastic/eui'; -import { History } from 'history'; + +import { KibanaContext, IKibanaContext } from '../../index'; import { ENTERPRISE_SEARCH_PLUGIN, @@ -20,50 +23,46 @@ import { letBrowserHandleEvent } from '../react_router_helpers'; * https://elastic.github.io/eui/#/navigation/breadcrumbs */ -interface IGenerateBreadcrumbProps { +interface IBreadcrumb { text: string; path?: string; - history?: History; } +export type TBreadcrumbs = IBreadcrumb[]; + +export const useBreadcrumbs = (breadcrumbs: TBreadcrumbs) => { + const history = useHistory(); + const { navigateToUrl } = useContext(KibanaContext) as IKibanaContext; + + return breadcrumbs.map(({ text, path }) => { + const breadcrumb = { text } as EuiBreadcrumb; -export const generateBreadcrumb = ({ text, path, history }: IGenerateBreadcrumbProps) => { - const breadcrumb = { text } as EuiBreadcrumb; + if (path) { + const href = history.createHref({ pathname: path }) as string; - if (path && history) { - breadcrumb.href = history.createHref({ pathname: path }); - breadcrumb.onClick = (event) => { - if (letBrowserHandleEvent(event)) return; - event.preventDefault(); - history.push(path); - }; - } + breadcrumb.href = href; + breadcrumb.onClick = (event) => { + if (letBrowserHandleEvent(event)) return; + event.preventDefault(); + navigateToUrl(href); + }; + } - return breadcrumb; + return breadcrumb; + }); }; /** * Product-specific breadcrumb helpers */ -export type TBreadcrumbs = IGenerateBreadcrumbProps[]; +export const useEnterpriseSearchBreadcrumbs = (breadcrumbs: TBreadcrumbs = []) => + useBreadcrumbs([{ text: ENTERPRISE_SEARCH_PLUGIN.NAME }, ...breadcrumbs]); -export const enterpriseSearchBreadcrumbs = (history: History) => ( - breadcrumbs: TBreadcrumbs = [] -) => [ - generateBreadcrumb({ text: ENTERPRISE_SEARCH_PLUGIN.NAME }), - ...breadcrumbs.map(({ text, path }: IGenerateBreadcrumbProps) => - generateBreadcrumb({ text, path, history }) - ), -]; - -export const appSearchBreadcrumbs = (history: History) => (breadcrumbs: TBreadcrumbs = []) => - enterpriseSearchBreadcrumbs(history)([ - { text: APP_SEARCH_PLUGIN.NAME, path: '/' }, - ...breadcrumbs, - ]); +export const useAppSearchBreadcrumbs = (breadcrumbs: TBreadcrumbs = []) => + useEnterpriseSearchBreadcrumbs([{ text: APP_SEARCH_PLUGIN.NAME, path: '/' }, ...breadcrumbs]); -export const workplaceSearchBreadcrumbs = (history: History) => (breadcrumbs: TBreadcrumbs = []) => - enterpriseSearchBreadcrumbs(history)([ +export const useWorkplaceSearchBreadcrumbs = (breadcrumbs: TBreadcrumbs = []) => + useEnterpriseSearchBreadcrumbs([ { text: WORKPLACE_SEARCH_PLUGIN.NAME, path: '/' }, ...breadcrumbs, ]); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.test.tsx index aba0b250e56c0..bda816c9a5554 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.test.tsx @@ -4,16 +4,18 @@ * you may not use this file except in compliance with the Elastic License. */ +import '../../__mocks__/shallow_usecontext.mock'; +import '../../__mocks__/react_router_history.mock'; + import React from 'react'; -import '../../__mocks__/react_router_history.mock'; import { mockKibanaContext, mountWithKibanaContext } from '../../__mocks__'; jest.mock('./generate_breadcrumbs', () => ({ - appSearchBreadcrumbs: jest.fn(() => (crumbs: any) => crumbs), - workplaceSearchBreadcrumbs: jest.fn(() => (crumbs: any) => crumbs), + useAppSearchBreadcrumbs: jest.fn(() => (crumbs: any) => crumbs), + useWorkplaceSearchBreadcrumbs: jest.fn(() => (crumbs: any) => crumbs), })); -import { appSearchBreadcrumbs, workplaceSearchBreadcrumbs } from './generate_breadcrumbs'; +import { useAppSearchBreadcrumbs, useWorkplaceSearchBreadcrumbs } from './generate_breadcrumbs'; jest.mock('./generate_title', () => ({ appSearchTitle: jest.fn((title: any) => title), @@ -23,62 +25,55 @@ import { appSearchTitle, workplaceSearchTitle } from './generate_title'; import { SetAppSearchChrome, SetWorkplaceSearchChrome } from './'; -describe('SetAppSearchChrome', () => { +describe('Set Kibana Chrome helpers', () => { beforeEach(() => { jest.clearAllMocks(); }); afterEach(() => { - expect(appSearchBreadcrumbs).toHaveBeenCalled(); - expect(appSearchTitle).toHaveBeenCalled(); - }); - - it('sets breadcrumbs and document title', () => { - mountWithKibanaContext(); - - expect(mockKibanaContext.setBreadcrumbs).toHaveBeenCalledWith([ - { - text: 'Engines', - path: '/current-path', - }, - ]); - expect(mockKibanaContext.setDocTitle).toHaveBeenCalledWith(['Engines']); + expect(mockKibanaContext.setBreadcrumbs).toHaveBeenCalled(); + expect(mockKibanaContext.setDocTitle).toHaveBeenCalled(); }); - it('sets empty breadcrumbs and document title when isRoot is true', () => { - mountWithKibanaContext(); - - expect(mockKibanaContext.setBreadcrumbs).toHaveBeenCalledWith([]); - expect(mockKibanaContext.setDocTitle).toHaveBeenCalledWith([]); + describe('SetAppSearchChrome', () => { + it('sets breadcrumbs and document title', () => { + mountWithKibanaContext(); + + expect(appSearchTitle).toHaveBeenCalledWith(['Engines']); + expect(useAppSearchBreadcrumbs).toHaveBeenCalledWith([ + { + text: 'Engines', + path: '/current-path', + }, + ]); + }); + + it('sets empty breadcrumbs and document title when isRoot is true', () => { + mountWithKibanaContext(); + + expect(appSearchTitle).toHaveBeenCalledWith([]); + expect(useAppSearchBreadcrumbs).toHaveBeenCalledWith([]); + }); }); -}); - -describe('SetWorkplaceSearchChrome', () => { - beforeEach(() => { - jest.clearAllMocks(); - }); - - afterEach(() => { - expect(workplaceSearchBreadcrumbs).toHaveBeenCalled(); - expect(workplaceSearchTitle).toHaveBeenCalled(); - }); - - it('sets breadcrumbs and document title', () => { - mountWithKibanaContext(); - - expect(mockKibanaContext.setBreadcrumbs).toHaveBeenCalledWith([ - { - text: 'Sources', - path: '/current-path', - }, - ]); - expect(mockKibanaContext.setDocTitle).toHaveBeenCalledWith(['Sources']); - }); - - it('sets empty breadcrumbs and document title when isRoot is true', () => { - mountWithKibanaContext(); - expect(mockKibanaContext.setBreadcrumbs).toHaveBeenCalledWith([]); - expect(mockKibanaContext.setDocTitle).toHaveBeenCalledWith([]); + describe('SetWorkplaceSearchChrome', () => { + it('sets breadcrumbs and document title', () => { + mountWithKibanaContext(); + + expect(workplaceSearchTitle).toHaveBeenCalledWith(['Sources']); + expect(useWorkplaceSearchBreadcrumbs).toHaveBeenCalledWith([ + { + text: 'Sources', + path: '/current-path', + }, + ]); + }); + + it('sets empty breadcrumbs and document title when isRoot is true', () => { + mountWithKibanaContext(); + + expect(workplaceSearchTitle).toHaveBeenCalledWith([]); + expect(useWorkplaceSearchBreadcrumbs).toHaveBeenCalledWith([]); + }); }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.tsx index 59e83a2cb13c2..43db93c1583d1 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.tsx @@ -7,10 +7,11 @@ import React, { useContext, useEffect } from 'react'; import { useHistory } from 'react-router-dom'; import { EuiBreadcrumb } from '@elastic/eui'; + import { KibanaContext, IKibanaContext } from '../../index'; import { - appSearchBreadcrumbs, - workplaceSearchBreadcrumbs, + useAppSearchBreadcrumbs, + useWorkplaceSearchBreadcrumbs, TBreadcrumbs, } from './generate_breadcrumbs'; import { appSearchTitle, workplaceSearchTitle, TTitle } from './generate_title'; @@ -36,12 +37,15 @@ export const SetAppSearchChrome: React.FC = ({ text, isRoot } const history = useHistory(); const { setBreadcrumbs, setDocTitle } = useContext(KibanaContext) as IKibanaContext; - const crumb = isRoot ? [] : [{ text, path: history.location.pathname }]; const title = isRoot ? [] : [text]; + const docTitle = appSearchTitle(title as TTitle | []); + + const crumb = isRoot ? [] : [{ text, path: history.location.pathname }]; + const breadcrumbs = useAppSearchBreadcrumbs(crumb as TBreadcrumbs | []); useEffect(() => { - setBreadcrumbs(appSearchBreadcrumbs(history)(crumb as TBreadcrumbs | [])); - setDocTitle(appSearchTitle(title as TTitle | [])); + setBreadcrumbs(breadcrumbs); + setDocTitle(docTitle); }, []); return null; @@ -51,12 +55,15 @@ export const SetWorkplaceSearchChrome: React.FC = ({ text, is const history = useHistory(); const { setBreadcrumbs, setDocTitle } = useContext(KibanaContext) as IKibanaContext; - const crumb = isRoot ? [] : [{ text, path: history.location.pathname }]; const title = isRoot ? [] : [text]; + const docTitle = workplaceSearchTitle(title as TTitle | []); + + const crumb = isRoot ? [] : [{ text, path: history.location.pathname }]; + const breadcrumbs = useWorkplaceSearchBreadcrumbs(crumb as TBreadcrumbs | []); useEffect(() => { - setBreadcrumbs(workplaceSearchBreadcrumbs(history)(crumb as TBreadcrumbs | [])); - setDocTitle(workplaceSearchTitle(title as TTitle | [])); + setBreadcrumbs(breadcrumbs); + setDocTitle(docTitle); }, []); return null; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_link.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_link.test.tsx index 76ee8293f2c8b..063118f94cd19 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_link.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_link.test.tsx @@ -4,12 +4,14 @@ * you may not use this file except in compliance with the Elastic License. */ +import '../../__mocks__/shallow_usecontext.mock'; +import '../../__mocks__/react_router_history.mock'; + import React from 'react'; import { shallow, mount } from 'enzyme'; import { EuiLink, EuiButton } from '@elastic/eui'; -import '../../__mocks__/react_router_history.mock'; -import { mockHistory } from '../../__mocks__'; +import { mockKibanaContext, mockHistory } from '../../__mocks__'; import { EuiReactRouterLink, EuiReactRouterButton } from './eui_link'; @@ -59,7 +61,7 @@ describe('EUI & React Router Component Helpers', () => { wrapper.find(EuiLink).simulate('click', simulatedEvent); expect(simulatedEvent.preventDefault).toHaveBeenCalled(); - expect(mockHistory.push).toHaveBeenCalled(); + expect(mockKibanaContext.navigateToUrl).toHaveBeenCalled(); }); it('does not prevent default browser behavior on new tab/window clicks', () => { @@ -71,7 +73,7 @@ describe('EUI & React Router Component Helpers', () => { }; wrapper.find(EuiLink).simulate('click', simulatedEvent); - expect(mockHistory.push).not.toHaveBeenCalled(); + expect(mockKibanaContext.navigateToUrl).not.toHaveBeenCalled(); }); it('calls inherited onClick actions in addition to default navigation', () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_link.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_link.tsx index b53b2f2b3b650..7221a61d0997b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_link.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_link.tsx @@ -4,10 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ -import React from 'react'; +import React, { useContext } from 'react'; import { useHistory } from 'react-router-dom'; import { EuiLink, EuiButton, EuiButtonProps, EuiLinkAnchorProps } from '@elastic/eui'; +import { KibanaContext, IKibanaContext } from '../../index'; import { letBrowserHandleEvent } from './link_events'; /** @@ -24,6 +25,10 @@ interface IEuiReactRouterProps { export const EuiReactRouterHelper: React.FC = ({ to, onClick, children }) => { const history = useHistory(); + const { navigateToUrl } = useContext(KibanaContext) as IKibanaContext; + + // Generate the correct link href (with basename etc. accounted for) + const href = history.createHref({ pathname: to }); const reactRouterLinkClick = (event: React.MouseEvent) => { if (onClick) onClick(); // Run any passed click events (e.g. telemetry) @@ -32,13 +37,10 @@ export const EuiReactRouterHelper: React.FC = ({ to, onCli // Prevent regular link behavior, which causes a browser refresh. event.preventDefault(); - // Push the route to the history. - history.push(to); + // Perform SPA navigation. + navigateToUrl(href); }; - // Generate the correct link href (with basename etc. accounted for) - const href = history.createHref({ pathname: to }); - const reactRouterProps = { href, onClick: reactRouterLinkClick }; return React.cloneElement(children as React.ReactElement, reactRouterProps); }; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.tsx index ca0d395c0d673..4aa171a5a5762 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.tsx @@ -33,7 +33,6 @@ export const WorkplaceSearch: React.FC = () => { - {/* Kibana displays a blank page on redirect if this isn't included */} ); From eba482743adce2661d5814cff1e6539730d1e830 Mon Sep 17 00:00:00 2001 From: Devon Thomson Date: Thu, 20 Aug 2020 13:01:25 -0400 Subject: [PATCH 04/45] [Dashboard First] Use App Title for Display Instead of App Id (#75457) Created app title fetch method in embeddable_state_transfer. Used it instead of the raw app id in a number of places. --- .../embeddable_state_transfer.test.ts | 25 ++++++++++++++++++- .../embeddable_state_transfer.ts | 16 ++++++++++-- src/plugins/embeddable/public/plugin.tsx | 23 ++++++++++++++--- .../saved_object_save_modal_origin.tsx | 12 ++++----- .../components/visualize_top_nav.tsx | 3 +++ .../application/utils/get_top_nav_config.tsx | 11 +++++--- x-pack/plugins/lens/public/app_plugin/app.tsx | 3 +++ .../lens/public/app_plugin/mounter.tsx | 1 + .../routes/maps_app/top_nav_config.tsx | 1 + 9 files changed, 78 insertions(+), 17 deletions(-) diff --git a/src/plugins/embeddable/public/lib/state_transfer/embeddable_state_transfer.test.ts b/src/plugins/embeddable/public/lib/state_transfer/embeddable_state_transfer.test.ts index 42adb9d770e8a..ef79b18acd4f5 100644 --- a/src/plugins/embeddable/public/lib/state_transfer/embeddable_state_transfer.test.ts +++ b/src/plugins/embeddable/public/lib/state_transfer/embeddable_state_transfer.test.ts @@ -19,7 +19,7 @@ import { coreMock, scopedHistoryMock } from '../../../../../core/public/mocks'; import { EmbeddableStateTransfer } from '.'; -import { ApplicationStart } from '../../../../../core/public'; +import { ApplicationStart, PublicAppInfo } from '../../../../../core/public'; function mockHistoryState(state: unknown) { return scopedHistoryMock.create({ state }); @@ -37,6 +37,29 @@ describe('embeddable state transfer', () => { stateTransfer = new EmbeddableStateTransfer(application.navigateToApp); }); + it('cannot fetch app name when given no app list', async () => { + expect(stateTransfer.getAppNameFromId('test')).toBeUndefined(); + }); + + it('cannot fetch app name when app id is not in given app list', async () => { + const appsList = new Map([ + ['testId', { title: 'State Transfer Test App Hello' } as PublicAppInfo], + ['testId2', { title: 'State Transfer Test App Goodbye' } as PublicAppInfo], + ]); + stateTransfer = new EmbeddableStateTransfer(application.navigateToApp, undefined, appsList); + expect(stateTransfer.getAppNameFromId('kibanana')).toBeUndefined(); + }); + + it('can fetch app titles when given app list', async () => { + const appsList = new Map([ + ['testId', { title: 'State Transfer Test App Hello' } as PublicAppInfo], + ['testId2', { title: 'State Transfer Test App Goodbye' } as PublicAppInfo], + ]); + stateTransfer = new EmbeddableStateTransfer(application.navigateToApp, undefined, appsList); + expect(stateTransfer.getAppNameFromId('testId')).toBe('State Transfer Test App Hello'); + expect(stateTransfer.getAppNameFromId('testId2')).toBe('State Transfer Test App Goodbye'); + }); + it('can send an outgoing originating app state', async () => { await stateTransfer.navigateToEditor(destinationApp, { state: { originatingApp } }); expect(application.navigateToApp).toHaveBeenCalledWith('superUltraVisualize', { diff --git a/src/plugins/embeddable/public/lib/state_transfer/embeddable_state_transfer.ts b/src/plugins/embeddable/public/lib/state_transfer/embeddable_state_transfer.ts index 8f70e5a66c478..780cff9f4be7e 100644 --- a/src/plugins/embeddable/public/lib/state_transfer/embeddable_state_transfer.ts +++ b/src/plugins/embeddable/public/lib/state_transfer/embeddable_state_transfer.ts @@ -18,7 +18,12 @@ */ import { cloneDeep } from 'lodash'; -import { ScopedHistory, ApplicationStart } from '../../../../../core/public'; +import { + ScopedHistory, + ApplicationStart, + PublicLegacyAppInfo, + PublicAppInfo, +} from '../../../../../core/public'; import { EmbeddableEditorState, isEmbeddableEditorState, @@ -35,9 +40,16 @@ import { export class EmbeddableStateTransfer { constructor( private navigateToApp: ApplicationStart['navigateToApp'], - private scopedHistory?: ScopedHistory + private scopedHistory?: ScopedHistory, + private appList?: ReadonlyMap | undefined ) {} + /** + * Fetches an internationalized app title when given an appId. + * @param appId - The id of the app to fetch the title for + */ + public getAppNameFromId = (appId: string): string | undefined => this.appList?.get(appId)?.title; + /** * Fetches an {@link EmbeddableEditorState | originating app} argument from the scoped * history's location state. diff --git a/src/plugins/embeddable/public/plugin.tsx b/src/plugins/embeddable/public/plugin.tsx index 3cbd49279564f..fb09729ab71c3 100644 --- a/src/plugins/embeddable/public/plugin.tsx +++ b/src/plugins/embeddable/public/plugin.tsx @@ -17,6 +17,7 @@ * under the License. */ import React from 'react'; +import { Subscription } from 'rxjs'; import { DataPublicPluginSetup, DataPublicPluginStart } from '../../data/public'; import { getSavedObjectFinder } from '../../saved_objects/public'; import { UiActionsSetup, UiActionsStart } from '../../ui_actions/public'; @@ -27,6 +28,8 @@ import { CoreStart, Plugin, ScopedHistory, + PublicAppInfo, + PublicLegacyAppInfo, } from '../../../core/public'; import { EmbeddableFactoryRegistry, EmbeddableFactoryProvider } from './types'; import { bootstrap } from './bootstrap'; @@ -89,6 +92,8 @@ export class EmbeddablePublicPlugin implements Plugin; + private appListSubscription?: Subscription; constructor(initializerContext: PluginInitializerContext) {} @@ -121,7 +126,15 @@ export class EmbeddablePublicPlugin implements Plugin { + this.appList = appList; + }); + + this.outgoingOnlyStateTransfer = new EmbeddableStateTransfer( + core.application.navigateToApp, + undefined, + this.appList + ); this.isRegistryReady = true; const getEmbeddablePanelHoc = (stateTransfer?: EmbeddableStateTransfer) => ({ @@ -151,7 +164,7 @@ export class EmbeddablePublicPlugin implements Plugin { return history - ? new EmbeddableStateTransfer(core.application.navigateToApp, history) + ? new EmbeddableStateTransfer(core.application.navigateToApp, history, this.appList) : this.outgoingOnlyStateTransfer; }, EmbeddablePanel: getEmbeddablePanelHoc(), @@ -159,7 +172,11 @@ export class EmbeddablePublicPlugin implements Plugin { this.ensureFactoriesExist(); diff --git a/src/plugins/saved_objects/public/save_modal/saved_object_save_modal_origin.tsx b/src/plugins/saved_objects/public/save_modal/saved_object_save_modal_origin.tsx index 63863b0826f11..ce08151d37c2c 100644 --- a/src/plugins/saved_objects/public/save_modal/saved_object_save_modal_origin.tsx +++ b/src/plugins/saved_objects/public/save_modal/saved_object_save_modal_origin.tsx @@ -32,6 +32,7 @@ interface SaveModalDocumentInfo { interface OriginSaveModalProps { originatingApp?: string; + getAppNameFromId?: (appId: string) => string | undefined; documentInfo: SaveModalDocumentInfo; objectType: string; onClose: () => void; @@ -53,16 +54,13 @@ export function SavedObjectSaveModalOrigin(props: OriginSaveModalProps) { if (!props.originatingApp) { return; } - let origin = props.originatingApp!; - - // TODO: Remove this after https://github.com/elastic/kibana/pull/63443 - if (origin.startsWith('kibana:')) { - origin = origin.split(':')[1]; - } + const origin = props.getAppNameFromId + ? props.getAppNameFromId(props.originatingApp) || props.originatingApp + : props.originatingApp; if ( !state.copyOnSave || - origin === 'dashboards' // dashboard supports adding a copied panel on save... + props.originatingApp === 'dashboards' // dashboard supports adding a copied panel on save... ) { const originVerb = !documentInfo.id || state.copyOnSave ? addLabel : returnLabel; return ( diff --git a/src/plugins/visualize/public/application/components/visualize_top_nav.tsx b/src/plugins/visualize/public/application/components/visualize_top_nav.tsx index 12a3d1cdf95b1..130561b6245ae 100644 --- a/src/plugins/visualize/public/application/components/visualize_top_nav.tsx +++ b/src/plugins/visualize/public/application/components/visualize_top_nav.tsx @@ -75,6 +75,7 @@ const TopNav = ({ }, [visInstance.embeddableHandler] ); + const stateTransfer = services.embeddable.getStateTransfer(); const config = useMemo(() => { if (isEmbeddableRendered) { @@ -89,6 +90,7 @@ const TopNav = ({ visInstance, stateContainer, visualizationIdFromUrl, + stateTransfer, embeddableId, }, services @@ -107,6 +109,7 @@ const TopNav = ({ visualizationIdFromUrl, services, embeddableId, + stateTransfer, ]); const [indexPattern, setIndexPattern] = useState(vis.data.indexPattern); const showDatePicker = () => { diff --git a/src/plugins/visualize/public/application/utils/get_top_nav_config.tsx b/src/plugins/visualize/public/application/utils/get_top_nav_config.tsx index 43121f2cffc41..0423e48bfb41e 100644 --- a/src/plugins/visualize/public/application/utils/get_top_nav_config.tsx +++ b/src/plugins/visualize/public/application/utils/get_top_nav_config.tsx @@ -38,6 +38,7 @@ import { } from '../types'; import { VisualizeConstants } from '../visualize_constants'; import { getEditBreadcrumbs } from './breadcrumbs'; +import { EmbeddableStateTransfer } from '../../../../embeddable/public'; interface TopNavConfigParams { hasUnsavedChanges: boolean; @@ -49,6 +50,7 @@ interface TopNavConfigParams { visInstance: VisualizeEditorVisInstance; stateContainer: VisualizeAppStateContainer; visualizationIdFromUrl?: string; + stateTransfer: EmbeddableStateTransfer; embeddableId?: string; } @@ -63,12 +65,12 @@ export const getTopNavConfig = ( visInstance, stateContainer, visualizationIdFromUrl, + stateTransfer, embeddableId, }: TopNavConfigParams, { application, chrome, - embeddable, history, share, setActiveUrl, @@ -118,8 +120,8 @@ export const getTopNavConfig = ( history.replace(appPath); setActiveUrl(appPath); - if (newlyCreated && embeddable) { - embeddable.getStateTransfer().navigateToWithEmbeddablePackage(originatingApp, { + if (newlyCreated && stateTransfer) { + stateTransfer.navigateToWithEmbeddablePackage(originatingApp, { state: { id, type: VISUALIZE_EMBEDDABLE_TYPE }, }); } else { @@ -174,7 +176,7 @@ export const getTopNavConfig = ( if (embeddableId) { state.embeddableId = embeddableId; } - embeddable.getStateTransfer().navigateToWithEmbeddablePackage(originatingApp, { state }); + stateTransfer.navigateToWithEmbeddablePackage(originatingApp, { state }); }; const topNavMenu: TopNavMenuData[] = [ @@ -284,6 +286,7 @@ export const getTopNavConfig = ( {}} originatingApp={originatingApp} diff --git a/x-pack/plugins/lens/public/app_plugin/app.tsx b/x-pack/plugins/lens/public/app_plugin/app.tsx index ffab84a51a229..b20fe2f804683 100644 --- a/x-pack/plugins/lens/public/app_plugin/app.tsx +++ b/x-pack/plugins/lens/public/app_plugin/app.tsx @@ -70,6 +70,7 @@ export function App({ navigation, onAppLeave, history, + getAppNameFromId, }: { editorFrame: EditorFrameInstance; data: DataPublicPluginStart; @@ -82,6 +83,7 @@ export function App({ originatingApp?: string | undefined; onAppLeave: AppMountParameters['onAppLeave']; history: History; + getAppNameFromId?: (appId: string) => string | undefined; }) { const [state, setState] = useState(() => { const currentRange = data.query.timefilter.timefilter.getTime(); @@ -534,6 +536,7 @@ export function App({ originatingApp={state.originatingApp} onSave={(props) => runSave(props)} onClose={() => setState((s) => ({ ...s, isSaveModalVisible: false }))} + getAppNameFromId={getAppNameFromId} documentInfo={{ id: lastKnownDoc.id, title: lastKnownDoc.title || '', diff --git a/x-pack/plugins/lens/public/app_plugin/mounter.tsx b/x-pack/plugins/lens/public/app_plugin/mounter.tsx index 1ee618a31a698..398d01af7f1b3 100644 --- a/x-pack/plugins/lens/public/app_plugin/mounter.tsx +++ b/x-pack/plugins/lens/public/app_plugin/mounter.tsx @@ -87,6 +87,7 @@ export async function mountApp( redirectTo(routeProps, id, returnToOrigin, newlyCreated) } originatingApp={originatingApp} + getAppNameFromId={stateTransfer.getAppNameFromId} onAppLeave={params.onAppLeave} history={routeProps.history} /> diff --git a/x-pack/plugins/maps/public/routing/routes/maps_app/top_nav_config.tsx b/x-pack/plugins/maps/public/routing/routes/maps_app/top_nav_config.tsx index 35d8490f1a886..497c87ad533a6 100644 --- a/x-pack/plugins/maps/public/routing/routes/maps_app/top_nav_config.tsx +++ b/x-pack/plugins/maps/public/routing/routes/maps_app/top_nav_config.tsx @@ -175,6 +175,7 @@ export function getTopNavConfig({ const saveModal = ( {}} documentInfo={{ From 644e9c25d782b8e9cd54ca05015ab514a7ee429e Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Thu, 20 Aug 2020 19:04:42 +0200 Subject: [PATCH 05/45] [Ingest Pipelines] Processor forms for processors E-J (#75054) * Added the enrich processor form (big one) * added fail processor form * Added foreach processor form * Added geoip processor form and refactored some deserialization * added grok processor form and updated comments and some i18n ids * updated existing gsub processor form to be in line with other forms * added html_strip processor form * refactored some serialize and deserialize functions and added inference processor form * fix copy-pasta mistake in inference form and add join processor form * Added JSON processor field - Also factored out target_field field to common field (still have to update the all instances) - Built out special logic for handling add_to_root and target_field combo on JSON processor form - Created another serializer, for default boolean -> undefined. * remove unused variable * Refactor to use new shared target_field component, and fix JSON serializer bug * fix i18n * address pr feedback * Fix enrich max fields help text copy * add link to enrich policy docs in help text * fix error validation message in enrich policy form and replace space with horizontal rule * address copy feedback * fix i18n id typo * fix i18n * address additional round of feedback and fix json form help text Co-authored-by: Elastic Machine --- .../processor_settings_fields.tsx | 4 +- .../processors/append.tsx | 4 +- .../processors/bytes.tsx | 18 +- .../processors/circle.tsx | 18 +- .../common_fields/common_processor_fields.tsx | 7 +- .../common_fields/ignore_missing_field.tsx | 33 ++- .../processors/common_fields/target_field.tsx | 46 +++ .../processors/convert.tsx | 24 +- .../manage_processor_form/processors/csv.tsx | 8 +- .../manage_processor_form/processors/date.tsx | 35 +-- .../processors/date_index_name.tsx | 6 +- .../processors/enrich.tsx | 264 ++++++++++++++++++ .../manage_processor_form/processors/fail.tsx | 40 +++ .../processors/foreach.tsx | 81 ++++++ .../processors/geoip.tsx | 109 ++++++++ .../manage_processor_form/processors/grok.tsx | 134 +++++++++ .../manage_processor_form/processors/gsub.tsx | 142 +++++----- .../processors/html_strip.tsx | 39 +++ .../manage_processor_form/processors/index.ts | 10 + .../processors/inference.tsx | 203 ++++++++++++++ .../manage_processor_form/processors/join.tsx | 71 +++++ .../manage_processor_form/processors/json.tsx | 87 ++++++ .../processors/shared.ts | 56 +++- .../shared/map_processor_type_to_form.tsx | 44 +-- .../translations/translations/ja-JP.json | 4 - .../translations/translations/zh-CN.json | 4 - 26 files changed, 1300 insertions(+), 191 deletions(-) create mode 100644 x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/target_field.tsx create mode 100644 x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/enrich.tsx create mode 100644 x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/fail.tsx create mode 100644 x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/foreach.tsx create mode 100644 x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/geoip.tsx create mode 100644 x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/grok.tsx create mode 100644 x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/html_strip.tsx create mode 100644 x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/inference.tsx create mode 100644 x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/join.tsx create mode 100644 x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/json.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processor_settings_fields.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processor_settings_fields.tsx index a6447bc30ac00..6a70592bc2f70 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processor_settings_fields.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processor_settings_fields.tsx @@ -5,7 +5,7 @@ */ import React, { FunctionComponent } from 'react'; -import { EuiHorizontalRule, EuiSpacer } from '@elastic/eui'; +import { EuiHorizontalRule } from '@elastic/eui'; import { FormDataProvider } from '../../../../../shared_imports'; import { ProcessorInternal } from '../../types'; @@ -36,7 +36,7 @@ export const ProcessorSettingsFields: FunctionComponent = ({ processor }) return ( <> - + ); diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/append.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/append.tsx index 8eb484b56bafe..09d0981adf1c2 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/append.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/append.tsx @@ -14,7 +14,7 @@ import { ComboBoxField, } from '../../../../../../shared_imports'; -import { FieldsConfig } from './shared'; +import { FieldsConfig, to } from './shared'; import { FieldNameField } from './common_fields/field_name_field'; const { emptyField } = fieldValidators; @@ -22,7 +22,7 @@ const { emptyField } = fieldValidators; const fieldsConfig: FieldsConfig = { value: { type: FIELD_TYPES.COMBO_BOX, - deserializer: (v) => (Array.isArray(v) ? v : [String(v)]), + deserializer: to.arrayOfStrings, label: i18n.translate('xpack.ingestPipelines.pipelineEditor.appendForm.valueFieldLabel', { defaultMessage: 'Value', }), diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/bytes.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/bytes.tsx index 64a501f03d454..a76e1a6f3ce9a 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/bytes.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/bytes.tsx @@ -7,23 +7,9 @@ import React, { FunctionComponent } from 'react'; import { i18n } from '@kbn/i18n'; -import { FIELD_TYPES, UseField, Field } from '../../../../../../shared_imports'; - -import { FieldsConfig } from './shared'; import { IgnoreMissingField } from './common_fields/ignore_missing_field'; import { FieldNameField } from './common_fields/field_name_field'; - -const fieldsConfig: FieldsConfig = { - target_field: { - type: FIELD_TYPES.TEXT, - label: i18n.translate('xpack.ingestPipelines.pipelineEditor.bytesForm.targetFieldLabel', { - defaultMessage: 'Target field (optional)', - }), - helpText: i18n.translate('xpack.ingestPipelines.pipelineEditor.bytesForm.targetFieldHelpText', { - defaultMessage: 'The field to assign the converted value to', - }), - }, -}; +import { TargetField } from './common_fields/target_field'; export const Bytes: FunctionComponent = () => { return ( @@ -35,7 +21,7 @@ export const Bytes: FunctionComponent = () => { )} /> - + diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/circle.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/circle.tsx index 3a39e597cb8dc..599d2fdbfd413 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/circle.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/circle.tsx @@ -11,7 +11,6 @@ import { FIELD_TYPES, fieldValidators, UseField, - Field, SelectField, NumericField, } from '../../../../../../shared_imports'; @@ -19,22 +18,12 @@ import { import { FieldsConfig } from './shared'; import { IgnoreMissingField } from './common_fields/ignore_missing_field'; import { FieldNameField } from './common_fields/field_name_field'; +import { TargetField } from './common_fields/target_field'; const { emptyField } = fieldValidators; const fieldsConfig: FieldsConfig = { - target_field: { - type: FIELD_TYPES.TEXT, - label: i18n.translate('xpack.ingestPipelines.pipelineEditor.circleForm.targetFieldLabel', { - defaultMessage: 'Target field (optional)', - }), - helpText: i18n.translate( - 'xpack.ingestPipelines.pipelineEditor.circleForm.targetFieldHelpText', - { - defaultMessage: 'By default field is updated in-place.', - } - ), - }, + /* Required fields config */ error_distance: { type: FIELD_TYPES.NUMBER, deserializer: (v) => (typeof v === 'number' && !isNaN(v) ? v : 1.0), @@ -71,6 +60,7 @@ const fieldsConfig: FieldsConfig = { }, shape_type: { type: FIELD_TYPES.SELECT, + serializer: String, label: i18n.translate('xpack.ingestPipelines.pipelineEditor.circleForm.shapeTypeFieldLabel', { defaultMessage: 'Shape type', }), @@ -132,7 +122,7 @@ export const Circle: FunctionComponent = () => { path="fields.shape_type" /> - + diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/common_processor_fields.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/common_processor_fields.tsx index 7ae7b82c31a43..8089b8e7dfad3 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/common_processor_fields.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/common_processor_fields.tsx @@ -16,11 +16,12 @@ import { } from '../../../../../../../shared_imports'; import { TextEditor } from '../../field_components'; +import { to, from } from '../shared'; const ignoreFailureConfig: FieldConfig = { defaultValue: false, - serializer: (v) => (v === false ? undefined : v), - deserializer: (v) => (typeof v === 'boolean' ? v : undefined), + deserializer: to.booleanOrUndef, + serializer: from.defaultBoolToUndef(false), label: i18n.translate( 'xpack.ingestPipelines.pipelineEditor.commonFields.ignoreFailureFieldLabel', { @@ -62,7 +63,7 @@ export const CommonProcessorFields: FunctionComponent = () => { component={TextEditor} componentProps={{ editorProps: { - language: 'painless', + languageId: 'painless', height: 75, options: { minimap: { enabled: false } }, }, diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/ignore_missing_field.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/ignore_missing_field.tsx index 08eb0a425ef33..35dd462d88425 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/ignore_missing_field.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/ignore_missing_field.tsx @@ -5,32 +5,47 @@ */ import React, { FunctionComponent } from 'react'; import { i18n } from '@kbn/i18n'; -import { FIELD_TYPES, UseField, ToggleField } from '../../../../../../../shared_imports'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { EuiCode } from '@elastic/eui'; -import { FieldsConfig } from '../shared'; +import { + FIELD_TYPES, + UseField, + ToggleField, + FieldConfig, +} from '../../../../../../../shared_imports'; + +import { FieldsConfig, to, from } from '../shared'; export const fieldsConfig: FieldsConfig = { ignore_missing: { type: FIELD_TYPES.TOGGLE, defaultValue: false, - serializer: (v) => (v === false ? undefined : v), - deserializer: (v) => (typeof v === 'boolean' ? v : undefined), + deserializer: to.booleanOrUndef, + serializer: from.defaultBoolToUndef(false), label: i18n.translate( 'xpack.ingestPipelines.pipelineEditor.commonFields.ignoreMissingFieldLabel', { defaultMessage: 'Ignore missing', } ), + helpText: ( + {'field'}, + }} + /> + ), }, }; -interface Props { - helpText?: string; -} +type Props = Partial; -export const IgnoreMissingField: FunctionComponent = ({ helpText }) => ( +export const IgnoreMissingField: FunctionComponent = (props) => ( diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/target_field.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/target_field.tsx new file mode 100644 index 0000000000000..9bf44425a7c5d --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/target_field.tsx @@ -0,0 +1,46 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FunctionComponent } from 'react'; +import { i18n } from '@kbn/i18n'; + +import { Field, FIELD_TYPES, UseField, FieldConfig } from '../../../../../../../shared_imports'; + +import { FieldsConfig } from '../shared'; + +const fieldsConfig: FieldsConfig = { + target_field: { + type: FIELD_TYPES.TEXT, + deserializer: String, + label: i18n.translate('xpack.ingestPipelines.pipelineEditor.commonFields.targetFieldLabel', { + defaultMessage: 'Target field (optional)', + }), + helpText: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.commonFields.targetFieldHelpText', + { + defaultMessage: + 'The field to assign the joined value to. If empty, the field is updated in-place.', + } + ), + }, +}; + +type Props = Partial; + +export const TARGET_FIELD_PATH = 'fields.target_field'; + +export const TargetField: FunctionComponent = (props) => { + return ( + + ); +}; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/convert.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/convert.tsx index b45f589bf0f92..2bf642dd9b518 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/convert.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/convert.tsx @@ -11,13 +11,13 @@ import { FIELD_TYPES, fieldValidators, UseField, - Field, SelectField, } from '../../../../../../shared_imports'; import { FieldsConfig } from './shared'; import { FieldNameField } from './common_fields/field_name_field'; import { IgnoreMissingField } from './common_fields/ignore_missing_field'; +import { TargetField } from './common_fields/target_field'; const { emptyField } = fieldValidators; @@ -42,19 +42,6 @@ const fieldsConfig: FieldsConfig = { }, ], }, - /* Optional fields config */ - target_field: { - type: FIELD_TYPES.TEXT, - label: i18n.translate('xpack.ingestPipelines.pipelineEditor.convertForm.targetFieldLabel', { - defaultMessage: 'Target field (optional)', - }), - helpText: i18n.translate( - 'xpack.ingestPipelines.pipelineEditor.convertForm.targetFieldHelpText', - { - defaultMessage: 'The field to assign the converted value to.', - } - ), - }, }; export const Convert: FunctionComponent = () => { @@ -128,7 +115,14 @@ export const Convert: FunctionComponent = () => { path="fields.type" /> - + diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/csv.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/csv.tsx index 3ac0179ca02a6..835177dd861d5 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/csv.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/csv.tsx @@ -23,7 +23,7 @@ import { FieldsConfig } from './shared'; import { IgnoreMissingField } from './common_fields/ignore_missing_field'; import { FieldNameField } from './common_fields/field_name_field'; -import { isArrayOfStrings } from './shared'; +import { to } from './shared'; const { minLengthField } = fieldValidators; @@ -47,9 +47,7 @@ const fieldsConfig: FieldsConfig = { /* Required fields config */ target_fields: { type: FIELD_TYPES.COMBO_BOX, - deserializer: (v) => { - return isArrayOfStrings(v) ? v : []; - }, + deserializer: to.arrayOfStrings, label: i18n.translate('xpack.ingestPipelines.pipelineEditor.csvForm.targetFieldsFieldLabel', { defaultMessage: 'Target fields', }), @@ -112,7 +110,7 @@ const fieldsConfig: FieldsConfig = { trim: { type: FIELD_TYPES.TOGGLE, defaultValue: false, - deserializer: (v) => (typeof v === 'boolean' ? v : undefined), + deserializer: to.booleanOrUndef, label: i18n.translate('xpack.ingestPipelines.pipelineEditor.csvForm.trimFieldLabel', { defaultMessage: 'Trim', }), diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/date.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/date.tsx index 424e84058ac3f..7e3f8e0d7cd70 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/date.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/date.tsx @@ -17,8 +17,9 @@ import { ComboBoxField, } from '../../../../../../shared_imports'; -import { FieldsConfig, isArrayOfStrings } from './shared'; +import { FieldsConfig, to } from './shared'; import { FieldNameField } from './common_fields/field_name_field'; +import { TargetField } from './common_fields/target_field'; const { minLengthField } = fieldValidators; @@ -26,9 +27,7 @@ const fieldsConfig: FieldsConfig = { /* Required fields config */ formats: { type: FIELD_TYPES.COMBO_BOX, - deserializer: (v) => { - return isArrayOfStrings(v) ? v : []; - }, + deserializer: to.arrayOfStrings, label: i18n.translate('xpack.ingestPipelines.pipelineEditor.dateForm.formatsFieldLabel', { defaultMessage: 'Formats', }), @@ -51,22 +50,6 @@ const fieldsConfig: FieldsConfig = { ], }, /* Optional fields config */ - target_field: { - type: FIELD_TYPES.TEXT, - serializer: (v) => (v ? undefined : v), - label: i18n.translate('xpack.ingestPipelines.pipelineEditor.dateForm.targetFieldFieldLabel', { - defaultMessage: 'Target field (optional)', - }), - helpText: ( - {'@timestamp'}, - }} - /> - ), - }, timezone: { type: FIELD_TYPES.TEXT, serializer: (v) => (v ? v : undefined), @@ -112,7 +95,17 @@ export const DateProcessor: FunctionComponent = () => { - + {'@timestamp'}, + }} + /> + } + /> diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/date_index_name.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/date_index_name.tsx index 387c9ff4e0b46..2a278a251c30f 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/date_index_name.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/date_index_name.tsx @@ -18,7 +18,7 @@ import { SelectField, } from '../../../../../../shared_imports'; -import { FieldsConfig, isArrayOfStrings } from './shared'; +import { FieldsConfig, to } from './shared'; import { FieldNameField } from './common_fields/field_name_field'; const { emptyField } = fieldValidators; @@ -89,9 +89,7 @@ const fieldsConfig: FieldsConfig = { serializer: (v: string[]) => { return v.length ? v : undefined; }, - deserializer: (v) => { - return isArrayOfStrings(v) ? v : []; - }, + deserializer: to.arrayOfStrings, label: i18n.translate( 'xpack.ingestPipelines.pipelineEditor.dateIndexNameForm.dateFormatsFieldLabel', { diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/enrich.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/enrich.tsx new file mode 100644 index 0000000000000..31eac38222afb --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/enrich.tsx @@ -0,0 +1,264 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FunctionComponent } from 'react'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { EuiLink } from '@elastic/eui'; +import { + FIELD_TYPES, + fieldValidators, + UseField, + Field, + ToggleField, + NumericField, + SelectField, + ValidationConfig, + useKibana, +} from '../../../../../../shared_imports'; + +import { FieldNameField } from './common_fields/field_name_field'; +import { IgnoreMissingField } from './common_fields/ignore_missing_field'; +import { TargetField } from './common_fields/target_field'; + +import { FieldsConfig, from, to } from './shared'; + +const { emptyField, numberSmallerThanField, numberGreaterThanField } = fieldValidators; + +const maxMatchesValidators = { + max: numberSmallerThanField({ + than: 128, + allowEquality: true, + message: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.enrichForm.maxMatchesMaxNumberError', + { defaultMessage: 'This number must be less than 128.' } + ), + }), + min: numberGreaterThanField({ + than: 0, + allowEquality: false, + message: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.enrichForm.maxMatchesMinNumberError', + { defaultMessage: 'This number must be greater than 0.' } + ), + }), +}; + +const targetFieldValidator: ValidationConfig = { + validator: emptyField( + i18n.translate('xpack.ingestPipelines.pipelineEditor.enrichForm.targetFieldRequiredError', { + defaultMessage: 'A target field value is required.', + }) + ), +}; + +const fieldsConfig: FieldsConfig = { + /* Required fields config */ + policy_name: { + type: FIELD_TYPES.TEXT, + label: i18n.translate('xpack.ingestPipelines.pipelineEditor.enrichForm.policyNameFieldLabel', { + defaultMessage: 'Policy name', + }), + validations: [ + { + validator: emptyField( + i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.enrichForm.policyNameRequiredError', + { + defaultMessage: 'A value is required.', + } + ) + ), + }, + ], + }, + + /* Optional fields config */ + override: { + type: FIELD_TYPES.TOGGLE, + defaultValue: true, + deserializer: to.booleanOrUndef, + serializer: from.defaultBoolToUndef, + label: i18n.translate('xpack.ingestPipelines.pipelineEditor.enrichForm.overrideFieldLabel', { + defaultMessage: 'Override', + }), + helpText: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.enrichForm.overrideFieldHelpText', + { + defaultMessage: 'If enabled, the processor can overwrite pre-existing field values.', + } + ), + }, + + max_matches: { + type: FIELD_TYPES.NUMBER, + defaultValue: 1, + deserializer: (v) => (typeof v === 'number' && !isNaN(v) ? v : 1), + serializer: (v) => { + const n = parseInt(v, 10); + return n === 1 ? undefined : n; + }, + label: i18n.translate('xpack.ingestPipelines.pipelineEditor.enrichForm.maxMatchesFieldLabel', { + defaultMessage: 'Maximum matches (optional)', + }), + helpText: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.enrichForm.maxMatchesFieldHelpText', + { + defaultMessage: + 'Number of matching enrich documents to include in the target field. Accepts 1–128.', + } + ), + validations: [ + { + validator: (v) => { + if (v.value /* value is a string here */) { + return maxMatchesValidators.max(v) ?? maxMatchesValidators.min(v); + } + }, + }, + ], + }, + + shape_relation: { + type: FIELD_TYPES.SELECT, + defaultValue: 'INTERSECTS', + deserializer: String, + serializer: (v) => (v === 'INTERSECTS' ? undefined : v), + label: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.enrichForm.shapeRelationFieldLabel', + { + defaultMessage: 'Shape relation (optional)', + } + ), + }, +}; + +export const Enrich: FunctionComponent = () => { + const { services } = useKibana(); + const esDocUrl = services.documentation.getEsDocsBasePath(); + return ( + <> + + + + {i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.enrichForm.policyNameHelpText.enrichPolicyLink', + { defaultMessage: 'enrich policy' } + )} + + ), + }} + /> + ), + }} + component={Field} + path="fields.policy_name" + /> + + + + + + + + + {i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.enrichForm.shapeRelationFieldHelpText.geoMatchPoliciesLink', + { defaultMessage: 'geo-match enrich policies' } + )} + + ), + }} + /> + ), + }} + component={SelectField} + componentProps={{ + euiFieldProps: { + options: [ + { + value: 'INTERSECTS', + text: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.enrichForm.intersectsOption', + { defaultMessage: 'Intersects' } + ), + }, + { + value: 'DISJOINT', + text: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.enrichFrom.disjointOption', + { defaultMessage: 'Disjoint' } + ), + }, + { + value: 'WITHIN', + text: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.enrichForm.withinOption', + { defaultMessage: 'Within' } + ), + }, + { + value: 'CONTAINS', + text: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.enrichForm.containsOption', + { defaultMessage: 'Contains' } + ), + }, + ], + }, + }} + path="fields.shape_relation" + /> + + + + ); +}; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/fail.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/fail.tsx new file mode 100644 index 0000000000000..3befadc3ca5a3 --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/fail.tsx @@ -0,0 +1,40 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FunctionComponent } from 'react'; +import { i18n } from '@kbn/i18n'; + +import { FIELD_TYPES, fieldValidators, UseField, Field } from '../../../../../../shared_imports'; + +import { FieldsConfig } from './shared'; + +const { emptyField } = fieldValidators; + +const fieldsConfig: FieldsConfig = { + message: { + type: FIELD_TYPES.TEXT, + deserializer: String, + label: i18n.translate('xpack.ingestPipelines.pipelineEditor.failForm.messageFieldLabel', { + defaultMessage: 'Message', + }), + helpText: i18n.translate('xpack.ingestPipelines.pipelineEditor.failForm.messageHelpText', { + defaultMessage: 'Error message returned by the processor', + }), + validations: [ + { + validator: emptyField( + i18n.translate('xpack.ingestPipelines.pipelineEditor.failForm.valueRequiredError', { + defaultMessage: 'A message is required.', + }) + ), + }, + ], + }, +}; + +export const Fail: FunctionComponent = () => { + return ; +}; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/foreach.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/foreach.tsx new file mode 100644 index 0000000000000..e471f8322f164 --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/foreach.tsx @@ -0,0 +1,81 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FunctionComponent } from 'react'; +import { i18n } from '@kbn/i18n'; + +import { FIELD_TYPES, fieldValidators, UseField } from '../../../../../../shared_imports'; + +import { XJsonEditor } from '../field_components'; + +import { FieldNameField } from './common_fields/field_name_field'; +import { FieldsConfig, to } from './shared'; + +const { emptyField, isJsonField } = fieldValidators; + +const fieldsConfig: FieldsConfig = { + /* Required fields config */ + processor: { + type: FIELD_TYPES.TEXT, + deserializer: to.jsonString, + serializer: JSON.parse, + label: i18n.translate('xpack.ingestPipelines.pipelineEditor.foreachForm.processorFieldLabel', { + defaultMessage: 'Processor', + }), + helpText: i18n.translate('xpack.ingestPipelines.pipelineEditor.foreachForm.processorHelpText', { + defaultMessage: 'Ingest processor to run on each array value', + }), + validations: [ + { + validator: emptyField( + i18n.translate('xpack.ingestPipelines.pipelineEditor.failForm.processorRequiredError', { + defaultMessage: 'A processor is required.', + }) + ), + }, + { + validator: isJsonField( + i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.failForm.processorInvalidJsonError', + { + defaultMessage: 'Invalid JSON', + } + ) + ), + }, + ], + }, +}; + +export const Foreach: FunctionComponent = () => { + return ( + <> + + + + + ); +}; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/geoip.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/geoip.tsx new file mode 100644 index 0000000000000..ef2aa62c4a7de --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/geoip.tsx @@ -0,0 +1,109 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FunctionComponent } from 'react'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { EuiCode } from '@elastic/eui'; + +import { + FIELD_TYPES, + UseField, + Field, + ComboBoxField, + ToggleField, +} from '../../../../../../shared_imports'; + +import { FieldNameField } from './common_fields/field_name_field'; +import { IgnoreMissingField } from './common_fields/ignore_missing_field'; +import { FieldsConfig, from, to } from './shared'; +import { TargetField } from './common_fields/target_field'; + +const fieldsConfig: FieldsConfig = { + /* Optional field config */ + database_file: { + type: FIELD_TYPES.TEXT, + serializer: (v) => (v === 'GeoLite2-City.mmdb' ? undefined : v), + label: i18n.translate('xpack.ingestPipelines.pipelineEditor.geoIPForm.databaseFileLabel', { + defaultMessage: 'Database file (optional)', + }), + helpText: ( + {'GeoLite2-City.mmdb'}, + ingestGeoIP: {'ingest-geoip'}, + }} + /> + ), + }, + + properties: { + type: FIELD_TYPES.COMBO_BOX, + deserializer: to.arrayOfStrings, + label: i18n.translate('xpack.ingestPipelines.pipelineEditor.geoIPForm.propertiesFieldLabel', { + defaultMessage: 'Properties (optional)', + }), + helpText: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.geoIPForm.propertiesFieldHelpText', + { + defaultMessage: + 'Properties added to the target field. Valid properties depend on the database file used.', + } + ), + }, + + first_only: { + type: FIELD_TYPES.TOGGLE, + defaultValue: true, + deserializer: to.booleanOrUndef, + serializer: from.defaultBoolToUndef(true), + label: i18n.translate('xpack.ingestPipelines.pipelineEditor.geoIPForm.firstOnlyFieldLabel', { + defaultMessage: 'First only', + }), + helpText: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.geoIPForm.firstOnlyFieldHelpText', + { + defaultMessage: 'Use the first matching geo data, even if the field contains an array.', + } + ), + }, +}; + +export const GeoIP: FunctionComponent = () => { + return ( + <> + + + + + + + + + + + + + ); +}; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/grok.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/grok.tsx new file mode 100644 index 0000000000000..1ed9898149a67 --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/grok.tsx @@ -0,0 +1,134 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FunctionComponent } from 'react'; +import { i18n } from '@kbn/i18n'; + +import { + FIELD_TYPES, + UseField, + ComboBoxField, + ToggleField, + fieldValidators, +} from '../../../../../../shared_imports'; + +import { XJsonEditor } from '../field_components'; + +import { FieldNameField } from './common_fields/field_name_field'; +import { IgnoreMissingField } from './common_fields/ignore_missing_field'; +import { FieldsConfig, to, from } from './shared'; + +const { emptyField, isJsonField } = fieldValidators; + +const fieldsConfig: FieldsConfig = { + /* Required field configs */ + patterns: { + type: FIELD_TYPES.COMBO_BOX, + deserializer: to.arrayOfStrings, + label: i18n.translate('xpack.ingestPipelines.pipelineEditor.grokForm.patternsFieldLabel', { + defaultMessage: 'Patterns', + }), + helpText: i18n.translate('xpack.ingestPipelines.pipelineEditor.grokForm.patternsHelpText', { + defaultMessage: + 'Grok expressions used to match and extract named capture groups. Uses the first matching expression.', + }), + validations: [ + { + validator: emptyField( + i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.grokForm.patternsValueRequiredError', + { defaultMessage: 'A value is required.' } + ) + ), + }, + ], + }, + /* Optional field configs */ + pattern_definitions: { + type: FIELD_TYPES.TEXT, + deserializer: to.jsonString, + serializer: from.optionalJson, + label: i18n.translate('xpack.ingestPipelines.pipelineEditor.grokForm.patternDefinitionsLabel', { + defaultMessage: 'Pattern definitions (optional)', + }), + helpText: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.grokForm.patternDefinitionsHelpText', + { + defaultMessage: + 'A map of pattern-name and pattern tuples defining custom patterns. Patterns matching existing names will override the pre-existing definition.', + } + ), + validations: [ + { + validator: isJsonField( + i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.grokForm.patternsDefinitionsInvalidJSONError', + { defaultMessage: 'Invalid JSON' } + ), + { + allowEmptyString: true, + } + ), + }, + ], + }, + + trace_match: { + type: FIELD_TYPES.TOGGLE, + defaultValue: false, + deserializer: to.booleanOrUndef, + serializer: from.defaultBoolToUndef(false), + label: i18n.translate('xpack.ingestPipelines.pipelineEditor.grokForm.traceMatchFieldLabel', { + defaultMessage: 'Trace match', + }), + helpText: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.grokForm.traceMatchFieldHelpText', + { + defaultMessage: 'Add metadata about the matching expression to the document', + } + ), + }, +}; + +export const Grok: FunctionComponent = () => { + return ( + <> + + + + + + + + + + + ); +}; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/gsub.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/gsub.tsx index 3148022adaa98..4d3445d469da2 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/gsub.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/gsub.tsx @@ -6,89 +6,75 @@ import React, { FunctionComponent } from 'react'; import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { EuiCode } from '@elastic/eui'; -import { - FieldConfig, - FIELD_TYPES, - fieldValidators, - ToggleField, - UseField, - Field, -} from '../../../../../../shared_imports'; -import { TextEditor } from '../field_components'; - -const { emptyField } = fieldValidators; +import { FIELD_TYPES, fieldValidators, UseField, Field } from '../../../../../../shared_imports'; -const fieldConfig: FieldConfig = { - type: FIELD_TYPES.TEXT, - label: i18n.translate('xpack.ingestPipelines.pipelineEditor.gsubForm.fieldFieldLabel', { - defaultMessage: 'Field', - }), - validations: [ - { - validator: emptyField( - i18n.translate('xpack.ingestPipelines.pipelineEditor.gsubForm.fieldRequiredError', { - defaultMessage: 'A field value is required.', - }) - ), - }, - ], -}; +import { TextEditor } from '../field_components'; -const patternConfig: FieldConfig = { - type: FIELD_TYPES.TEXT, - label: i18n.translate('xpack.ingestPipelines.pipelineEditor.gsubForm.patternFieldLabel', { - defaultMessage: 'Pattern', - }), - validations: [ - { - validator: emptyField( - i18n.translate('xpack.ingestPipelines.pipelineEditor.gsubForm.patternRequiredError', { - defaultMessage: 'A pattern value is required.', - }) - ), - }, - ], -}; +import { FieldsConfig } from './shared'; +import { FieldNameField } from './common_fields/field_name_field'; +import { IgnoreMissingField } from './common_fields/ignore_missing_field'; +import { TargetField } from './common_fields/target_field'; -const replacementConfig: FieldConfig = { - type: FIELD_TYPES.TEXT, - label: i18n.translate('xpack.ingestPipelines.pipelineEditor.gsubForm.replacementFieldLabel', { - defaultMessage: 'Replacement', - }), - validations: [ - { - validator: emptyField( - i18n.translate('xpack.ingestPipelines.pipelineEditor.gsubForm.replacementRequiredError', { - defaultMessage: 'A replacement value is required.', - }) - ), - }, - ], -}; +const { emptyField } = fieldValidators; -const targetConfig: FieldConfig = { - type: FIELD_TYPES.TEXT, - label: i18n.translate('xpack.ingestPipelines.pipelineEditor.gsubForm.targetFieldLabel', { - defaultMessage: 'Target field (optional)', - }), -}; +const fieldsConfig: FieldsConfig = { + /* Required fields config */ + pattern: { + type: FIELD_TYPES.TEXT, + label: i18n.translate('xpack.ingestPipelines.pipelineEditor.gsubForm.patternFieldLabel', { + defaultMessage: 'Pattern', + }), + deserializer: String, + helpText: i18n.translate('xpack.ingestPipelines.pipelineEditor.gsubForm.patternFieldHelpText', { + defaultMessage: 'Regular expression used to match substrings in the field', + }), + validations: [ + { + validator: emptyField( + i18n.translate('xpack.ingestPipelines.pipelineEditor.gsubForm.patternRequiredError', { + defaultMessage: 'A value is required.', + }) + ), + }, + ], + }, -const ignoreMissingConfig: FieldConfig = { - defaultValue: false, - label: i18n.translate('xpack.ingestPipelines.pipelineEditor.gsubForm.ignoreMissingFieldLabel', { - defaultMessage: 'Ignore missing', - }), - type: FIELD_TYPES.TOGGLE, + replacement: { + type: FIELD_TYPES.TEXT, + label: i18n.translate('xpack.ingestPipelines.pipelineEditor.gsubForm.replacementFieldLabel', { + defaultMessage: 'Replacement', + }), + helpText: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.gsubForm.replacementFieldHelpText', + { defaultMessage: 'Replacement text for matches' } + ), + validations: [ + { + validator: emptyField( + i18n.translate('xpack.ingestPipelines.pipelineEditor.gsubForm.replacementRequiredError', { + defaultMessage: 'A value is required.', + }) + ), + }, + ], + }, }; export const Gsub: FunctionComponent = () => { return ( <> - + { path="fields.pattern" /> - + - + {'field'}, + }} + /> + } + /> - + ); }; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/html_strip.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/html_strip.tsx new file mode 100644 index 0000000000000..c6ca7df4cc3e7 --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/html_strip.tsx @@ -0,0 +1,39 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FunctionComponent } from 'react'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { EuiCode } from '@elastic/eui'; + +import { FieldNameField } from './common_fields/field_name_field'; +import { IgnoreMissingField } from './common_fields/ignore_missing_field'; +import { TargetField } from './common_fields/target_field'; + +export const HtmlStrip: FunctionComponent = () => { + return ( + <> + + + {'field'} }} + /> + } + /> + + + + ); +}; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/index.ts b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/index.ts index 6996deb2d861c..4974361bf0410 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/index.ts +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/index.ts @@ -14,3 +14,13 @@ export { DateIndexName } from './date_index_name'; export { Dissect } from './dissect'; export { DotExpander } from './dot_expander'; export { Drop } from './drop'; +export { Enrich } from './enrich'; +export { Fail } from './fail'; +export { Foreach } from './foreach'; +export { GeoIP } from './geoip'; +export { Grok } from './grok'; +export { Gsub } from './gsub'; +export { HtmlStrip } from './html_strip'; +export { Inference } from './inference'; +export { Join } from './join'; +export { Json } from './json'; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/inference.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/inference.tsx new file mode 100644 index 0000000000000..ee8d7cc55a9f1 --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/inference.tsx @@ -0,0 +1,203 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FunctionComponent } from 'react'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { EuiCode, EuiLink } from '@elastic/eui'; + +import { + FIELD_TYPES, + fieldValidators, + UseField, + Field, + useKibana, +} from '../../../../../../shared_imports'; + +import { XJsonEditor } from '../field_components'; + +import { TargetField } from './common_fields/target_field'; + +import { FieldsConfig, to, from } from './shared'; + +const { emptyField, isJsonField } = fieldValidators; + +const INFERENCE_CONFIG_DOCS = { + regression: { + path: 'inference-processor.html#inference-processor-regression-opt', + linkLabel: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.inferenceForm.inferenceConfigField.regressionLinkLabel', + { defaultMessage: 'regression' } + ), + }, + classification: { + path: 'inference-processor.html#inference-processor-classification-opt', + linkLabel: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.inferenceForm.inferenceConfigField.classificationLinkLabel', + { defaultMessage: 'classification' } + ), + }, +}; + +const getInferenceConfigHelpText = (esDocsBasePath: string): React.ReactNode => { + return ( + + {INFERENCE_CONFIG_DOCS.regression.linkLabel} + + ), + classification: ( + + {INFERENCE_CONFIG_DOCS.classification.linkLabel} + + ), + }} + /> + ); +}; + +const fieldsConfig: FieldsConfig = { + /* Required fields config */ + model_id: { + type: FIELD_TYPES.TEXT, + label: i18n.translate('xpack.ingestPipelines.pipelineEditor.inferenceForm.modelIDFieldLabel', { + defaultMessage: 'Model ID', + }), + deserializer: String, + helpText: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.inferenceForm.modelIDFieldHelpText', + { + defaultMessage: 'ID of the model to infer against', + } + ), + validations: [ + { + validator: emptyField( + i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.inferenceForm.patternRequiredError', + { + defaultMessage: 'A model ID value is required.', + } + ) + ), + }, + ], + }, + + /* Optional fields config */ + field_map: { + type: FIELD_TYPES.TEXT, + deserializer: to.jsonString, + serializer: from.optionalJson, + label: i18n.translate('xpack.ingestPipelines.pipelineEditor.inferenceForm.fieldMapLabel', { + defaultMessage: 'Field map (optional)', + }), + helpText: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.inferenceForm.fieldMapHelpText', + { + defaultMessage: + 'Maps document field names to the known field names of the model. Takes precedence over any mappings in the model.', + } + ), + validations: [ + { + validator: isJsonField( + i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.inferenceForm.fieldMapInvalidJSONError', + { defaultMessage: 'Invalid JSON' } + ), + { + allowEmptyString: true, + } + ), + }, + ], + }, + + inference_config: { + type: FIELD_TYPES.TEXT, + deserializer: to.jsonString, + serializer: from.optionalJson, + label: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.inferenceForm.inferenceConfigLabel', + { + defaultMessage: 'Inference configuration (optional)', + } + ), + validations: [ + { + validator: isJsonField( + i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.grokForm.patternsDefinitionsInvalidJSONError', + { defaultMessage: 'Invalid JSON' } + ), + { + allowEmptyString: true, + } + ), + }, + ], + }, +}; + +export const Inference: FunctionComponent = () => { + const { services } = useKibana(); + const esDocUrl = services.documentation.getEsDocsBasePath(); + return ( + <> + + + {'ml.inference.'} }} + /> + } + /> + + + + + + ); +}; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/join.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/join.tsx new file mode 100644 index 0000000000000..712d0106459b1 --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/join.tsx @@ -0,0 +1,71 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FunctionComponent } from 'react'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { EuiCode } from '@elastic/eui'; + +import { FIELD_TYPES, fieldValidators, UseField, Field } from '../../../../../../shared_imports'; + +import { FieldsConfig } from './shared'; +import { FieldNameField } from './common_fields/field_name_field'; +import { TargetField } from './common_fields/target_field'; + +const { emptyField } = fieldValidators; + +const fieldsConfig: FieldsConfig = { + /* Required fields config */ + separator: { + type: FIELD_TYPES.TEXT, + label: i18n.translate('xpack.ingestPipelines.pipelineEditor.joinForm.separatorFieldLabel', { + defaultMessage: 'Separator', + }), + deserializer: String, + helpText: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.joinForm.separatorFieldHelpText', + { + defaultMessage: 'Separator character', + } + ), + validations: [ + { + validator: emptyField( + i18n.translate('xpack.ingestPipelines.pipelineEditor.joinForm.separatorRequiredError', { + defaultMessage: 'A separator value is required.', + }) + ), + }, + ], + }, +}; + +export const Join: FunctionComponent = () => { + return ( + <> + + + + + {'field'}, + }} + /> + } + /> + + ); +}; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/json.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/json.tsx new file mode 100644 index 0000000000000..9d62c67460136 --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/json.tsx @@ -0,0 +1,87 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FunctionComponent, useEffect, useState } from 'react'; +import { i18n } from '@kbn/i18n'; + +import { + FIELD_TYPES, + UseField, + ToggleField, + useFormContext, +} from '../../../../../../shared_imports'; + +import { FieldsConfig, from, to } from './shared'; +import { FieldNameField } from './common_fields/field_name_field'; +import { TargetField, TARGET_FIELD_PATH } from './common_fields/target_field'; + +const ADD_TO_ROOT_FIELD_PATH = 'fields.add_to_root'; + +const fieldsConfig: FieldsConfig = { + /* Optional fields config */ + add_to_root: { + type: FIELD_TYPES.TOGGLE, + defaultValue: false, + label: i18n.translate('xpack.ingestPipelines.pipelineEditor.jsonForm.addToRootFieldLabel', { + defaultMessage: 'Add to root', + }), + deserializer: to.booleanOrUndef, + serializer: from.defaultBoolToUndef(false), + helpText: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.jsonForm.addToRootFieldHelpText', + { + defaultMessage: + 'Add the JSON object to the top level of the document. Cannot be combined with a target field.', + } + ), + }, +}; + +export const Json: FunctionComponent = () => { + const form = useFormContext(); + const [isAddToPathDisabled, setIsAddToPathDisabled] = useState(false); + useEffect(() => { + const subscription = form.subscribe(({ data: { raw: rawData } }) => { + const hasTargetField = !!rawData[TARGET_FIELD_PATH]; + if (hasTargetField && !isAddToPathDisabled) { + setIsAddToPathDisabled(true); + form.getFields()[ADD_TO_ROOT_FIELD_PATH].setValue(false); + } else if (!hasTargetField && isAddToPathDisabled) { + setIsAddToPathDisabled(false); + } + }); + return subscription.unsubscribe; + }, [form, isAddToPathDisabled]); + + return ( + <> + + + + + + + ); +}; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/shared.ts b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/shared.ts index a0a31dd3a8e93..84b308dd9cd7a 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/shared.ts +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/shared.ts @@ -6,11 +6,63 @@ import * as rt from 'io-ts'; import { isRight } from 'fp-ts/lib/Either'; -import { flow } from 'fp-ts/lib/function'; import { FieldConfig } from '../../../../../../shared_imports'; export const arrayOfStrings = rt.array(rt.string); -export const isArrayOfStrings = flow(arrayOfStrings.decode, isRight); + +export function isArrayOfStrings(v: unknown): v is string[] { + const res = arrayOfStrings.decode(v); + return isRight(res); +} + +/** + * Shared deserializer functions. + * + * These are intended to be used in @link{FieldsConfig} as the "deserializer". + * + * Example: + * { + * ... + * deserialize: to.booleanOrUndef, + * ... + * } + * + */ +export const to = { + booleanOrUndef: (v: unknown): boolean | undefined => (typeof v === 'boolean' ? v : undefined), + arrayOfStrings: (v: unknown): string[] => (isArrayOfStrings(v) ? v : []), + jsonString: (v: unknown) => (v ? JSON.stringify(v, null, 2) : '{}'), +}; + +/** + * Shared serializer functions. + * + * These are intended to be used in @link{FieldsConfig} as the "serializer". + * + * Example: + * { + * ... + * serializer: from.optionalJson, + * ... + * } + * + */ +export const from = { + /* Works with `to.jsonString` as deserializer. */ + optionalJson: (v: string) => { + if (v) { + try { + const json = JSON.parse(v); + if (Object.keys(json).length) { + return json; + } + } catch (e) { + // Ignore + } + } + }, + defaultBoolToUndef: (defaultBool: boolean) => (v: boolean) => (v === defaultBool ? undefined : v), +}; export type FieldsConfig = Record; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/shared/map_processor_type_to_form.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/shared/map_processor_type_to_form.tsx index b5f7df9117f35..854c6632ab94a 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/shared/map_processor_type_to_form.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/shared/map_processor_type_to_form.tsx @@ -18,6 +18,16 @@ import { Dissect, DotExpander, Drop, + Enrich, + Fail, + Foreach, + GeoIP, + Grok, + Gsub, + HtmlStrip, + Inference, + Join, + Json, } from '../manage_processor_form/processors'; // import { SetProcessor } from './processors/set'; @@ -106,63 +116,70 @@ export const mapProcessorTypeToDescriptor: MapProcessorTypeToDescriptor = { }), }, enrich: { - FieldsComponent: undefined, // TODO: Implement - docLinkPath: '/enrich-processor.html', + FieldsComponent: Enrich, + docLinkPath: '/ingest-enriching-data.html', label: i18n.translate('xpack.ingestPipelines.processors.label.enrich', { defaultMessage: 'Enrich', }), }, fail: { - FieldsComponent: undefined, // TODO: Implement + FieldsComponent: Fail, docLinkPath: '/fail-processor.html', label: i18n.translate('xpack.ingestPipelines.processors.label.fail', { defaultMessage: 'Fail', }), }, foreach: { - FieldsComponent: undefined, // TODO: Implement + FieldsComponent: Foreach, docLinkPath: '/foreach-processor.html', label: i18n.translate('xpack.ingestPipelines.processors.label.foreach', { defaultMessage: 'Foreach', }), }, geoip: { - FieldsComponent: undefined, // TODO: Implement + FieldsComponent: GeoIP, docLinkPath: '/geoip-processor.html', label: i18n.translate('xpack.ingestPipelines.processors.label.geoip', { defaultMessage: 'GeoIP', }), }, + grok: { + FieldsComponent: Grok, + docLinkPath: '/grok-processor.html', + label: i18n.translate('xpack.ingestPipelines.processors.label.grok', { + defaultMessage: 'Grok', + }), + }, gsub: { - FieldsComponent: undefined, + FieldsComponent: Gsub, docLinkPath: '/gsub-processor.html', label: i18n.translate('xpack.ingestPipelines.processors.label.gsub', { defaultMessage: 'Gsub', }), }, html_strip: { - FieldsComponent: undefined, // TODO: Implement + FieldsComponent: HtmlStrip, docLinkPath: '/htmlstrip-processor.html', label: i18n.translate('xpack.ingestPipelines.processors.label.htmlStrip', { defaultMessage: 'HTML strip', }), }, inference: { - FieldsComponent: undefined, // TODO: Implement + FieldsComponent: Inference, docLinkPath: '/inference-processor.html', label: i18n.translate('xpack.ingestPipelines.processors.label.inference', { defaultMessage: 'Inference', }), }, join: { - FieldsComponent: undefined, // TODO: Implement + FieldsComponent: Join, docLinkPath: '/join-processor.html', label: i18n.translate('xpack.ingestPipelines.processors.label.join', { defaultMessage: 'Join', }), }, json: { - FieldsComponent: undefined, // TODO: Implement + FieldsComponent: Json, docLinkPath: '/json-processor.html', label: i18n.translate('xpack.ingestPipelines.processors.label.json', { defaultMessage: 'JSON', @@ -268,13 +285,6 @@ export const mapProcessorTypeToDescriptor: MapProcessorTypeToDescriptor = { defaultMessage: 'Set', }), }, - grok: { - FieldsComponent: undefined, - docLinkPath: '/grok-processor.html', - label: i18n.translate('xpack.ingestPipelines.processors.label.grok', { - defaultMessage: 'Grok', - }), - }, }; export type ProcessorType = keyof typeof mapProcessorTypeToDescriptor; diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 0fd9e437a5c3d..6a7737d367005 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -9734,14 +9734,10 @@ "xpack.ingestPipelines.pipelineEditor.deleteModal.deleteDescription": "このプロセッサーとエラーハンドラーを削除します。", "xpack.ingestPipelines.pipelineEditor.dropZoneButton.moveHereToolTip": "ここに移動", "xpack.ingestPipelines.pipelineEditor.dropZoneButton.unavailableToolTip": "ここに移動できません", - "xpack.ingestPipelines.pipelineEditor.gsubForm.fieldFieldLabel": "フィールド", - "xpack.ingestPipelines.pipelineEditor.gsubForm.fieldRequiredError": "フィールド値が必要です。", - "xpack.ingestPipelines.pipelineEditor.gsubForm.ignoreMissingFieldLabel": "不足しテイル項目を無視", "xpack.ingestPipelines.pipelineEditor.gsubForm.patternFieldLabel": "パターン", "xpack.ingestPipelines.pipelineEditor.gsubForm.patternRequiredError": "パターン値が必要です。", "xpack.ingestPipelines.pipelineEditor.gsubForm.replacementFieldLabel": "置換", "xpack.ingestPipelines.pipelineEditor.gsubForm.replacementRequiredError": "置換値が必要です。", - "xpack.ingestPipelines.pipelineEditor.gsubForm.targetFieldLabel": "ターゲットフィールド(任意)", "xpack.ingestPipelines.pipelineEditor.item.cancelMoveButtonAriaLabel": "移動のキャンセル", "xpack.ingestPipelines.pipelineEditor.item.descriptionPlaceholder": "説明なし", "xpack.ingestPipelines.pipelineEditor.item.editButtonAriaLabel": "このプロセッサーを編集", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 02e6da8c3f812..4d0186141f38d 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -9737,14 +9737,10 @@ "xpack.ingestPipelines.pipelineEditor.deleteModal.deleteDescription": "删除此处理器和其失败时处理程序。", "xpack.ingestPipelines.pipelineEditor.dropZoneButton.moveHereToolTip": "移到此处", "xpack.ingestPipelines.pipelineEditor.dropZoneButton.unavailableToolTip": "无法移到此处", - "xpack.ingestPipelines.pipelineEditor.gsubForm.fieldFieldLabel": "字段", - "xpack.ingestPipelines.pipelineEditor.gsubForm.fieldRequiredError": "字段值必填。", - "xpack.ingestPipelines.pipelineEditor.gsubForm.ignoreMissingFieldLabel": "忽略缺失", "xpack.ingestPipelines.pipelineEditor.gsubForm.patternFieldLabel": "模式", "xpack.ingestPipelines.pipelineEditor.gsubForm.patternRequiredError": "模式值必填。", "xpack.ingestPipelines.pipelineEditor.gsubForm.replacementFieldLabel": "替换", "xpack.ingestPipelines.pipelineEditor.gsubForm.replacementRequiredError": "替换值必填。", - "xpack.ingestPipelines.pipelineEditor.gsubForm.targetFieldLabel": "目标字段(可选)", "xpack.ingestPipelines.pipelineEditor.item.cancelMoveButtonAriaLabel": "取消移动", "xpack.ingestPipelines.pipelineEditor.item.descriptionPlaceholder": "无描述", "xpack.ingestPipelines.pipelineEditor.item.editButtonAriaLabel": "编辑此处理器", From 0d8a4613e487faa1becf25152a86c718ed9aad38 Mon Sep 17 00:00:00 2001 From: Zacqary Adam Xeper Date: Thu, 20 Aug 2020 13:22:04 -0500 Subject: [PATCH 06/45] [Metrics UI] Support percentage format in threshold alerts (#72701) Co-authored-by: Elastic Machine --- .../utils/corrected_percent_convert.test.ts | 52 ++++++++++++ .../common/utils/corrected_percent_convert.ts | 16 ++++ .../components/expression_row.test.tsx | 84 +++++++++++++++++++ .../components/expression_row.tsx | 30 +++++-- .../metric_threshold_executor.test.ts | 30 +++++++ .../metric_threshold_executor.ts | 28 ++++++- 6 files changed, 232 insertions(+), 8 deletions(-) create mode 100644 x-pack/plugins/infra/common/utils/corrected_percent_convert.test.ts create mode 100644 x-pack/plugins/infra/common/utils/corrected_percent_convert.ts create mode 100644 x-pack/plugins/infra/public/alerting/metric_threshold/components/expression_row.test.tsx diff --git a/x-pack/plugins/infra/common/utils/corrected_percent_convert.test.ts b/x-pack/plugins/infra/common/utils/corrected_percent_convert.test.ts new file mode 100644 index 0000000000000..ab608f331b884 --- /dev/null +++ b/x-pack/plugins/infra/common/utils/corrected_percent_convert.test.ts @@ -0,0 +1,52 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { decimalToPct, pctToDecimal } from './corrected_percent_convert'; + +describe('decimalToPct', () => { + test('should retain correct floating point precision up to 10 decimal places', () => { + // Most of these cases would still work fine just doing x * 100 instead of passing it through + // decimalToPct, but the function still needs to work regardless + expect(decimalToPct(0)).toBe(0); + expect(decimalToPct(0.1)).toBe(10); + expect(decimalToPct(0.01)).toBe(1); + expect(decimalToPct(0.014)).toBe(1.4); + expect(decimalToPct(0.0141)).toBe(1.41); + expect(decimalToPct(0.01414)).toBe(1.414); + // This case is known to fail without decimalToPct; vanilla JS 0.014141 * 100 === 1.4141000000000001 + expect(decimalToPct(0.014141)).toBe(1.4141); + expect(decimalToPct(0.0141414)).toBe(1.41414); + expect(decimalToPct(0.01414141)).toBe(1.414141); + expect(decimalToPct(0.014141414)).toBe(1.4141414); + }); + test('should also work with values greater than 1', () => { + expect(decimalToPct(2)).toBe(200); + expect(decimalToPct(2.1)).toBe(210); + expect(decimalToPct(2.14)).toBe(214); + expect(decimalToPct(2.14141414)).toBe(214.141414); + }); +}); + +describe('pctToDecimal', () => { + test('should retain correct floating point precision up to 10 decimal places', () => { + expect(pctToDecimal(0)).toBe(0); + expect(pctToDecimal(10)).toBe(0.1); + expect(pctToDecimal(1)).toBe(0.01); + expect(pctToDecimal(1.4)).toBe(0.014); + expect(pctToDecimal(1.41)).toBe(0.0141); + expect(pctToDecimal(1.414)).toBe(0.01414); + expect(pctToDecimal(1.4141)).toBe(0.014141); + expect(pctToDecimal(1.41414)).toBe(0.0141414); + expect(pctToDecimal(1.414141)).toBe(0.01414141); + expect(pctToDecimal(1.4141414)).toBe(0.014141414); + }); + test('should also work with values greater than 100%', () => { + expect(pctToDecimal(200)).toBe(2); + expect(pctToDecimal(210)).toBe(2.1); + expect(pctToDecimal(214)).toBe(2.14); + expect(pctToDecimal(214.141414)).toBe(2.14141414); + }); +}); diff --git a/x-pack/plugins/infra/common/utils/corrected_percent_convert.ts b/x-pack/plugins/infra/common/utils/corrected_percent_convert.ts new file mode 100644 index 0000000000000..a8e3db5133cf5 --- /dev/null +++ b/x-pack/plugins/infra/common/utils/corrected_percent_convert.ts @@ -0,0 +1,16 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +const correctedPctConvert = (v: number, decimalToPct: boolean) => { + // Correct floating point precision + const replacementPattern = decimalToPct ? new RegExp(/0?\./) : '.'; + const numberOfDigits = String(v).replace(replacementPattern, '').length; + const multipliedValue = decimalToPct ? v * 100 : v / 100; + return parseFloat(multipliedValue.toPrecision(numberOfDigits)); +}; + +export const decimalToPct = (v: number) => correctedPctConvert(v, true); +export const pctToDecimal = (v: number) => correctedPctConvert(v, false); diff --git a/x-pack/plugins/infra/public/alerting/metric_threshold/components/expression_row.test.tsx b/x-pack/plugins/infra/public/alerting/metric_threshold/components/expression_row.test.tsx new file mode 100644 index 0000000000000..d5be8a2ec2675 --- /dev/null +++ b/x-pack/plugins/infra/public/alerting/metric_threshold/components/expression_row.test.tsx @@ -0,0 +1,84 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { mountWithIntl, nextTick } from 'test_utils/enzyme_helpers'; +import { MetricExpression } from '../types'; +import React from 'react'; +import { ExpressionRow } from './expression_row'; +import { act } from 'react-dom/test-utils'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { Comparator } from '../../../../server/lib/alerting/metric_threshold/types'; + +jest.mock('../../../containers/source/use_source_via_http', () => ({ + useSourceViaHttp: () => ({ + source: { id: 'default' }, + createDerivedIndexPattern: () => ({ fields: [], title: 'metricbeat-*' }), + }), +})); + +describe('ExpressionRow', () => { + async function setup(expression: MetricExpression) { + const wrapper = mountWithIntl( + {}} + addExpression={() => {}} + key={1} + expressionId={1} + setAlertParams={() => {}} + errors={{ + aggField: [], + timeSizeUnit: [], + timeWindowSize: [], + }} + expression={expression} + /> + ); + + const update = async () => + await act(async () => { + await nextTick(); + wrapper.update(); + }); + + await update(); + + return { wrapper, update }; + } + + it('should display thresholds as a percentage for pct metrics', async () => { + const expression = { + metric: 'system.cpu.user.pct', + comparator: Comparator.GT, + threshold: [0.5], + timeSize: 1, + timeUnit: 'm', + aggType: 'avg', + }; + const { wrapper } = await setup(expression as MetricExpression); + const [valueMatch] = wrapper.html().match('50') ?? []; + expect(valueMatch).toBeTruthy(); + }); + + it('should display thresholds as a decimal for all other metrics', async () => { + const expression = { + metric: 'system.load.1', + comparator: Comparator.GT, + threshold: [0.5], + timeSize: 1, + timeUnit: 'm', + aggType: 'avg', + }; + const { wrapper } = await setup(expression as MetricExpression); + const [valueMatch] = + wrapper.html().match('0.5') ?? []; + expect(valueMatch).toBeTruthy(); + }); +}); diff --git a/x-pack/plugins/infra/public/alerting/metric_threshold/components/expression_row.tsx b/x-pack/plugins/infra/public/alerting/metric_threshold/components/expression_row.tsx index 653b9e1d5c308..1487557bde3a0 100644 --- a/x-pack/plugins/infra/public/alerting/metric_threshold/components/expression_row.tsx +++ b/x-pack/plugins/infra/public/alerting/metric_threshold/components/expression_row.tsx @@ -3,10 +3,11 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import React, { useCallback, useState } from 'react'; +import React, { useCallback, useState, useMemo } from 'react'; import { i18n } from '@kbn/i18n'; -import { EuiFlexGroup, EuiFlexItem, EuiButtonIcon, EuiSpacer } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiButtonIcon, EuiSpacer, EuiText } from '@elastic/eui'; import { IFieldType } from 'src/plugins/data/public'; +import { pctToDecimal, decimalToPct } from '../../../../common/utils/corrected_percent_convert'; import { WhenExpression, OfExpression, @@ -76,6 +77,8 @@ export const ExpressionRow: React.FC = (props) => { threshold = [], } = expression; + const isMetricPct = useMemo(() => metric && metric.endsWith('.pct'), [metric]); + const updateAggType = useCallback( (at: string) => { setAlertParams(expressionId, { @@ -102,14 +105,22 @@ export const ExpressionRow: React.FC = (props) => { ); const updateThreshold = useCallback( - (t) => { + (enteredThreshold) => { + const t = isMetricPct + ? enteredThreshold.map((v: number) => pctToDecimal(v)) + : enteredThreshold; if (t.join() !== expression.threshold.join()) { setAlertParams(expressionId, { ...expression, threshold: t }); } }, - [expressionId, expression, setAlertParams] + [expressionId, expression, isMetricPct, setAlertParams] ); + const displayedThreshold = useMemo(() => { + if (isMetricPct) return threshold.map((v) => decimalToPct(v)); + return threshold; + }, [threshold, isMetricPct]); + return ( <> @@ -149,13 +160,22 @@ export const ExpressionRow: React.FC = (props) => { + {isMetricPct && ( +
+ % +
+ )} {canDelete && ( diff --git a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.test.ts b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.test.ts index fa705798baf7a..3a52bb6b6ce71 100644 --- a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.test.ts +++ b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.test.ts @@ -387,6 +387,36 @@ describe('The metric threshold alert type', () => { // expect(getState(instanceID).alertState).toBe(AlertStates.OK); // }); // }); + + describe('querying a metric with a percentage metric', () => { + const instanceID = '*'; + const execute = () => + executor({ + services, + params: { + sourceId: 'default', + criteria: [ + { + ...baseCriterion, + metric: 'test.metric.pct', + comparator: Comparator.GT, + threshold: [0.75], + }, + ], + }, + }); + test('reports values converted from decimals to percentages to the action context', async () => { + const now = 1577858400000; + await execute(); + const { action } = mostRecentAction(instanceID); + expect(action.group).toBe('*'); + expect(action.reason).toContain('current value is 100%'); + expect(action.reason).toContain('threshold of 75%'); + expect(action.threshold.condition0[0]).toBe('75%'); + expect(action.value.condition0).toBe('100%'); + expect(action.timestamp).toBe(new Date(now).toISOString()); + }); + }); }); const createMockStaticConfiguration = (sources: any) => ({ diff --git a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.ts b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.ts index b2a8f0281b9e2..9265e8089e915 100644 --- a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.ts +++ b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.ts @@ -14,6 +14,7 @@ import { buildNoDataAlertReason, stateToAlertMessage, } from '../common/messages'; +import { createFormatter } from '../../../../common/formatters'; import { AlertStates } from './types'; import { evaluateAlert } from './lib/evaluate_alert'; @@ -59,7 +60,7 @@ export const createMetricThresholdExecutor = (libs: InfraBackendLibs) => let reason; if (nextState === AlertStates.ALERT) { reason = alertResults - .map((result) => buildFiredAlertReason(result[group] as any)) + .map((result) => buildFiredAlertReason(formatAlertResult(result[group]) as any)) .join('\n'); } if (alertOnNoData) { @@ -83,8 +84,14 @@ export const createMetricThresholdExecutor = (libs: InfraBackendLibs) => alertState: stateToAlertMessage[nextState], reason, timestamp, - value: mapToConditionsLookup(alertResults, (result) => result[group].currentValue), - threshold: mapToConditionsLookup(criteria, (c) => c.threshold), + value: mapToConditionsLookup( + alertResults, + (result) => formatAlertResult(result[group]).currentValue + ), + threshold: mapToConditionsLookup( + alertResults, + (result) => formatAlertResult(result[group]).threshold + ), metric: mapToConditionsLookup(criteria, (c) => c.metric), }); } @@ -113,3 +120,18 @@ const mapToConditionsLookup = ( (result: Record, value, i) => ({ ...result, [`condition${i}`]: value }), {} ); + +const formatAlertResult = (alertResult: { + metric: string; + currentValue: number; + threshold: number[]; +}) => { + const { metric, currentValue, threshold } = alertResult; + if (!metric.endsWith('.pct')) return alertResult; + const formatter = createFormatter('percent'); + return { + ...alertResult, + currentValue: formatter(currentValue), + threshold: Array.isArray(threshold) ? threshold.map((v: number) => formatter(v)) : threshold, + }; +}; From bcca9331b568659a908a73d3f6b6c64bd75e0623 Mon Sep 17 00:00:00 2001 From: Zacqary Adam Xeper Date: Thu, 20 Aug 2020 13:28:10 -0500 Subject: [PATCH 07/45] [Metrics UI] Get custom metrics working in inventory alerts with limited UI (#75073) --- .../formatters}/get_custom_metric_label.ts | 2 +- .../inventory/components/alert_flyout.tsx | 17 +- .../inventory/components/expression.test.tsx | 186 ++++++++++++++++++ .../inventory/components/expression.tsx | 86 ++++++-- .../alerting/inventory/components/metric.tsx | 7 +- .../hooks/use_inventory_alert_prefill.ts | 8 +- .../waffle/metric_control/index.tsx | 2 +- .../metric_control/metrics_context_menu.tsx | 2 +- .../metric_control/metrics_edit_mode.tsx | 2 +- .../hooks/use_waffle_options.test.ts | 19 ++ .../hooks/use_waffle_options.ts | 3 +- .../evaluate_condition.ts | 15 +- .../inventory_metric_threshold_executor.ts | 33 ++-- ...r_inventory_metric_threshold_alert_type.ts | 9 + .../inventory_metric_threshold/types.ts | 2 + 15 files changed, 348 insertions(+), 45 deletions(-) rename x-pack/plugins/infra/{public/pages/metrics/inventory_view/components/waffle/metric_control => common/formatters}/get_custom_metric_label.ts (91%) create mode 100644 x-pack/plugins/infra/public/alerting/inventory/components/expression.test.tsx diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/get_custom_metric_label.ts b/x-pack/plugins/infra/common/formatters/get_custom_metric_label.ts similarity index 91% rename from x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/get_custom_metric_label.ts rename to x-pack/plugins/infra/common/formatters/get_custom_metric_label.ts index 495cc8197d2e7..3be5986d489d3 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/get_custom_metric_label.ts +++ b/x-pack/plugins/infra/common/formatters/get_custom_metric_label.ts @@ -5,7 +5,7 @@ */ import { i18n } from '@kbn/i18n'; -import { SnapshotCustomMetricInput } from '../../../../../../../common/http_api/snapshot_api'; +import { SnapshotCustomMetricInput } from '../http_api/snapshot_api'; export const getCustomMetricLabel = (metric: SnapshotCustomMetricInput) => { const METRIC_LABELS = { diff --git a/x-pack/plugins/infra/public/alerting/inventory/components/alert_flyout.tsx b/x-pack/plugins/infra/public/alerting/inventory/components/alert_flyout.tsx index 804ff9602c81c..834afefd74712 100644 --- a/x-pack/plugins/infra/public/alerting/inventory/components/alert_flyout.tsx +++ b/x-pack/plugins/infra/public/alerting/inventory/components/alert_flyout.tsx @@ -12,6 +12,7 @@ import { useKibana } from '../../../../../../../src/plugins/kibana_react/public' import { METRIC_INVENTORY_THRESHOLD_ALERT_TYPE_ID } from '../../../../server/lib/alerting/inventory_metric_threshold/types'; import { InfraWaffleMapOptions } from '../../../lib/lib'; import { InventoryItemType } from '../../../../common/inventory_models/types'; +import { useAlertPrefillContext } from '../../../alerting/use_alert_prefill'; interface Props { visible?: boolean; @@ -21,16 +22,24 @@ interface Props { setVisible: React.Dispatch>; } -export const AlertFlyout = (props: Props) => { +export const AlertFlyout = ({ options, nodeType, filter, visible, setVisible }: Props) => { const { triggersActionsUI } = useContext(TriggerActionsContext); const { services } = useKibana(); + const { inventoryPrefill } = useAlertPrefillContext(); + const { customMetrics } = inventoryPrefill; + return ( <> {triggersActionsUI && ( { }} > ({ + useSourceViaHttp: () => ({ + source: { id: 'default' }, + createDerivedIndexPattern: () => ({ fields: [], title: 'metricbeat-*' }), + }), +})); + +const exampleCustomMetric = { + id: 'this-is-an-id', + field: 'some.system.field', + aggregation: 'rate', + type: 'custom', +} as SnapshotCustomMetricInput; + +describe('Expression', () => { + async function setup(currentOptions: AlertContextMeta) { + const alertParams = { + criteria: [], + nodeType: undefined, + filterQueryText: '', + }; + + const mocks = coreMock.createSetup(); + const startMocks = coreMock.createStart(); + const [ + { + application: { capabilities }, + }, + ] = await mocks.getStartServices(); + + const context: AlertsContextValue = { + http: mocks.http, + toastNotifications: mocks.notifications.toasts, + actionTypeRegistry: actionTypeRegistryMock.create() as any, + alertTypeRegistry: alertTypeRegistryMock.create() as any, + docLinks: startMocks.docLinks, + capabilities: { + ...capabilities, + actions: { + delete: true, + save: true, + show: true, + }, + }, + metadata: currentOptions, + }; + + const wrapper = mountWithIntl( + Reflect.set(alertParams, key, value)} + setAlertProperty={() => {}} + /> + ); + + const update = async () => + await act(async () => { + await nextTick(); + wrapper.update(); + }); + + await update(); + + return { wrapper, update, alertParams }; + } + + it('should prefill the alert using the context metadata', async () => { + const currentOptions = { + filter: 'foo', + nodeType: 'pod', + customMetrics: [], + options: { metric: { type: 'memory' } }, + }; + const { alertParams } = await setup(currentOptions as AlertContextMeta); + expect(alertParams.nodeType).toBe('pod'); + expect(alertParams.filterQueryText).toBe('foo'); + expect(alertParams.criteria).toEqual([ + { + metric: 'memory', + comparator: Comparator.GT, + threshold: [], + timeSize: 1, + timeUnit: 'm', + }, + ]); + }); + describe('using custom metrics', () => { + it('should prefill the alert using the context metadata', async () => { + const currentOptions = { + filter: '', + nodeType: 'tx', + customMetrics: [exampleCustomMetric], + options: { metric: exampleCustomMetric }, + }; + const { alertParams, update } = await setup(currentOptions as AlertContextMeta); + await update(); + expect(alertParams.nodeType).toBe('tx'); + expect(alertParams.filterQueryText).toBe(''); + expect(alertParams.criteria).toEqual([ + { + metric: 'custom', + comparator: Comparator.GT, + threshold: [], + timeSize: 1, + timeUnit: 'm', + customMetric: exampleCustomMetric, + }, + ]); + }); + }); +}); + +describe('ExpressionRow', () => { + async function setup(expression: InventoryMetricConditions) { + const wrapper = mountWithIntl( + {}} + addExpression={() => {}} + key={1} + expressionId={1} + setAlertParams={() => {}} + errors={{ + aggField: [], + timeSizeUnit: [], + timeWindowSize: [], + metric: [], + }} + expression={expression} + alertsContextMetadata={{ + customMetrics: [], + }} + /> + ); + + const update = async () => + await act(async () => { + await nextTick(); + wrapper.update(); + }); + + await update(); + + return { wrapper, update }; + } + const expression = { + metric: 'custom', + comparator: Comparator.GT, + threshold: [], + timeSize: 1, + timeUnit: 'm', + customMetric: exampleCustomMetric, + }; + + it('loads custom metrics passed in through the expression, even with an empty context', async () => { + const { wrapper } = await setup(expression as InventoryMetricConditions); + const [valueMatch] = + wrapper.html().match('Rate of some.system.field') ?? + []; + expect(valueMatch).toBeTruthy(); + }); +}); diff --git a/x-pack/plugins/infra/public/alerting/inventory/components/expression.tsx b/x-pack/plugins/infra/public/alerting/inventory/components/expression.tsx index 7ca17617871ff..78cabcf354437 100644 --- a/x-pack/plugins/infra/public/alerting/inventory/components/expression.tsx +++ b/x-pack/plugins/infra/public/alerting/inventory/components/expression.tsx @@ -4,7 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { debounce, pick } from 'lodash'; +import { set } from '@elastic/safer-lodash-set'; +import { debounce, pick, uniqBy, isEqual } from 'lodash'; import { Unit } from '@elastic/datemath'; import React, { useCallback, useMemo, useEffect, useState, ChangeEvent } from 'react'; import { @@ -22,6 +23,7 @@ import { } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; +import { getCustomMetricLabel } from '../../../../common/formatters/get_custom_metric_label'; import { toMetricOpt } from '../../../../common/snapshot_metric_i18n'; import { AlertPreview } from '../../common'; import { METRIC_INVENTORY_THRESHOLD_ALERT_TYPE_ID } from '../../../../common/alerting/metrics'; @@ -49,22 +51,31 @@ import { hostMetricTypes } from '../../../../common/inventory_models/host/toolba import { containerMetricTypes } from '../../../../common/inventory_models/container/toolbar_items'; import { podMetricTypes } from '../../../../common/inventory_models/pod/toolbar_items'; import { findInventoryModel } from '../../../../common/inventory_models'; -import { InventoryItemType, SnapshotMetricType } from '../../../../common/inventory_models/types'; +import { + InventoryItemType, + SnapshotMetricType, + SnapshotMetricTypeRT, +} from '../../../../common/inventory_models/types'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { InventoryMetricConditions } from '../../../../server/lib/alerting/inventory_metric_threshold/types'; import { MetricExpression } from './metric'; import { NodeTypeExpression } from './node_type'; import { InfraWaffleMapOptions } from '../../../lib/lib'; import { convertKueryToElasticSearchQuery } from '../../../utils/kuery'; +import { + SnapshotCustomMetricInput, + SnapshotCustomMetricInputRT, +} from '../../../../common/http_api/snapshot_api'; import { validateMetricThreshold } from './validation'; const FILTER_TYPING_DEBOUNCE_MS = 500; -interface AlertContextMeta { +export interface AlertContextMeta { options?: Partial; nodeType?: InventoryItemType; filter?: string; + customMetrics?: SnapshotCustomMetricInput[]; } interface Props { @@ -89,6 +100,7 @@ const defaultExpression = { threshold: [], timeSize: 1, timeUnit: 'm', + customMetric: undefined, } as InventoryMetricConditions; export const Expressions: React.FC = (props) => { @@ -204,6 +216,9 @@ export const Expressions: React.FC = (props) => { { ...defaultExpression, metric: md.options.metric!.type, + customMetric: SnapshotCustomMetricInputRT.is(md.options.metric) + ? md.options.metric + : undefined, } as InventoryMetricConditions, ]); } else { @@ -282,6 +297,7 @@ export const Expressions: React.FC = (props) => { setAlertParams={updateParams} errors={errors[idx] || emptyError} expression={e || {}} + alertsContextMetadata={alertsContext.metadata} /> ); })} @@ -389,6 +405,7 @@ interface ExpressionRowProps { addExpression(): void; remove(id: number): void; setAlertParams(id: number, params: Partial): void; + alertsContextMetadata: AlertsContextValue['metadata']; } const StyledExpressionRow = euiStyled(EuiFlexGroup)` @@ -402,14 +419,48 @@ const StyledExpression = euiStyled.div` `; export const ExpressionRow: React.FC = (props) => { - const { setAlertParams, expression, errors, expressionId, remove, canDelete } = props; - const { metric, comparator = Comparator.GT, threshold = [] } = expression; + const { + setAlertParams, + expression, + errors, + expressionId, + remove, + canDelete, + alertsContextMetadata, + } = props; + const { metric, comparator = Comparator.GT, threshold = [], customMetric } = expression; + const [customMetrics, updateCustomMetrics] = useState([]); + + // Create and uniquify a list of custom metrics including: + // - The alert metadata context (which only gives us custom metrics on the inventory page) + // - The custom metric stored in the expression (necessary when editing this alert without having + // access to the metadata context) + // - Whatever custom metrics were previously stored in this list (to preserve the custom metric in the dropdown + // if the user edits the alert and switches away from the custom metric) + useEffect(() => { + const ctxCustomMetrics = alertsContextMetadata?.customMetrics ?? []; + const expressionCustomMetrics = customMetric ? [customMetric] : []; + const newCustomMetrics = uniqBy( + [...customMetrics, ...ctxCustomMetrics, ...expressionCustomMetrics], + (cm: SnapshotCustomMetricInput) => cm.id + ); + if (!isEqual(customMetrics, newCustomMetrics)) updateCustomMetrics(newCustomMetrics); + }, [alertsContextMetadata, customMetric, customMetrics, updateCustomMetrics]); const updateMetric = useCallback( - (m?: SnapshotMetricType) => { - setAlertParams(expressionId, { ...expression, metric: m }); + (m?: SnapshotMetricType | string) => { + const newMetric = SnapshotMetricTypeRT.is(m) ? m : 'custom'; + const newAlertParams = { ...expression, metric: newMetric }; + if (newMetric === 'custom' && customMetrics) { + set( + newAlertParams, + 'customMetric', + customMetrics.find((cm) => cm.id === m) + ); + } + setAlertParams(expressionId, newAlertParams); }, - [expressionId, expression, setAlertParams] + [expressionId, expression, setAlertParams, customMetrics] ); const updateComparator = useCallback( @@ -446,6 +497,7 @@ export const ExpressionRow: React.FC = (props) => { break; case 'host': myMetrics = hostMetricTypes; + break; case 'pod': myMetrics = podMetricTypes; @@ -454,8 +506,17 @@ export const ExpressionRow: React.FC = (props) => { myMetrics = containerMetricTypes; break; } - return myMetrics.map(toMetricOpt); - }, [props.nodeType]); + const baseMetricOpts = myMetrics.map(toMetricOpt); + const customMetricOpts = customMetrics + ? customMetrics.map((m, i) => ({ + text: getCustomMetricLabel(m), + value: m.id, + })) + : []; + return [...baseMetricOpts, ...customMetricOpts]; + }, [props.nodeType, customMetrics]); + + const selectedMetricValue = metric === 'custom' && customMetric ? customMetric.id : metric!; return ( <> @@ -465,8 +526,8 @@ export const ExpressionRow: React.FC = (props) => { v?.value === metric)?.text || '', + value: selectedMetricValue, + text: ofFields.find((v) => v?.value === selectedMetricValue)?.text || '', }} metrics={ ofFields.filter((m) => m !== undefined && m.value !== undefined) as Array<{ @@ -568,4 +629,5 @@ const metricUnit: Record = { s3DownloadBytes: { label: 'bytes' }, sqsOldestMessage: { label: 'seconds' }, rdsLatency: { label: 'ms' }, + custom: { label: '' }, }; diff --git a/x-pack/plugins/infra/public/alerting/inventory/components/metric.tsx b/x-pack/plugins/infra/public/alerting/inventory/components/metric.tsx index ff859a95a3d9d..2e5ccbe1a4276 100644 --- a/x-pack/plugins/infra/public/alerting/inventory/components/metric.tsx +++ b/x-pack/plugins/infra/public/alerting/inventory/components/metric.tsx @@ -18,13 +18,12 @@ import { import { EuiPopoverTitle, EuiButtonIcon } from '@elastic/eui'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { IErrorObject } from '../../../../../triggers_actions_ui/public/types'; -import { SnapshotMetricType } from '../../../../common/inventory_models/types'; interface Props { - metric?: { value: SnapshotMetricType; text: string }; + metric?: { value: string; text: string }; metrics: Array<{ value: string; text: string }>; errors: IErrorObject; - onChange: (metric?: SnapshotMetricType) => void; + onChange: (metric?: string) => void; popupPosition?: | 'upCenter' | 'upLeft' @@ -104,7 +103,7 @@ export const MetricExpression = ({ metric, metrics, errors, onChange, popupPosit renderOption={(o: any) => o.label} onChange={(selectedOptions) => { if (selectedOptions.length > 0) { - onChange(selectedOptions[0].value as SnapshotMetricType); + onChange(selectedOptions[0].value); setAggFieldPopoverOpen(false); } else { onChange(); diff --git a/x-pack/plugins/infra/public/alerting/inventory/hooks/use_inventory_alert_prefill.ts b/x-pack/plugins/infra/public/alerting/inventory/hooks/use_inventory_alert_prefill.ts index d659057b95ed9..a57f9cafa5e19 100644 --- a/x-pack/plugins/infra/public/alerting/inventory/hooks/use_inventory_alert_prefill.ts +++ b/x-pack/plugins/infra/public/alerting/inventory/hooks/use_inventory_alert_prefill.ts @@ -5,20 +5,26 @@ */ import { useState } from 'react'; -import { SnapshotMetricInput } from '../../../../common/http_api/snapshot_api'; +import { + SnapshotMetricInput, + SnapshotCustomMetricInput, +} from '../../../../common/http_api/snapshot_api'; import { InventoryItemType } from '../../../../common/inventory_models/types'; export const useInventoryAlertPrefill = () => { const [nodeType, setNodeType] = useState('host'); const [filterQuery, setFilterQuery] = useState(); const [metric, setMetric] = useState({ type: 'cpu' }); + const [customMetrics, setCustomMetrics] = useState([]); return { nodeType, filterQuery, metric, + customMetrics, setNodeType, setFilterQuery, setMetric, + setCustomMetrics, }; }; diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/index.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/index.tsx index aae787c8c0395..96169810e02a8 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/index.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/index.tsx @@ -8,13 +8,13 @@ import { EuiPopover } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React, { useState, useCallback } from 'react'; import { IFieldType } from 'src/plugins/data/public'; +import { getCustomMetricLabel } from '../../../../../../../common/formatters/get_custom_metric_label'; import { SnapshotMetricInput, SnapshotCustomMetricInput, SnapshotCustomMetricInputRT, } from '../../../../../../../common/http_api/snapshot_api'; import { CustomMetricForm } from './custom_metric_form'; -import { getCustomMetricLabel } from './get_custom_metric_label'; import { MetricsContextMenu } from './metrics_context_menu'; import { ModeSwitcher } from './mode_switcher'; import { MetricsEditMode } from './metrics_edit_mode'; diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/metrics_context_menu.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/metrics_context_menu.tsx index 7ab90297ebbb3..71a000d3165b6 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/metrics_context_menu.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/metrics_context_menu.tsx @@ -5,6 +5,7 @@ */ import React, { useCallback } from 'react'; import { EuiContextMenuPanelDescriptor, EuiContextMenu } from '@elastic/eui'; +import { getCustomMetricLabel } from '../../../../../../../common/formatters/get_custom_metric_label'; import { SnapshotMetricInput, SnapshotCustomMetricInput, @@ -14,7 +15,6 @@ import { SnapshotMetricTypeRT, SnapshotMetricType, } from '../../../../../../../common/inventory_models/types'; -import { getCustomMetricLabel } from './get_custom_metric_label'; interface Props { options: Array<{ text: string; value: string }>; diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/metrics_edit_mode.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/metrics_edit_mode.tsx index 649dcc4282d67..e75885ccbc917 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/metrics_edit_mode.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/metrics_edit_mode.tsx @@ -6,8 +6,8 @@ import React from 'react'; import { EuiFlexItem, EuiFlexGroup, EuiButtonIcon } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import { getCustomMetricLabel } from '../../../../../../../common/formatters/get_custom_metric_label'; import { SnapshotCustomMetricInput } from '../../../../../../../common/http_api/snapshot_api'; -import { getCustomMetricLabel } from './get_custom_metric_label'; import { EuiTheme, withTheme, diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_options.test.ts b/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_options.test.ts index 579073e9500d0..d44d8fca4faba 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_options.test.ts +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_options.test.ts @@ -20,6 +20,7 @@ jest.mock('react-router-dom', () => ({ // reassign them, so we can't make these both part of the same object let PREFILL_NODETYPE: WaffleOptionsState['nodeType'] | undefined; let PREFILL_METRIC: WaffleOptionsState['metric'] | undefined; +let PREFILL_CUSTOM_METRICS: WaffleOptionsState['customMetrics'] | undefined; jest.mock('../../../../alerting/use_alert_prefill', () => ({ useAlertPrefillContext: () => ({ inventoryPrefill: { @@ -29,6 +30,9 @@ jest.mock('../../../../alerting/use_alert_prefill', () => ({ setMetric(metric: WaffleOptionsState['metric']) { PREFILL_METRIC = metric; }, + setCustomMetrics(customMetrics: WaffleOptionsState['customMetrics']) { + PREFILL_CUSTOM_METRICS = customMetrics; + }, }, }), })); @@ -39,6 +43,7 @@ describe('useWaffleOptions', () => { beforeEach(() => { PREFILL_NODETYPE = undefined; PREFILL_METRIC = undefined; + PREFILL_CUSTOM_METRICS = undefined; }); it('should sync the options to the inventory alert preview context', () => { @@ -47,6 +52,15 @@ describe('useWaffleOptions', () => { const newOptions = { nodeType: 'pod', metric: { type: 'memory' }, + customMetrics: [ + { + type: 'custom', + id: + "i don't want to bother to copy and paste an actual uuid so instead i'm going to smash my keyboard skjdghsjodkyjheurvjnsgn", + aggregation: 'avg', + field: 'hey.system.are.you.good', + }, + ], } as WaffleOptionsState; act(() => { result.current.changeNodeType(newOptions.nodeType); @@ -58,5 +72,10 @@ describe('useWaffleOptions', () => { }); rerender(); expect(PREFILL_METRIC).toEqual(newOptions.metric); + act(() => { + result.current.changeCustomMetrics(newOptions.customMetrics); + }); + rerender(); + expect(PREFILL_CUSTOM_METRICS).toEqual(newOptions.customMetrics); }); }); diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_options.ts b/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_options.ts index 8059d1ad12a3a..35d069adc939e 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_options.ts +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_options.ts @@ -125,9 +125,10 @@ export const useWaffleOptions = () => { const { inventoryPrefill } = useAlertPrefillContext(); useEffect(() => { - const { setNodeType, setMetric } = inventoryPrefill; + const { setNodeType, setMetric, setCustomMetrics } = inventoryPrefill; setNodeType(state.nodeType); setMetric(state.metric); + setCustomMetrics(state.customMetrics); }, [state, inventoryPrefill]); return { diff --git a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/evaluate_condition.ts b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/evaluate_condition.ts index 3b795810b39f0..9be6a4b52157c 100644 --- a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/evaluate_condition.ts +++ b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/evaluate_condition.ts @@ -5,6 +5,7 @@ */ import { mapValues, last, first } from 'lodash'; import moment from 'moment'; +import { SnapshotCustomMetricInput } from '../../../../common/http_api/snapshot_api'; import { isTooManyBucketsPreviewException, TOO_MANY_BUCKETS_PREVIEW_EXCEPTION, @@ -37,7 +38,7 @@ export const evaluateCondition = async ( filterQuery?: string, lookbackSize?: number ): Promise> => { - const { comparator, metric } = condition; + const { comparator, metric, customMetric } = condition; let { threshold } = condition; const timerange = { @@ -55,7 +56,8 @@ export const evaluateCondition = async ( metric, timerange, sourceConfiguration, - filterQuery + filterQuery, + customMetric ); threshold = threshold.map((n) => convertMetricValue(metric, n)); @@ -93,19 +95,24 @@ const getData = async ( metric: SnapshotMetricType, timerange: InfraTimerangeInput, sourceConfiguration: InfraSourceConfiguration, - filterQuery?: string + filterQuery?: string, + customMetric?: SnapshotCustomMetricInput ) => { const snapshot = new InfraSnapshot(); const esClient = ( options: CallWithRequestParams ): Promise> => callCluster('search', options); + const metrics = [ + metric === 'custom' ? (customMetric as SnapshotCustomMetricInput) : { type: metric }, + ]; + const options = { filterQuery: parseFilterQuery(filterQuery), nodeType, groupBy: [], sourceConfiguration, - metrics: [{ type: metric }], + metrics, timerange, includeTimeseries: Boolean(timerange.lookbackSize), }; diff --git a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts index 7b816f2f225b5..db1ff26ee1810 100644 --- a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts +++ b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts @@ -6,6 +6,7 @@ import { first, get, last } from 'lodash'; import { i18n } from '@kbn/i18n'; import moment from 'moment'; +import { getCustomMetricLabel } from '../../../../common/formatters/get_custom_metric_label'; import { toMetricOpt } from '../../../../common/snapshot_metric_i18n'; import { AlertStates, InventoryMetricConditions } from './types'; import { AlertExecutorOptions } from '../../../../../alerts/server'; @@ -77,27 +78,19 @@ export const createInventoryMetricThresholdExecutor = (libs: InfraBackendLibs) = let reason; if (nextState === AlertStates.ALERT) { reason = results - .map((result) => { - if (!result[item]) return ''; - const resultWithVerboseMetricName = { - ...result[item], - metric: toMetricOpt(result[item].metric)?.text || result[item].metric, - currentValue: formatMetric(result[item].metric, result[item].currentValue), - }; - return buildFiredAlertReason(resultWithVerboseMetricName); - }) + .map((result) => buildReasonWithVerboseMetricName(result[item], buildFiredAlertReason)) .join('\n'); } if (alertOnNoData) { if (nextState === AlertStates.NO_DATA) { reason = results .filter((result) => result[item].isNoData) - .map((result) => buildNoDataAlertReason(result[item])) + .map((result) => buildReasonWithVerboseMetricName(result[item], buildNoDataAlertReason)) .join('\n'); } else if (nextState === AlertStates.ERROR) { reason = results .filter((result) => result[item].isError) - .map((result) => buildErrorAlertReason(result[item].metric)) + .map((result) => buildReasonWithVerboseMetricName(result[item], buildErrorAlertReason)) .join('\n'); } } @@ -121,6 +114,20 @@ export const createInventoryMetricThresholdExecutor = (libs: InfraBackendLibs) = } }; +const buildReasonWithVerboseMetricName = (resultItem: any, buildReason: (r: any) => string) => { + if (!resultItem) return ''; + const resultWithVerboseMetricName = { + ...resultItem, + metric: + toMetricOpt(resultItem.metric)?.text || + (resultItem.metric === 'custom' + ? getCustomMetricLabel(resultItem.customMetric) + : resultItem.metric), + currentValue: formatMetric(resultItem.metric, resultItem.currentValue), + }; + return buildReason(resultWithVerboseMetricName); +}; + const mapToConditionsLookup = ( list: any[], mapFn: (value: any, index: number, array: any[]) => unknown @@ -140,10 +147,6 @@ export const FIRED_ACTIONS = { }; const formatMetric = (metric: SnapshotMetricType, value: number) => { - // if (SnapshotCustomMetricInputRT.is(metric)) { - // const formatter = createFormatterForMetric(metric); - // return formatter(val); - // } const metricFormatter = get(METRIC_FORMATTERS, metric, METRIC_FORMATTERS.count); if (value == null) { return ''; diff --git a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/register_inventory_metric_threshold_alert_type.ts b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/register_inventory_metric_threshold_alert_type.ts index f664a59acd165..14d1acf0e4a9f 100644 --- a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/register_inventory_metric_threshold_alert_type.ts +++ b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/register_inventory_metric_threshold_alert_type.ts @@ -27,6 +27,15 @@ const condition = schema.object({ timeUnit: schema.string(), timeSize: schema.number(), metric: schema.string(), + customMetric: schema.maybe( + schema.object({ + type: schema.literal('custom'), + id: schema.string(), + field: schema.string(), + aggregation: schema.string(), + label: schema.maybe(schema.string()), + }) + ), }); export const registerMetricInventoryThresholdAlertType = (libs: InfraBackendLibs) => ({ diff --git a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/types.ts b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/types.ts index 86c77e6d7459a..06f5efaf9eb36 100644 --- a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/types.ts +++ b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/types.ts @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import { Unit } from '@elastic/datemath'; +import { SnapshotCustomMetricInput } from '../../../../common/http_api/snapshot_api'; import { SnapshotMetricType } from '../../../../common/inventory_models/types'; import { Comparator, AlertStates } from '../common/types'; @@ -18,4 +19,5 @@ export interface InventoryMetricConditions { sourceId?: string; threshold: number[]; comparator: Comparator; + customMetric?: SnapshotCustomMetricInput; } From 5308cc7100bdff415e8b576655930f0d2a45b561 Mon Sep 17 00:00:00 2001 From: Gidi Meir Morris Date: Thu, 20 Aug 2020 21:26:56 +0100 Subject: [PATCH 08/45] [Task Manager] Monitors the Task Manager Poller and automatically recovers from failure (#75420) Introduces a monitor around the Task Manager poller which pips through all values emitted by the poller and recovers from poller failures or stalls. This monitor does the following: 1. Catches the poller thrown errors and recovers by proxying the error to a handler and continues listening to the poller. 2. Reacts to the poller `error` (caused by uncaught errors) and `completion` events, by starting a new poller and piping its event through to any previous subscribers (in our case, Task Manager itself). 3. Tracks the rate at which the poller emits events (this can be both work events, and `No Task` events, so polling and finding no work, still counts as an emitted event) and times out when this rate gets too long (suggesting the poller has hung) and replaces the Poller with a new one. We're not aware of any clear cases where Task Manager should actually get restarted by the monitor - this is definitely an error case and we have addressed all known cases. The goal of introducing this monitor is as an insurance policy in case an unexpected error case breaks the poller in a long running production environment. --- .../task_manager/server/polling/index.ts | 9 + .../server/polling/observable_monitor.test.ts | 170 ++++++++++++++++++ .../server/polling/observable_monitor.ts | 80 +++++++++ .../server/{ => polling}/task_poller.test.ts | 4 +- .../server/{ => polling}/task_poller.ts | 6 +- .../timeout_promise_after.test.ts | 0 .../{lib => polling}/timeout_promise_after.ts | 0 .../task_manager/server/task_manager.ts | 51 ++++-- 8 files changed, 302 insertions(+), 18 deletions(-) create mode 100644 x-pack/plugins/task_manager/server/polling/index.ts create mode 100644 x-pack/plugins/task_manager/server/polling/observable_monitor.test.ts create mode 100644 x-pack/plugins/task_manager/server/polling/observable_monitor.ts rename x-pack/plugins/task_manager/server/{ => polling}/task_poller.test.ts (99%) rename x-pack/plugins/task_manager/server/{ => polling}/task_poller.ts (97%) rename x-pack/plugins/task_manager/server/{lib => polling}/timeout_promise_after.test.ts (100%) rename x-pack/plugins/task_manager/server/{lib => polling}/timeout_promise_after.ts (100%) diff --git a/x-pack/plugins/task_manager/server/polling/index.ts b/x-pack/plugins/task_manager/server/polling/index.ts new file mode 100644 index 0000000000000..5c1f06eaeb256 --- /dev/null +++ b/x-pack/plugins/task_manager/server/polling/index.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export { createObservableMonitor } from './observable_monitor'; +export { createTaskPoller, PollingError, PollingErrorType } from './task_poller'; +export { timeoutPromiseAfter } from './timeout_promise_after'; diff --git a/x-pack/plugins/task_manager/server/polling/observable_monitor.test.ts b/x-pack/plugins/task_manager/server/polling/observable_monitor.test.ts new file mode 100644 index 0000000000000..0b7bbdfb623e5 --- /dev/null +++ b/x-pack/plugins/task_manager/server/polling/observable_monitor.test.ts @@ -0,0 +1,170 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { interval, from, Subject } from 'rxjs'; +import { map, concatMap, takeWhile, take } from 'rxjs/operators'; + +import { createObservableMonitor } from './observable_monitor'; +import { times } from 'lodash'; + +describe('Poll Monitor', () => { + test('returns a cold observable so that the monitored Observable is only created on demand', async () => { + const instantiator = jest.fn(() => new Subject()); + + createObservableMonitor(instantiator); + + expect(instantiator).not.toHaveBeenCalled(); + }); + + test('subscribing to the observable instantiates a new observable and pipes its results through', async () => { + const instantiator = jest.fn(() => from([0, 1, 2])); + const monitoredObservable = createObservableMonitor(instantiator); + + expect(instantiator).not.toHaveBeenCalled(); + + return new Promise((resolve) => { + const next = jest.fn(); + monitoredObservable.pipe(take(3)).subscribe({ + next, + complete: () => { + expect(instantiator).toHaveBeenCalled(); + expect(next).toHaveBeenCalledWith(0); + expect(next).toHaveBeenCalledWith(1); + expect(next).toHaveBeenCalledWith(2); + resolve(); + }, + }); + }); + }); + + test('unsubscribing from the monitor prevents the monitor from resubscribing to the observable', async () => { + const heartbeatInterval = 1000; + const instantiator = jest.fn(() => interval(100)); + const monitoredObservable = createObservableMonitor(instantiator, { heartbeatInterval }); + + return new Promise((resolve) => { + const next = jest.fn(); + monitoredObservable.pipe(take(3)).subscribe({ + next, + complete: () => { + expect(instantiator).toHaveBeenCalledTimes(1); + setTimeout(() => { + expect(instantiator).toHaveBeenCalledTimes(1); + resolve(); + }, heartbeatInterval * 2); + }, + }); + }); + }); + + test(`ensures the observable subscription hasn't closed at a fixed interval and reinstantiates if it has`, async () => { + let iteration = 0; + const instantiator = jest.fn(() => { + iteration++; + return interval(100).pipe( + map((index) => `${iteration}:${index}`), + // throw on 3rd value of the first iteration + map((value, index) => { + if (iteration === 1 && index === 3) { + throw new Error('Source threw an error!'); + } + return value; + }) + ); + }); + + const onError = jest.fn(); + const monitoredObservable = createObservableMonitor(instantiator, { onError }); + + return new Promise((resolve) => { + const next = jest.fn(); + const error = jest.fn(); + monitoredObservable + .pipe( + // unsubscribe once we confirm we have successfully recovered from an error in the source + takeWhile(function validateExpectation() { + try { + [...times(3, (index) => `1:${index}`), ...times(5, (index) => `2:${index}`)].forEach( + (expecteArg) => { + expect(next).toHaveBeenCalledWith(expecteArg); + } + ); + return false; + } catch { + return true; + } + }) + ) + .subscribe({ + next, + error, + complete: () => { + expect(error).not.toHaveBeenCalled(); + expect(onError).toHaveBeenCalledWith(new Error('Source threw an error!')); + resolve(); + }, + }); + }); + }); + + test(`ensures the observable subscription hasn't hung at a fixed interval and reinstantiates if it has`, async () => { + let iteration = 0; + const instantiator = jest.fn(() => { + iteration++; + return interval(100).pipe( + map((index) => `${iteration}:${index}`), + // hang on 3rd value of the first iteration + concatMap((value, index) => { + if (iteration === 1 && index === 3) { + return new Promise(() => { + // never resolve or reject, just hang for EVER + }); + } + return Promise.resolve(value); + }) + ); + }); + + const onError = jest.fn(); + const monitoredObservable = createObservableMonitor(instantiator, { + onError, + heartbeatInterval: 100, + inactivityTimeout: 500, + }); + + return new Promise((resolve) => { + const next = jest.fn(); + const error = jest.fn(); + monitoredObservable + .pipe( + // unsubscribe once we confirm we have successfully recovered from an error in the source + takeWhile(function validateExpectation() { + try { + [...times(3, (index) => `1:${index}`), ...times(5, (index) => `2:${index}`)].forEach( + (expecteArg) => { + expect(next).toHaveBeenCalledWith(expecteArg); + } + ); + return false; + } catch { + return true; + } + }) + ) + .subscribe({ + next, + error, + complete: () => { + expect(error).not.toHaveBeenCalled(); + expect(onError).toHaveBeenCalledWith( + new Error(`Observable Monitor: Hung Observable restarted after 500ms of inactivity`) + ); + resolve(); + }, + }); + }); + }); +}); diff --git a/x-pack/plugins/task_manager/server/polling/observable_monitor.ts b/x-pack/plugins/task_manager/server/polling/observable_monitor.ts new file mode 100644 index 0000000000000..7b06117ef59d1 --- /dev/null +++ b/x-pack/plugins/task_manager/server/polling/observable_monitor.ts @@ -0,0 +1,80 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { Subject, Observable, throwError, interval, timer, Subscription } from 'rxjs'; +import { exhaustMap, tap, takeUntil, switchMap, switchMapTo, catchError } from 'rxjs/operators'; +import { noop } from 'lodash'; + +const DEFAULT_HEARTBEAT_INTERVAL = 1000; + +// by default don't monitor inactivity as not all observables are expected +// to emit at any kind of fixed interval +const DEFAULT_INACTIVITY_TIMEOUT = 0; + +export interface ObservableMonitorOptions { + heartbeatInterval?: number; + inactivityTimeout?: number; + onError?: (err: E) => void; +} + +export function createObservableMonitor( + observableFactory: () => Observable, + { + heartbeatInterval = DEFAULT_HEARTBEAT_INTERVAL, + inactivityTimeout = DEFAULT_INACTIVITY_TIMEOUT, + onError = noop, + }: ObservableMonitorOptions = {} +): Observable { + return new Observable((subscriber) => { + const subscription: Subscription = interval(heartbeatInterval) + .pipe( + // switch from the heartbeat interval to the instantiated observable until it completes / errors + exhaustMap(() => takeUntilDurationOfInactivity(observableFactory(), inactivityTimeout)), + // if an error is thrown, catch it, notify and try to recover + catchError((err: E, source$: Observable) => { + onError(err); + // return source, which will allow our observable to recover from this error and + // keep pulling values out of it + return source$; + }) + ) + .subscribe(subscriber); + return () => { + subscription.unsubscribe(); + }; + }); +} + +function takeUntilDurationOfInactivity(source$: Observable, inactivityTimeout: number) { + // if there's a specified maximum duration of inactivity, only take values until that + // duration elapses without any new events + if (inactivityTimeout) { + // an observable which starts a timer every time a new value is passed in, replacing the previous timer + // if the timer goes off without having been reset by a fresh value, it will emit a single event - which will + // notify our monitor that the source has been inactive for too long + const inactivityMonitor$ = new Subject(); + return source$.pipe( + takeUntil( + inactivityMonitor$.pipe( + // on each new emited value, start a new timer, discarding the old one + switchMap(() => timer(inactivityTimeout)), + // every time a timer expires (meaning no new value came in on time to discard it) + // throw an error, forcing the monitor instantiate a new observable + switchMapTo( + throwError( + new Error( + `Observable Monitor: Hung Observable restarted after ${inactivityTimeout}ms of inactivity` + ) + ) + ) + ) + ), + // poke `inactivityMonitor$` so it restarts the timer + tap(() => inactivityMonitor$.next()) + ); + } + return source$; +} diff --git a/x-pack/plugins/task_manager/server/task_poller.test.ts b/x-pack/plugins/task_manager/server/polling/task_poller.test.ts similarity index 99% rename from x-pack/plugins/task_manager/server/task_poller.test.ts rename to x-pack/plugins/task_manager/server/polling/task_poller.test.ts index 98e6d0f9388a4..607e2ac2b80fa 100644 --- a/x-pack/plugins/task_manager/server/task_poller.test.ts +++ b/x-pack/plugins/task_manager/server/polling/task_poller.test.ts @@ -9,8 +9,8 @@ import { Subject } from 'rxjs'; import { Option, none, some } from 'fp-ts/lib/Option'; import { createTaskPoller, PollingError, PollingErrorType } from './task_poller'; import { fakeSchedulers } from 'rxjs-marbles/jest'; -import { sleep, resolvable, Resolvable } from './test_utils'; -import { asOk, asErr } from './lib/result_type'; +import { sleep, resolvable, Resolvable } from '../test_utils'; +import { asOk, asErr } from '../lib/result_type'; describe('TaskPoller', () => { beforeEach(() => jest.useFakeTimers()); diff --git a/x-pack/plugins/task_manager/server/task_poller.ts b/x-pack/plugins/task_manager/server/polling/task_poller.ts similarity index 97% rename from x-pack/plugins/task_manager/server/task_poller.ts rename to x-pack/plugins/task_manager/server/polling/task_poller.ts index 88511f42f96fb..a1435ffafe8f8 100644 --- a/x-pack/plugins/task_manager/server/task_poller.ts +++ b/x-pack/plugins/task_manager/server/polling/task_poller.ts @@ -15,7 +15,7 @@ import { mapTo, filter, scan, concatMap, tap, catchError } from 'rxjs/operators' import { pipe } from 'fp-ts/lib/pipeable'; import { Option, none, map as mapOptional, getOrElse } from 'fp-ts/lib/Option'; -import { pullFromSet } from './lib/pull_from_set'; +import { pullFromSet } from '../lib/pull_from_set'; import { Result, Err, @@ -24,8 +24,8 @@ import { asOk, asErr, promiseResult, -} from './lib/result_type'; -import { timeoutPromiseAfter } from './lib/timeout_promise_after'; +} from '../lib/result_type'; +import { timeoutPromiseAfter } from './timeout_promise_after'; type WorkFn = (...params: T[]) => Promise; diff --git a/x-pack/plugins/task_manager/server/lib/timeout_promise_after.test.ts b/x-pack/plugins/task_manager/server/polling/timeout_promise_after.test.ts similarity index 100% rename from x-pack/plugins/task_manager/server/lib/timeout_promise_after.test.ts rename to x-pack/plugins/task_manager/server/polling/timeout_promise_after.test.ts diff --git a/x-pack/plugins/task_manager/server/lib/timeout_promise_after.ts b/x-pack/plugins/task_manager/server/polling/timeout_promise_after.ts similarity index 100% rename from x-pack/plugins/task_manager/server/lib/timeout_promise_after.ts rename to x-pack/plugins/task_manager/server/polling/timeout_promise_after.ts diff --git a/x-pack/plugins/task_manager/server/task_manager.ts b/x-pack/plugins/task_manager/server/task_manager.ts index 2c812f0da516d..fb2d5e07030a4 100644 --- a/x-pack/plugins/task_manager/server/task_manager.ts +++ b/x-pack/plugins/task_manager/server/task_manager.ts @@ -46,7 +46,12 @@ import { TaskStatus, ElasticJs, } from './task'; -import { createTaskPoller, PollingError, PollingErrorType } from './task_poller'; +import { + createTaskPoller, + PollingError, + PollingErrorType, + createObservableMonitor, +} from './polling'; import { TaskPool } from './task_pool'; import { TaskManagerRunner, TaskRunner } from './task_runner'; import { @@ -154,18 +159,38 @@ export class TaskManager { maxWorkers: opts.config.max_workers, }); - this.poller$ = createTaskPoller({ - pollInterval: opts.config.poll_interval, - bufferCapacity: opts.config.request_capacity, - getCapacity: () => this.pool.availableWorkers, - pollRequests$: this.claimRequests$, - work: this.pollForWork, - // Time out the `work` phase if it takes longer than a certain number of polling cycles - // The `work` phase includes the prework needed *before* executing a task - // (such as polling for new work, marking tasks as running etc.) but does not - // include the time of actually running the task - workTimeout: opts.config.poll_interval * opts.config.max_poll_inactivity_cycles, - }); + const { + max_poll_inactivity_cycles: maxPollInactivityCycles, + poll_interval: pollInterval, + } = opts.config; + this.poller$ = createObservableMonitor>, Error>( + () => + createTaskPoller({ + pollInterval, + bufferCapacity: opts.config.request_capacity, + getCapacity: () => this.pool.availableWorkers, + pollRequests$: this.claimRequests$, + work: this.pollForWork, + // Time out the `work` phase if it takes longer than a certain number of polling cycles + // The `work` phase includes the prework needed *before* executing a task + // (such as polling for new work, marking tasks as running etc.) but does not + // include the time of actually running the task + workTimeout: pollInterval * maxPollInactivityCycles, + }), + { + heartbeatInterval: pollInterval, + // Time out the poller itself if it has failed to complete the entire stream for a certain amount of time. + // This is different that the `work` timeout above, as the poller could enter an invalid state where + // it fails to complete a cycle even thought `work` is completing quickly. + // We grant it a single cycle longer than the time alotted to `work` so that timing out the `work` + // doesn't get short circuited by the monitor reinstantiating the poller all together (a far more expensive + // operation than just timing out the `work` internally) + inactivityTimeout: pollInterval * (maxPollInactivityCycles + 1), + onError: (error) => { + this.logger.error(`[Task Poller Monitor]: ${error.message}`); + }, + } + ); } private emitEvent = (event: TaskLifecycleEvent) => { From 3201efe79739bf8245a9648df9dac8d2a566d55a Mon Sep 17 00:00:00 2001 From: Jen Huang Date: Thu, 20 Aug 2020 15:29:56 -0700 Subject: [PATCH 09/45] [Ingest Manager] Add namespace validation (#75381) * Add namespace validation on APIs and UI * Add test coverage * Fix imports * Fix schema * Rename to policy * Fix typo --- .../ingest_manager/common/services/index.ts | 1 + .../services/is_valid_namespace.test.ts | 28 +++++++++++++++++++ .../common/services/is_valid_namespace.ts | 17 +++++++++++ .../components/agent_policy_form.tsx | 8 ++++++ .../services/validate_package_policy.ts | 8 +++++- .../ingest_manager/services/index.ts | 1 + .../server/types/models/agent_policy.ts | 4 +-- .../server/types/models/package_policy.ts | 12 +++++++- .../apis/agent_policy/agent_policy.ts | 13 ++++++++- .../apis/package_policy/create.ts | 27 +++++++++++++++++- 10 files changed, 113 insertions(+), 6 deletions(-) create mode 100644 x-pack/plugins/ingest_manager/common/services/is_valid_namespace.test.ts create mode 100644 x-pack/plugins/ingest_manager/common/services/is_valid_namespace.ts diff --git a/x-pack/plugins/ingest_manager/common/services/index.ts b/x-pack/plugins/ingest_manager/common/services/index.ts index 28fd15b5ea700..ad739bf9ff844 100644 --- a/x-pack/plugins/ingest_manager/common/services/index.ts +++ b/x-pack/plugins/ingest_manager/common/services/index.ts @@ -10,3 +10,4 @@ export { storedPackagePoliciesToAgentInputs } from './package_policies_to_agent_ export { fullAgentPolicyToYaml } from './full_agent_policy_to_yaml'; export { isPackageLimited, doesAgentPolicyAlreadyIncludePackage } from './limited_package'; export { decodeCloudId } from './decode_cloud_id'; +export { isValidNamespace } from './is_valid_namespace'; diff --git a/x-pack/plugins/ingest_manager/common/services/is_valid_namespace.test.ts b/x-pack/plugins/ingest_manager/common/services/is_valid_namespace.test.ts new file mode 100644 index 0000000000000..40f37cc456f94 --- /dev/null +++ b/x-pack/plugins/ingest_manager/common/services/is_valid_namespace.test.ts @@ -0,0 +1,28 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { isValidNamespace } from './is_valid_namespace'; + +describe('Ingest Manager - isValidNamespace', () => { + it('returns true for valid namespaces', () => { + expect(isValidNamespace('default')).toBe(true); + expect(isValidNamespace('namespace-with-dash')).toBe(true); + expect(isValidNamespace('123')).toBe(true); + }); + + it('returns false for invalid namespaces', () => { + expect(isValidNamespace('Default')).toBe(false); + expect(isValidNamespace('namespace with spaces')).toBe(false); + expect(isValidNamespace('foo/bar')).toBe(false); + expect(isValidNamespace('foo\\bar')).toBe(false); + expect(isValidNamespace('foo*bar')).toBe(false); + expect(isValidNamespace('foo?bar')).toBe(false); + expect(isValidNamespace('foo"bar')).toBe(false); + expect(isValidNamespace('foo, |, space character, comma, #, : + /^[^\*\\/\?"<>|\s,#:]+$/.test(namespace) + ); +} diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/components/agent_policy_form.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/components/agent_policy_form.tsx index a858a53c485b7..b216270aa08f0 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/components/agent_policy_form.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/components/agent_policy_form.tsx @@ -24,6 +24,7 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; import styled from 'styled-components'; import { NewAgentPolicy, AgentPolicy } from '../../../types'; +import { isValidNamespace } from '../../../services'; import { AgentPolicyDeleteProvider } from './agent_policy_delete_provider'; interface ValidationResults { @@ -57,6 +58,13 @@ export const agentPolicyFormValidation = ( defaultMessage="A namespace is required" />, ]; + } else if (!isValidNamespace(agentPolicy.namespace)) { + errors.namespace = [ + , + ]; } return errors; diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/create_package_policy_page/services/validate_package_policy.ts b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/create_package_policy_page/services/validate_package_policy.ts index f375352c5a055..2714f1fe2e6e5 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/create_package_policy_page/services/validate_package_policy.ts +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/create_package_policy_page/services/validate_package_policy.ts @@ -5,7 +5,7 @@ */ import { i18n } from '@kbn/i18n'; import { safeLoad } from 'js-yaml'; -import { getFlattenedObject } from '../../../../services'; +import { getFlattenedObject, isValidNamespace } from '../../../../services'; import { NewPackagePolicy, PackagePolicyInput, @@ -65,6 +65,12 @@ export const validatePackagePolicy = ( defaultMessage: 'Namespace is required', }), ]; + } else if (!isValidNamespace(packagePolicy.namespace)) { + validationResults.namespace = [ + i18n.translate('xpack.ingestManager.packagePolicyValidation.namespaceInvalidErrorMessage', { + defaultMessage: 'Namespace contains invalid characters', + }), + ]; } if ( diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/services/index.ts b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/services/index.ts index 7d426c11c0aab..56179b02c5ba2 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/services/index.ts +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/services/index.ts @@ -24,4 +24,5 @@ export { fullAgentPolicyToYaml, isPackageLimited, doesAgentPolicyAlreadyIncludePackage, + isValidNamespace, } from '../../../../common'; diff --git a/x-pack/plugins/ingest_manager/server/types/models/agent_policy.ts b/x-pack/plugins/ingest_manager/server/types/models/agent_policy.ts index 877d8e9e91714..5fff9247d78d9 100644 --- a/x-pack/plugins/ingest_manager/server/types/models/agent_policy.ts +++ b/x-pack/plugins/ingest_manager/server/types/models/agent_policy.ts @@ -4,12 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ import { schema } from '@kbn/config-schema'; -import { PackagePolicySchema } from './package_policy'; +import { PackagePolicySchema, NamespaceSchema } from './package_policy'; import { AgentPolicyStatus } from '../../../common'; const AgentPolicyBaseSchema = { name: schema.string({ minLength: 1 }), - namespace: schema.string({ minLength: 1 }), + namespace: NamespaceSchema, description: schema.maybe(schema.string()), monitoring_enabled: schema.maybe( schema.arrayOf(schema.oneOf([schema.literal('logs'), schema.literal('metrics')])) diff --git a/x-pack/plugins/ingest_manager/server/types/models/package_policy.ts b/x-pack/plugins/ingest_manager/server/types/models/package_policy.ts index 81bfb599b4c9a..c23918210114e 100644 --- a/x-pack/plugins/ingest_manager/server/types/models/package_policy.ts +++ b/x-pack/plugins/ingest_manager/server/types/models/package_policy.ts @@ -4,6 +4,16 @@ * you may not use this file except in compliance with the Elastic License. */ import { schema } from '@kbn/config-schema'; +import { isValidNamespace } from '../../../common'; + +export const NamespaceSchema = schema.string({ + minLength: 1, + validate: (value) => { + if (!isValidNamespace(value)) { + return 'Namespace contains invalid characters'; + } + }, +}); const ConfigRecordSchema = schema.recordOf( schema.string(), @@ -16,7 +26,7 @@ const ConfigRecordSchema = schema.recordOf( const PackagePolicyBaseSchema = { name: schema.string(), description: schema.maybe(schema.string()), - namespace: schema.string({ minLength: 1 }), + namespace: NamespaceSchema, policy_id: schema.string(), enabled: schema.boolean(), package: schema.maybe( diff --git a/x-pack/test/ingest_manager_api_integration/apis/agent_policy/agent_policy.ts b/x-pack/test/ingest_manager_api_integration/apis/agent_policy/agent_policy.ts index 5253b19b24d65..b55da0798c5f0 100644 --- a/x-pack/test/ingest_manager_api_integration/apis/agent_policy/agent_policy.ts +++ b/x-pack/test/ingest_manager_api_integration/apis/agent_policy/agent_policy.ts @@ -26,7 +26,7 @@ export default function ({ getService }: FtrProviderContext) { expect(apiResponse.success).to.be(true); }); - it('should return a 400 with an invalid namespace', async () => { + it('should return a 400 with an empty namespace', async () => { await supertest .post(`/api/ingest_manager/agent_policies`) .set('kbn-xsrf', 'xxxx') @@ -36,6 +36,17 @@ export default function ({ getService }: FtrProviderContext) { }) .expect(400); }); + + it('should return a 400 with an invalid namespace', async () => { + await supertest + .post(`/api/ingest_manager/agent_policies`) + .set('kbn-xsrf', 'xxxx') + .send({ + name: 'TEST', + namespace: 'InvalidNamespace', + }) + .expect(400); + }); }); describe('POST /api/ingest_manager/agent_policies/{agentPolicyId}/copy', () => { diff --git a/x-pack/test/ingest_manager_api_integration/apis/package_policy/create.ts b/x-pack/test/ingest_manager_api_integration/apis/package_policy/create.ts index 2043faa07b1e1..c88f03de59615 100644 --- a/x-pack/test/ingest_manager_api_integration/apis/package_policy/create.ts +++ b/x-pack/test/ingest_manager_api_integration/apis/package_policy/create.ts @@ -59,7 +59,7 @@ export default function ({ getService }: FtrProviderContext) { } }); - it('should return a 400 with an invalid namespace', async function () { + it('should return a 400 with an empty namespace', async function () { if (server.enabled) { await supertest .post(`/api/ingest_manager/package_policies`) @@ -84,6 +84,31 @@ export default function ({ getService }: FtrProviderContext) { } }); + it('should return a 400 with an invalid namespace', async function () { + if (server.enabled) { + await supertest + .post(`/api/ingest_manager/package_policies`) + .set('kbn-xsrf', 'xxxx') + .send({ + name: 'filetest-1', + description: '', + namespace: 'InvalidNamespace', + policy_id: agentPolicyId, + enabled: true, + output_id: '', + inputs: [], + package: { + name: 'filetest', + title: 'For File Tests', + version: '0.1.0', + }, + }) + .expect(400); + } else { + warnAndSkipTest(this, log); + } + }); + it('should not allow multiple limited packages on the same agent policy', async function () { if (server.enabled) { await supertest From 958296c5c2fec4ca41bc0b71af33dab4ff3ef29e Mon Sep 17 00:00:00 2001 From: Quynh Nguyen <43350163+qn895@users.noreply.github.com> Date: Thu, 20 Aug 2020 18:14:58 -0500 Subject: [PATCH 10/45] [ML] Update broken job config callout error (#75481) Co-authored-by: Elastic Machine --- .../job_config_error_callout.tsx | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/job_config_error_callout/job_config_error_callout.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/job_config_error_callout/job_config_error_callout.tsx index 9b9e1258db503..959f2d18d99fe 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/job_config_error_callout/job_config_error_callout.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/job_config_error_callout/job_config_error_callout.tsx @@ -4,13 +4,14 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { FC } from 'react'; +import React, { FC, useMemo } from 'react'; import { EuiCallOut, EuiLink, EuiPanel, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { ExplorationTitle } from '../exploration_title'; +import { useMlKibana } from '../../../../../contexts/kibana'; const jobConfigErrorTitle = i18n.translate('xpack.ml.dataframe.analytics.jobConfig.errorTitle', { defaultMessage: 'Unable to fetch results. An error occurred loading the job configuration data.', @@ -31,6 +32,11 @@ export const JobConfigErrorCallout: FC = ({ jobConfigErrorMessage, title, }) => { + const { + services: { + application: { getUrlForApp }, + }, + } = useMlKibana(); const containsIndexPatternLink = typeof jobCapsServiceErrorMessage === 'string' && jobCapsServiceErrorMessage.includes('locate that index-pattern') && @@ -39,9 +45,16 @@ export const JobConfigErrorCallout: FC = ({ const message = (

{jobConfigErrorMessage ? jobConfigErrorMessage : jobCapsServiceErrorMessage}

); + const newIndexPatternUrl = useMemo( + () => + getUrlForApp('management', { + path: 'kibana/indexPatterns', + }), + [] + ); const calloutBody = containsIndexPatternLink ? ( - + {message} ) : ( From 7b23e7cd8b20aa889a0d31181df91bf96c0f676d Mon Sep 17 00:00:00 2001 From: Spencer Date: Thu, 20 Aug 2020 18:50:36 -0700 Subject: [PATCH 11/45] [kbn/plugin-generator] remove sao, modernize (#75465) Co-authored-by: spalger --- .eslintignore | 2 +- .eslintrc.js | 1 - packages/kbn-plugin-generator/README.md | 10 +- packages/kbn-plugin-generator/index.js | 69 - .../integration_tests/generate_plugin.test.js | 62 - packages/kbn-plugin-generator/package.json | 26 +- .../kbn-plugin-generator/sao_template/sao.js | 189 - .../sao_template/sao.test.js | 159 - .../sao_template/template/eslintrc.js | 9 - .../sao_template/template/i18nrc.json | 10 - .../template/public/application.tsx | 25 - .../sao_template/template/public/index.ts | 16 - .../sao_template/template/public/types.ts | 11 - .../sao_template/template/server/index.ts | 15 - .../sao_template/template/server/plugin.ts | 30 - .../template/translations/ja-JP.json | 82 - .../kbn-plugin-generator/scripts/build.js | 43 + .../kbn-plugin-generator/src/ask_questions.ts | 103 + .../kbn-plugin-generator/src/casing.test.ts | 68 + packages/kbn-plugin-generator/src/casing.ts | 32 + packages/kbn-plugin-generator/src/cli.ts | 98 + .../{index.js.d.ts => src/index.ts} | 8 +- .../integration_tests/generate_plugin.test.ts | 143 + .../src/render_template.ts | 127 + packages/kbn-plugin-generator/src/streams.ts | 73 + .../template/.eslintrc.js.ejs | 10 + .../kbn-plugin-generator/template/.gitignore | 2 + .../template/.i18nrc.json.ejs | 9 + .../README.md => template/README.md.ejs} | 4 +- .../index.ts => template/common/index.ts.ejs} | 0 .../kibana.json => template/kibana.json.ejs} | 3 +- .../template/package.json.ejs | 8 + .../template/public/application.tsx.ejs | 24 + .../public/components/app.tsx.ejs} | 58 +- .../template/public/index.scss | 0 .../template/public/index.ts.ejs | 14 + .../public/plugin.ts.ejs} | 14 +- .../template/public/types.ts.ejs | 11 + .../template/server/index.ts.ejs | 15 + .../template/server/plugin.ts.ejs | 40 + .../server/routes/index.ts.ejs} | 3 +- .../types.ts => template/server/types.ts.ejs} | 4 +- .../template/translations/ja-JP.json.ejs | 81 + .../tsconfig.json.ejs} | 0 packages/kbn-plugin-generator/tsconfig.json | 11 +- packages/kbn-pm/dist/index.js | 46141 ++++++++-------- scripts/generate_plugin.js | 4 +- src/dev/file.ts | 8 +- .../tasks/extract_untracked_translations.ts | 2 +- src/dev/precommit_hook/casing_check_config.js | 8 + src/dev/precommit_hook/check_file_casing.js | 5 + yarn.lock | 653 +- 52 files changed, 24071 insertions(+), 24472 deletions(-) delete mode 100644 packages/kbn-plugin-generator/index.js delete mode 100644 packages/kbn-plugin-generator/integration_tests/generate_plugin.test.js delete mode 100755 packages/kbn-plugin-generator/sao_template/sao.js delete mode 100755 packages/kbn-plugin-generator/sao_template/sao.test.js delete mode 100644 packages/kbn-plugin-generator/sao_template/template/eslintrc.js delete mode 100644 packages/kbn-plugin-generator/sao_template/template/i18nrc.json delete mode 100644 packages/kbn-plugin-generator/sao_template/template/public/application.tsx delete mode 100644 packages/kbn-plugin-generator/sao_template/template/public/index.ts delete mode 100644 packages/kbn-plugin-generator/sao_template/template/public/types.ts delete mode 100644 packages/kbn-plugin-generator/sao_template/template/server/index.ts delete mode 100644 packages/kbn-plugin-generator/sao_template/template/server/plugin.ts delete mode 100644 packages/kbn-plugin-generator/sao_template/template/translations/ja-JP.json create mode 100644 packages/kbn-plugin-generator/scripts/build.js create mode 100644 packages/kbn-plugin-generator/src/ask_questions.ts create mode 100644 packages/kbn-plugin-generator/src/casing.test.ts create mode 100644 packages/kbn-plugin-generator/src/casing.ts create mode 100644 packages/kbn-plugin-generator/src/cli.ts rename packages/kbn-plugin-generator/{index.js.d.ts => src/index.ts} (88%) create mode 100644 packages/kbn-plugin-generator/src/integration_tests/generate_plugin.test.ts create mode 100644 packages/kbn-plugin-generator/src/render_template.ts create mode 100644 packages/kbn-plugin-generator/src/streams.ts create mode 100644 packages/kbn-plugin-generator/template/.eslintrc.js.ejs create mode 100644 packages/kbn-plugin-generator/template/.gitignore create mode 100644 packages/kbn-plugin-generator/template/.i18nrc.json.ejs rename packages/kbn-plugin-generator/{sao_template/template/README.md => template/README.md.ejs} (66%) rename packages/kbn-plugin-generator/{sao_template/template/common/index.ts => template/common/index.ts.ejs} (100%) rename packages/kbn-plugin-generator/{sao_template/template/kibana.json => template/kibana.json.ejs} (74%) create mode 100644 packages/kbn-plugin-generator/template/package.json.ejs create mode 100644 packages/kbn-plugin-generator/template/public/application.tsx.ejs rename packages/kbn-plugin-generator/{sao_template/template/public/components/app.tsx => template/public/components/app.tsx.ejs} (62%) rename packages/kbn-plugin-generator/{sao_template => }/template/public/index.scss (100%) create mode 100644 packages/kbn-plugin-generator/template/public/index.ts.ejs rename packages/kbn-plugin-generator/{sao_template/template/public/plugin.ts => template/public/plugin.ts.ejs} (68%) create mode 100644 packages/kbn-plugin-generator/template/public/types.ts.ejs create mode 100644 packages/kbn-plugin-generator/template/server/index.ts.ejs create mode 100644 packages/kbn-plugin-generator/template/server/plugin.ts.ejs rename packages/kbn-plugin-generator/{sao_template/template/server/routes/index.ts => template/server/routes/index.ts.ejs} (81%) rename packages/kbn-plugin-generator/{sao_template/template/server/types.ts => template/server/types.ts.ejs} (52%) create mode 100644 packages/kbn-plugin-generator/template/translations/ja-JP.json.ejs rename packages/kbn-plugin-generator/{sao_template/template/tsconfig.json => template/tsconfig.json.ejs} (100%) diff --git a/.eslintignore b/.eslintignore index 2b291e1c19714..972c818d791bf 100644 --- a/.eslintignore +++ b/.eslintignore @@ -41,7 +41,7 @@ target # package overrides /packages/eslint-config-kibana /packages/kbn-interpreter/src/common/lib/grammar.js -/packages/kbn-plugin-generator/sao_template/template +/packages/kbn-plugin-generator/template /packages/kbn-pm/dist /packages/kbn-test/src/functional_test_runner/__tests__/fixtures/ /packages/kbn-test/src/functional_test_runner/lib/config/__tests__/fixtures/ diff --git a/.eslintrc.js b/.eslintrc.js index 5cd9809242bba..8c2a46f80a3a8 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -604,7 +604,6 @@ module.exports = { { files: [ '.eslintrc.js', - 'packages/kbn-plugin-generator/**/*.js', 'packages/kbn-eslint-import-resolver-kibana/**/*.js', 'packages/kbn-eslint-plugin-eslint/**/*', 'x-pack/gulpfile.js', diff --git a/packages/kbn-plugin-generator/README.md b/packages/kbn-plugin-generator/README.md index 6ad665f9b87f8..9ff9a8aa95ca2 100644 --- a/packages/kbn-plugin-generator/README.md +++ b/packages/kbn-plugin-generator/README.md @@ -17,17 +17,17 @@ If you are targeting **Kibana 6.3 or greater** then checkout the corresponding K To target the current development version of Kibana just use the default `master` branch. ```sh -node scripts/generate_plugin my_plugin_name +node scripts/generate_plugin --name my_plugin_name -y # generates a plugin in `plugins/my_plugin_name` ``` -To target 6.3, use the `6.x` branch (until the `6.3` branch is created). +To target 6.8, use the `6.8` branch. ```sh git checkout 6.x yarn kbn bootstrap # always bootstrap when switching branches -node scripts/generate_plugin my_plugin_name -# generates a plugin for Kibana 6.3 in `../kibana-extra/my_plugin_name` +node scripts/generate_plugin --name my_plugin_name -y +# generates a plugin for Kibana 6.8 in `../kibana-extra/my_plugin_name` ``` The generate script supports a few flags; run it with the `--help` flag to learn more. @@ -49,7 +49,7 @@ yarn kbn bootstrap ## Plugin Development Scripts -Generated plugins receive a handful of scripts that can be used during development. Those scripts are detailed in the [README.md](sao_template/template/README.md) file in each newly generated plugin, and expose the scripts provided by the [Kibana plugin helpers](../kbn-plugin-helpers), but here is a quick reference in case you need it: +Generated plugins receive a handful of scripts that can be used during development. Those scripts are detailed in the [README.md](template/README.md) file in each newly generated plugin, and expose the scripts provided by the [Kibana plugin helpers](../kbn-plugin-helpers), but here is a quick reference in case you need it: > ***NOTE:*** All of these scripts should be run from the generated plugin. diff --git a/packages/kbn-plugin-generator/index.js b/packages/kbn-plugin-generator/index.js deleted file mode 100644 index 398b49fa1ecd5..0000000000000 --- a/packages/kbn-plugin-generator/index.js +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -const { resolve } = require('path'); - -const dedent = require('dedent'); -const sao = require('sao'); -const chalk = require('chalk'); -const getopts = require('getopts'); -const { snakeCase } = require('lodash'); - -exports.run = function run(argv) { - const options = getopts(argv, { - alias: { - h: 'help', - i: 'internal', - }, - }); - - if (!options.help && options._.length !== 1) { - console.log(chalk`{red {bold [name]} is a required argument}\n`); - options.help = true; - } - - if (options.help) { - console.log( - dedent(chalk` - # {dim Usage:} - node scripts/generate-plugin {bold [name]} - Generate a fresh Kibana plugin in the plugins/ directory - `) + '\n' - ); - process.exit(1); - } - - const name = options._[0]; - const template = resolve(__dirname, './sao_template'); - const kibanaPlugins = resolve(process.cwd(), 'plugins'); - const targetPath = resolve(kibanaPlugins, snakeCase(name)); - - sao({ - template: template, - targetPath: targetPath, - configOptions: { - name, - targetPath, - }, - }).catch((error) => { - console.error(chalk`{red fatal error}!`); - console.error(error.stack); - process.exit(1); - }); -}; diff --git a/packages/kbn-plugin-generator/integration_tests/generate_plugin.test.js b/packages/kbn-plugin-generator/integration_tests/generate_plugin.test.js deleted file mode 100644 index f434d09c6bf81..0000000000000 --- a/packages/kbn-plugin-generator/integration_tests/generate_plugin.test.js +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { spawn } from 'child_process'; -import Fs from 'fs'; -import { resolve } from 'path'; -import { promisify } from 'util'; - -import del from 'del'; -import { snakeCase } from 'lodash'; - -const statAsync = promisify(Fs.stat); -const ROOT_DIR = resolve(__dirname, '../../../'); - -const pluginName = 'ispec-plugin'; -const snakeCased = snakeCase(pluginName); -const generatedPath = resolve(ROOT_DIR, `plugins/${snakeCased}`); - -beforeAll(async () => { - await del(generatedPath, { force: true }); -}); - -afterAll(async () => { - await del(generatedPath, { force: true }); -}); - -it('generates a plugin', async () => { - await new Promise((resolve, reject) => { - const proc = spawn(process.execPath, ['scripts/generate_plugin.js', pluginName], { - cwd: ROOT_DIR, - stdio: 'pipe', - }); - - proc.stdout.on('data', function selectDefaults() { - proc.stdin.write('\n'); // Generate a plugin with default options. - }); - - proc.on('close', resolve); - proc.on('error', reject); - }); - - const stats = await statAsync(generatedPath); - if (!stats.isDirectory()) { - throw new Error(`Expected [${generatedPath}] to be a directory`); - } -}); diff --git a/packages/kbn-plugin-generator/package.json b/packages/kbn-plugin-generator/package.json index 0803e498279f3..89e4251bd7802 100644 --- a/packages/kbn-plugin-generator/package.json +++ b/packages/kbn-plugin-generator/package.json @@ -1,14 +1,26 @@ { "name": "@kbn/plugin-generator", - "license": "Apache-2.0", - "private": true, "version": "1.0.0", + "private": true, + "license": "Apache-2.0", + "main": "target/index.js", + "scripts": { + "kbn:bootstrap": "node scripts/build", + "kbn:watch": "node scripts/build --watch" + }, "dependencies": { - "chalk": "^4.1.0", - "dedent": "^0.7.0", + "@kbn/dev-utils": "1.0.0", + "ejs": "^3.1.5", "execa": "^4.0.2", - "getopts": "^2.2.4", - "lodash": "^4.17.15", - "sao": "^0.22.12" + "inquirer": "^7.3.3", + "normalize-path": "^3.0.0", + "prettier": "^2.0.5", + "vinyl": "^2.2.0", + "vinyl-fs": "^3.0.3" + }, + "devDependencies": { + "@types/ejs": "^3.0.4", + "@types/prettier": "^2.0.2", + "@types/inquirer": "^7.3.1" } } diff --git a/packages/kbn-plugin-generator/sao_template/sao.js b/packages/kbn-plugin-generator/sao_template/sao.js deleted file mode 100755 index e5f81a984ee93..0000000000000 --- a/packages/kbn-plugin-generator/sao_template/sao.js +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -const { relative, resolve } = require('path'); -const fs = require('fs'); - -const { camelCase, startCase, snakeCase } = require('lodash'); -const chalk = require('chalk'); -const execa = require('execa'); - -const pkg = require('../package.json'); -const kibanaPkgPath = require.resolve('../../../package.json'); -const kibanaPkg = require(kibanaPkgPath); // eslint-disable-line import/no-dynamic-require - -async function gitInit(dir) { - // Only plugins in /plugins get git init - try { - await execa('git', ['init', dir]); - console.log(`Git repo initialized in ${dir}`); - } catch (error) { - console.error(error); - throw new Error(`Failure to git init ${dir}: ${error.all || error}`); - } -} - -async function moveToCustomFolder(from, to) { - try { - await execa('mv', [from, to]); - } catch (error) { - console.error(error); - throw new Error(`Failure to move plugin to ${to}: ${error.all || error}`); - } -} - -async function eslintPlugin(dir) { - try { - await execa('yarn', ['lint:es', `./${dir}/**/*.ts*`, '--no-ignore', '--fix']); - } catch (error) { - console.error(error); - throw new Error(`Failure when running prettier on the generated output: ${error.all || error}`); - } -} - -module.exports = function ({ name, targetPath }) { - return { - prompts: { - customPath: { - message: 'Would you like to create the plugin in a different folder?', - default: '/plugins', - filter(value) { - // Keep default value empty - if (value === '/plugins') return ''; - // Remove leading slash - return value.startsWith('/') ? value.slice(1) : value; - }, - validate(customPath) { - const p = resolve(process.cwd(), customPath); - const exists = fs.existsSync(p); - if (!exists) - return `Folder should exist relative to the kibana root folder. Consider /src/plugins or /x-pack/plugins.`; - return true; - }, - }, - description: { - message: 'Provide a short description', - default: 'An awesome Kibana plugin', - }, - kbnVersion: { - message: 'What Kibana version are you targeting?', - default: kibanaPkg.version, - }, - generateApp: { - type: 'confirm', - message: 'Should an app component be generated?', - default: true, - }, - generateApi: { - type: 'confirm', - message: 'Should a server API be generated?', - default: true, - }, - generateTranslations: { - type: 'confirm', - when: (answers) => { - // only for 3rd party plugins - return !answers.customPath && answers.generateApp; - }, - message: 'Should translation files be generated?', - default({ customPath }) { - // only for 3rd party plugins - return !customPath; - }, - }, - generateScss: { - type: 'confirm', - message: 'Should SCSS be used?', - when: (answers) => answers.generateApp, - default: true, - }, - generateEslint: { - type: 'confirm', - message: 'Would you like to use a custom eslint file?', - default({ customPath }) { - return !customPath; - }, - }, - generateTsconfig: { - type: 'confirm', - message: 'Would you like to use a custom tsconfig file?', - default: true, - }, - }, - filters: { - 'public/**/index.scss': 'generateScss', - 'public/**/*': 'generateApp', - 'server/**/*': 'generateApi', - 'translations/**/*': 'generateTranslations', - 'i18nrc.json': 'generateTranslations', - 'eslintrc.js': 'generateEslint', - 'tsconfig.json': 'generateTsconfig', - }, - move: { - 'eslintrc.js': '.eslintrc.js', - 'i18nrc.json': '.i18nrc.json', - }, - data: (answers) => { - const pathToPlugin = answers.customPath - ? resolve(answers.customPath, camelCase(name), 'public') - : resolve(targetPath, 'public'); - return Object.assign( - { - templateVersion: pkg.version, - startCase, - camelCase, - snakeCase, - name, - // kibana plugins are placed in a the non default path - isKibanaPlugin: !answers.customPath, - kbnVersion: answers.kbnVersion, - upperCamelCaseName: name.charAt(0).toUpperCase() + camelCase(name).slice(1), - hasUi: !!answers.generateApp, - hasServer: !!answers.generateApi, - hasScss: !!answers.generateScss, - relRoot: relative(pathToPlugin, process.cwd()), - }, - answers - ); - }, - enforceNewFolder: true, - installDependencies: false, - async post({ log, answers }) { - let dir = relative(process.cwd(), targetPath); - if (answers.customPath) { - // Move to custom path - moveToCustomFolder(targetPath, answers.customPath); - dir = relative(process.cwd(), resolve(answers.customPath, snakeCase(name))); - } else { - // Init git only in the default path - await gitInit(dir); - } - - // Apply eslint to the generated plugin - eslintPlugin(dir); - - log.success(chalk`🎉 - -Your plugin has been created in {bold ${dir}}. - - {bold yarn start} -`); - }, - }; -}; diff --git a/packages/kbn-plugin-generator/sao_template/sao.test.js b/packages/kbn-plugin-generator/sao_template/sao.test.js deleted file mode 100755 index af243326cff33..0000000000000 --- a/packages/kbn-plugin-generator/sao_template/sao.test.js +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -const sao = require('sao'); - -const template = { - fromPath: __dirname, - configOptions: { - name: 'Some fancy plugin', - targetPath: '', - }, -}; - -function getFileContents(file) { - return file.contents.toString(); -} - -describe('plugin generator sao integration', () => { - test('skips files when answering no', async () => { - const res = await sao.mockPrompt(template, { - generateApp: false, - generateApi: false, - }); - - expect(res.fileList).toContain('common/index.ts'); - expect(res.fileList).not.toContain('public/index.ts'); - expect(res.fileList).not.toContain('server/index.ts'); - }); - - it('includes app when answering yes', async () => { - const res = await sao.mockPrompt(template, { - generateApp: true, - generateApi: false, - generateScss: true, - }); - - // check output files - expect(res.fileList).toContain('common/index.ts'); - expect(res.fileList).toContain('public/index.ts'); - expect(res.fileList).toContain('public/plugin.ts'); - expect(res.fileList).toContain('public/types.ts'); - expect(res.fileList).toContain('public/components/app.tsx'); - expect(res.fileList).toContain('public/index.scss'); - expect(res.fileList).not.toContain('server/index.ts'); - }); - - it('includes server api when answering yes', async () => { - const res = await sao.mockPrompt(template, { - generateApp: true, - generateApi: true, - }); - - // check output files - expect(res.fileList).toContain('public/plugin.ts'); - expect(res.fileList).toContain('server/plugin.ts'); - expect(res.fileList).toContain('server/index.ts'); - expect(res.fileList).toContain('server/types.ts'); - expect(res.fileList).toContain('server/routes/index.ts'); - }); - - it('skips eslintrc and scss', async () => { - const res = await sao.mockPrompt(template, { - generateApp: true, - generateApi: true, - generateScss: false, - generateEslint: false, - generateTsconfig: false, - }); - - // check output files - expect(res.fileList).toContain('public/plugin.ts'); - expect(res.fileList).not.toContain('public/index.scss'); - expect(res.fileList).not.toContain('.eslintrc.js'); - expect(res.fileList).not.toContain('tsconfig.json'); - }); - - it('plugin package has correct title', async () => { - const res = await sao.mockPrompt(template, { - generateApp: true, - generateApi: true, - }); - - const contents = getFileContents(res.files['common/index.ts']); - const controllerLine = contents.match("PLUGIN_NAME = '(.*)'")[1]; - - expect(controllerLine).toContain('Some fancy plugin'); - }); - - it('package has version "kibana" with master', async () => { - const res = await sao.mockPrompt(template, { - kbnVersion: 'master', - }); - - const packageContents = getFileContents(res.files['kibana.json']); - const pkg = JSON.parse(packageContents); - - expect(pkg.version).toBe('master'); - }); - - it('package has correct version', async () => { - const res = await sao.mockPrompt(template, { - kbnVersion: 'v6.0.0', - }); - - const packageContents = getFileContents(res.files['kibana.json']); - const pkg = JSON.parse(packageContents); - - expect(pkg.version).toBe('v6.0.0'); - }); - - it('sample app has correct values', async () => { - const res = await sao.mockPrompt(template, { - generateApp: true, - generateApi: true, - }); - - const contents = getFileContents(res.files['common/index.ts']); - const controllerLine = contents.match("PLUGIN_ID = '(.*)'")[1]; - - expect(controllerLine).toContain('someFancyPlugin'); - }); - - it('includes dotfiles', async () => { - const res = await sao.mockPrompt(template); - expect(res.files['tsconfig.json']).toBeTruthy(); - expect(res.files['.eslintrc.js']).toBeTruthy(); - expect(res.files['.i18nrc.json']).toBeTruthy(); - }); - - it('validaes path override', async () => { - try { - await sao.mockPrompt(template, { - generateApp: true, - generateApi: true, - generateScss: false, - generateEslint: false, - customPath: 'banana', - }); - } catch (e) { - expect(e.message).toContain('Validation failed at prompt "customPath"'); - } - }); -}); diff --git a/packages/kbn-plugin-generator/sao_template/template/eslintrc.js b/packages/kbn-plugin-generator/sao_template/template/eslintrc.js deleted file mode 100644 index b68d42e32e047..0000000000000 --- a/packages/kbn-plugin-generator/sao_template/template/eslintrc.js +++ /dev/null @@ -1,9 +0,0 @@ -module.exports = { - root: true, - extends: ['@elastic/eslint-config-kibana', 'plugin:@elastic/eui/recommended'], - <%_ if (!isKibanaPlugin) { -%> - rules: { - "@kbn/eslint/require-license-header": "off" - } - <%_ } -%> -}; \ No newline at end of file diff --git a/packages/kbn-plugin-generator/sao_template/template/i18nrc.json b/packages/kbn-plugin-generator/sao_template/template/i18nrc.json deleted file mode 100644 index a4b78b88e64e2..0000000000000 --- a/packages/kbn-plugin-generator/sao_template/template/i18nrc.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "prefix": "<%= camelCase(name) %>", - "paths": { - "<%= camelCase(name) %>": "." - }, - "translations": [ - "translations/ja-JP.json" - ] - } - \ No newline at end of file diff --git a/packages/kbn-plugin-generator/sao_template/template/public/application.tsx b/packages/kbn-plugin-generator/sao_template/template/public/application.tsx deleted file mode 100644 index 8106a18a784e7..0000000000000 --- a/packages/kbn-plugin-generator/sao_template/template/public/application.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import React from 'react'; -import ReactDOM from 'react-dom'; -import { AppMountParameters, CoreStart } from '<%= relRoot %>/src/core/public'; -import { AppPluginStartDependencies } from './types'; -import { <%= upperCamelCaseName %>App } from './components/app'; - - -export const renderApp = ( - { notifications, http }: CoreStart, - { navigation }: AppPluginStartDependencies, - { appBasePath, element }: AppMountParameters - ) => { - ReactDOM.render( - <<%= upperCamelCaseName %>App - basename={appBasePath} - notifications={notifications} - http={http} - navigation={navigation} - />, - element - ); - - return () => ReactDOM.unmountComponentAtNode(element); - }; - \ No newline at end of file diff --git a/packages/kbn-plugin-generator/sao_template/template/public/index.ts b/packages/kbn-plugin-generator/sao_template/template/public/index.ts deleted file mode 100644 index 2999dc7264ddb..0000000000000 --- a/packages/kbn-plugin-generator/sao_template/template/public/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -<%_ if (hasScss) { -%> -import './index.scss'; -<%_ } -%> - -import { <%= upperCamelCaseName %>Plugin } from './plugin'; - -// This exports static code and TypeScript types, -// as well as, Kibana Platform `plugin()` initializer. -export function plugin() { - return new <%= upperCamelCaseName %>Plugin(); -} -export { - <%= upperCamelCaseName %>PluginSetup, - <%= upperCamelCaseName %>PluginStart, -} from './types'; - diff --git a/packages/kbn-plugin-generator/sao_template/template/public/types.ts b/packages/kbn-plugin-generator/sao_template/template/public/types.ts deleted file mode 100644 index 2ebb0c0d1257f..0000000000000 --- a/packages/kbn-plugin-generator/sao_template/template/public/types.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { NavigationPublicPluginStart } from '<%= relRoot %>/src/plugins/navigation/public'; - -export interface <%= upperCamelCaseName %>PluginSetup { - getGreeting: () => string; -} -// eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface <%= upperCamelCaseName %>PluginStart {} - -export interface AppPluginStartDependencies { - navigation: NavigationPublicPluginStart -}; diff --git a/packages/kbn-plugin-generator/sao_template/template/server/index.ts b/packages/kbn-plugin-generator/sao_template/template/server/index.ts deleted file mode 100644 index 816b8faec2a45..0000000000000 --- a/packages/kbn-plugin-generator/sao_template/template/server/index.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { PluginInitializerContext } from '<%= relRoot %>/src/core/server'; -import { <%= upperCamelCaseName %>Plugin } from './plugin'; - - -// This exports static code and TypeScript types, -// as well as, Kibana Platform `plugin()` initializer. - - export function plugin(initializerContext: PluginInitializerContext) { - return new <%= upperCamelCaseName %>Plugin(initializerContext); -} - -export { - <%= upperCamelCaseName %>PluginSetup, - <%= upperCamelCaseName %>PluginStart, -} from './types'; diff --git a/packages/kbn-plugin-generator/sao_template/template/server/plugin.ts b/packages/kbn-plugin-generator/sao_template/template/server/plugin.ts deleted file mode 100644 index d6a343209e39e..0000000000000 --- a/packages/kbn-plugin-generator/sao_template/template/server/plugin.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { PluginInitializerContext, CoreSetup, CoreStart, Plugin, Logger } from '<%= relRoot %>/src/core/server'; - -import { <%= upperCamelCaseName %>PluginSetup, <%= upperCamelCaseName %>PluginStart } from './types'; -import { defineRoutes } from './routes'; - -export class <%= upperCamelCaseName %>Plugin - implements Plugin<<%= upperCamelCaseName %>PluginSetup, <%= upperCamelCaseName %>PluginStart> { - private readonly logger: Logger; - - constructor(initializerContext: PluginInitializerContext) { - this.logger = initializerContext.logger.get(); - } - - public setup(core: CoreSetup) { - this.logger.debug('<%= name %>: Setup'); - const router = core.http.createRouter(); - - // Register server side APIs - defineRoutes(router); - - return {}; - } - - public start(core: CoreStart) { - this.logger.debug('<%= name %>: Started'); - return {}; - } - - public stop() {} -} diff --git a/packages/kbn-plugin-generator/sao_template/template/translations/ja-JP.json b/packages/kbn-plugin-generator/sao_template/template/translations/ja-JP.json deleted file mode 100644 index ab4503f2c129c..0000000000000 --- a/packages/kbn-plugin-generator/sao_template/template/translations/ja-JP.json +++ /dev/null @@ -1,82 +0,0 @@ - -{ - "formats": { - "number": { - "currency": { - "style": "currency" - }, - "percent": { - "style": "percent" - } - }, - "date": { - "short": { - "month": "numeric", - "day": "numeric", - "year": "2-digit" - }, - "medium": { - "month": "short", - "day": "numeric", - "year": "numeric" - }, - "long": { - "month": "long", - "day": "numeric", - "year": "numeric" - }, - "full": { - "weekday": "long", - "month": "long", - "day": "numeric", - "year": "numeric" - } - }, - "time": { - "short": { - "hour": "numeric", - "minute": "numeric" - }, - "medium": { - "hour": "numeric", - "minute": "numeric", - "second": "numeric" - }, - "long": { - "hour": "numeric", - "minute": "numeric", - "second": "numeric", - "timeZoneName": "short" - }, - "full": { - "hour": "numeric", - "minute": "numeric", - "second": "numeric", - "timeZoneName": "short" - } - }, - "relative": { - "years": { - "units": "year" - }, - "months": { - "units": "month" - }, - "days": { - "units": "day" - }, - "hours": { - "units": "hour" - }, - "minutes": { - "units": "minute" - }, - "seconds": { - "units": "second" - } - } - }, - "messages": { - "<%= camelCase(name) %>.buttonText": "Translate me to Japanese", - } -} \ No newline at end of file diff --git a/packages/kbn-plugin-generator/scripts/build.js b/packages/kbn-plugin-generator/scripts/build.js new file mode 100644 index 0000000000000..2c252a064866c --- /dev/null +++ b/packages/kbn-plugin-generator/scripts/build.js @@ -0,0 +1,43 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +const Path = require('path'); + +const { run } = require('@kbn/dev-utils'); +const del = require('del'); +const execa = require('execa'); + +run( + async ({ flags }) => { + await del(Path.resolve(__dirname, '../target')); + + await execa(require.resolve('typescript/bin/tsc'), flags.watch ? ['--watch'] : [], { + cwd: Path.resolve(__dirname, '..'), + stdio: 'inherit', + }); + }, + { + flags: { + boolean: ['watch'], + help: ` + --watch Watch files and rebuild on changes + `, + }, + } +); diff --git a/packages/kbn-plugin-generator/src/ask_questions.ts b/packages/kbn-plugin-generator/src/ask_questions.ts new file mode 100644 index 0000000000000..b598396187245 --- /dev/null +++ b/packages/kbn-plugin-generator/src/ask_questions.ts @@ -0,0 +1,103 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import Path from 'path'; + +import { REPO_ROOT } from '@kbn/dev-utils'; +import inquirer from 'inquirer'; + +export interface Answers { + name: string; + internal: boolean; + internalLocation: string; + ui: boolean; + server: boolean; +} + +export const INTERNAL_PLUGIN_LOCATIONS: Array<{ name: string; value: string }> = [ + { + name: 'Kibana Example', + value: Path.resolve(REPO_ROOT, 'examples'), + }, + { + name: 'Kibana OSS', + value: Path.resolve(REPO_ROOT, 'src/plugins'), + }, + { + name: 'Kibana OSS Functional Testing', + value: Path.resolve(REPO_ROOT, 'test/plugin_functional/plugins'), + }, + { + name: 'X-Pack', + value: Path.resolve(REPO_ROOT, 'x-pack/plugins'), + }, + { + name: 'X-Pack Functional Testing', + value: Path.resolve(REPO_ROOT, 'x-pack/test/plugin_functional/plugins'), + }, +]; + +export const QUESTIONS = [ + { + name: 'name', + message: 'Plugin name (use camelCase)', + default: undefined, + validate: (name: string) => (!name ? 'name is required' : true), + }, + { + name: 'internal', + type: 'confirm', + message: 'Will this plugin be part of the Kibana repository?', + default: false, + }, + { + name: 'internalLocation', + type: 'list', + message: 'What type of internal plugin would you like to create', + choices: INTERNAL_PLUGIN_LOCATIONS, + default: INTERNAL_PLUGIN_LOCATIONS[0].value, + when: ({ internal }: Answers) => internal, + }, + { + name: 'ui', + type: 'confirm', + message: 'Should an UI plugin be generated?', + default: true, + }, + { + name: 'server', + type: 'confirm', + message: 'Should a server plugin be generated?', + default: true, + }, +] as const; + +export async function askQuestions(overrides: Partial) { + return await inquirer.prompt(QUESTIONS, overrides); +} + +export function getDefaultAnswers(overrides: Partial) { + return QUESTIONS.reduce( + (acc, q) => ({ + ...acc, + [q.name]: overrides[q.name] != null ? overrides[q.name] : q.default, + }), + {} + ) as Answers; +} diff --git a/packages/kbn-plugin-generator/src/casing.test.ts b/packages/kbn-plugin-generator/src/casing.test.ts new file mode 100644 index 0000000000000..05411678afdbf --- /dev/null +++ b/packages/kbn-plugin-generator/src/casing.test.ts @@ -0,0 +1,68 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { camelCase, snakeCase, upperCamelCase } from './casing'; + +describe('camelCase', () => { + it.each([ + ['foo', 'foo'], + ['foo_bar', 'fooBar'], + ['foo bar', 'fooBar'], + ['fooBar', 'fooBar'], + ['___foo *$( bar 14', 'fooBar14'], + ['foo-bar', 'fooBar'], + ['FOO BAR', 'fooBar'], + ['FOO_BAR', 'fooBar'], + ['FOOBAR', 'foobar'], + ])('converts %j to %j', (input, output) => { + expect(camelCase(input)).toBe(output); + }); +}); + +describe('upperCamelCase', () => { + it.each([ + ['foo', 'Foo'], + ['foo_bar', 'FooBar'], + ['foo bar', 'FooBar'], + ['fooBar', 'FooBar'], + ['___foo *$( bar 14', 'FooBar14'], + ['foo-bar', 'FooBar'], + ['FOO BAR', 'FooBar'], + ['FOO_BAR', 'FooBar'], + ['FOOBAR', 'Foobar'], + ])('converts %j to %j', (input, output) => { + expect(upperCamelCase(input)).toBe(output); + }); +}); + +describe('snakeCase', () => { + it.each([ + ['foo', 'foo'], + ['foo_bar', 'foo_bar'], + ['foo bar', 'foo_bar'], + ['fooBar', 'foo_bar'], + ['___foo *$( bar 14', 'foo_bar_14'], + ['foo-bar', 'foo_bar'], + ['FOO BAR', 'foo_bar'], + ['FOO_BAR', 'foo_bar'], + ['FOOBAR', 'foobar'], + ])('converts %j to %j', (input, output) => { + expect(snakeCase(input)).toBe(output); + }); +}); diff --git a/packages/kbn-plugin-generator/src/casing.ts b/packages/kbn-plugin-generator/src/casing.ts new file mode 100644 index 0000000000000..30296de65aecb --- /dev/null +++ b/packages/kbn-plugin-generator/src/casing.ts @@ -0,0 +1,32 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +const words = (input: string) => + input + .replace(/([a-z0-9])([A-Z])/g, '$1 $2') + .toLowerCase() + .split(/[^a-z0-9]+/g) + .filter(Boolean); + +const upperFirst = (input: string) => `${input.slice(0, 1).toUpperCase()}${input.slice(1)}`; +const lowerFirst = (input: string) => `${input.slice(0, 1).toLowerCase()}${input.slice(1)}`; + +export const snakeCase = (input: string) => words(input).join('_'); +export const upperCamelCase = (input: string) => words(input).map(upperFirst).join(''); +export const camelCase = (input: string) => lowerFirst(upperCamelCase(input)); diff --git a/packages/kbn-plugin-generator/src/cli.ts b/packages/kbn-plugin-generator/src/cli.ts new file mode 100644 index 0000000000000..f6966a245e46f --- /dev/null +++ b/packages/kbn-plugin-generator/src/cli.ts @@ -0,0 +1,98 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import Path from 'path'; +import Fs from 'fs'; + +import execa from 'execa'; +import { REPO_ROOT, run, createFailError, createFlagError } from '@kbn/dev-utils'; + +import { snakeCase } from './casing'; +import { askQuestions, getDefaultAnswers } from './ask_questions'; +import { renderTemplates } from './render_template'; + +export function runCli() { + run( + async ({ log, flags }) => { + const name = flags.name || undefined; + if (name && typeof name !== 'string') { + throw createFlagError(`expected one --name flag`); + } + + if (flags.yes && !name) { + throw createFlagError(`passing --yes requires that you specify a name`); + } + + const overrides = { + name, + ui: typeof flags.ui === 'boolean' ? flags.ui : undefined, + server: typeof flags.server === 'boolean' ? flags.server : undefined, + }; + const answers = flags.yes ? getDefaultAnswers(overrides) : await askQuestions(overrides); + + const outputDir = answers.internal + ? Path.resolve(answers.internalLocation, snakeCase(answers.name)) + : Path.resolve(REPO_ROOT, 'plugins', snakeCase(answers.name)); + + if (Fs.existsSync(outputDir)) { + throw createFailError(`Target output directory [${outputDir}] already exists`); + } + + // process the template directory, creating the actual plugin files + await renderTemplates({ + outputDir, + answers, + }); + + // init git repo in third party plugins + if (!answers.internal) { + await execa('git', ['init', outputDir]); + } + + log.success( + `🎉\n\nYour plugin has been created in ${Path.relative(process.cwd(), outputDir)}\n` + ); + }, + { + usage: 'node scripts/generate_plugin', + description: ` + Generate a fresh Kibana plugin in the plugins/ directory + `, + flags: { + string: ['name'], + boolean: ['yes', 'ui', 'server'], + default: { + ui: null, + server: null, + }, + alias: { + y: 'yes', + u: 'ui', + s: 'server', + }, + help: ` + --yes, -y Answer yes to all prompts, requires passing --name + --name Set the plugin name + --ui Generate a UI plugin + --server Generate a Server plugin + `, + }, + } + ); +} diff --git a/packages/kbn-plugin-generator/index.js.d.ts b/packages/kbn-plugin-generator/src/index.ts similarity index 88% rename from packages/kbn-plugin-generator/index.js.d.ts rename to packages/kbn-plugin-generator/src/index.ts index 46f7c43fd5790..a05bc698bde17 100644 --- a/packages/kbn-plugin-generator/index.js.d.ts +++ b/packages/kbn-plugin-generator/src/index.ts @@ -16,9 +16,5 @@ * specific language governing permissions and limitations * under the License. */ -interface PluginGenerator { - /** - * Run plugin generator. - */ - run: (...args: any[]) => any; -} + +export * from './cli'; diff --git a/packages/kbn-plugin-generator/src/integration_tests/generate_plugin.test.ts b/packages/kbn-plugin-generator/src/integration_tests/generate_plugin.test.ts new file mode 100644 index 0000000000000..b48113afc0ca7 --- /dev/null +++ b/packages/kbn-plugin-generator/src/integration_tests/generate_plugin.test.ts @@ -0,0 +1,143 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import Path from 'path'; + +import del from 'del'; +import execa from 'execa'; +import { REPO_ROOT, createAbsolutePathSerializer } from '@kbn/dev-utils'; +import globby from 'globby'; + +const GENERATED_DIR = Path.resolve(REPO_ROOT, `plugins`); + +expect.addSnapshotSerializer(createAbsolutePathSerializer()); + +beforeEach(async () => { + await del(GENERATED_DIR, { force: true }); +}); + +afterEach(async () => { + await del(GENERATED_DIR, { force: true }); +}); + +it('generates a plugin', async () => { + await execa(process.execPath, ['scripts/generate_plugin.js', '-y', '--name=foo'], { + cwd: REPO_ROOT, + buffer: true, + }); + + const paths = await globby('**/*', { + cwd: GENERATED_DIR, + absolute: true, + dot: true, + onlyFiles: true, + ignore: ['**/.git'], + }); + + expect(paths.sort((a, b) => a.localeCompare(b))).toMatchInlineSnapshot(` + Array [ + /plugins/foo/.eslintrc.js, + /plugins/foo/.gitignore, + /plugins/foo/.i18nrc.json, + /plugins/foo/common/index.ts, + /plugins/foo/kibana.json, + /plugins/foo/package.json, + /plugins/foo/public/application.tsx, + /plugins/foo/public/components/app.tsx, + /plugins/foo/public/index.scss, + /plugins/foo/public/index.ts, + /plugins/foo/public/plugin.ts, + /plugins/foo/public/types.ts, + /plugins/foo/README.md, + /plugins/foo/server/index.ts, + /plugins/foo/server/plugin.ts, + /plugins/foo/server/routes/index.ts, + /plugins/foo/server/types.ts, + /plugins/foo/translations/ja-JP.json, + /plugins/foo/tsconfig.json, + ] + `); +}); + +it('generates a plugin without UI', async () => { + await execa(process.execPath, ['scripts/generate_plugin.js', '--name=bar', '-y', '--no-ui'], { + cwd: REPO_ROOT, + buffer: true, + }); + + const paths = await globby('**/*', { + cwd: GENERATED_DIR, + absolute: true, + dot: true, + onlyFiles: true, + ignore: ['**/.git'], + }); + + expect(paths.sort((a, b) => a.localeCompare(b))).toMatchInlineSnapshot(` + Array [ + /plugins/bar/.eslintrc.js, + /plugins/bar/.gitignore, + /plugins/bar/.i18nrc.json, + /plugins/bar/common/index.ts, + /plugins/bar/kibana.json, + /plugins/bar/package.json, + /plugins/bar/README.md, + /plugins/bar/server/index.ts, + /plugins/bar/server/plugin.ts, + /plugins/bar/server/routes/index.ts, + /plugins/bar/server/types.ts, + /plugins/bar/tsconfig.json, + ] + `); +}); + +it('generates a plugin without server plugin', async () => { + await execa(process.execPath, ['scripts/generate_plugin.js', '--name=baz', '-y', '--no-server'], { + cwd: REPO_ROOT, + buffer: true, + }); + + const paths = await globby('**/*', { + cwd: GENERATED_DIR, + absolute: true, + dot: true, + onlyFiles: true, + ignore: ['**/.git'], + }); + + expect(paths.sort((a, b) => a.localeCompare(b))).toMatchInlineSnapshot(` + Array [ + /plugins/baz/.eslintrc.js, + /plugins/baz/.gitignore, + /plugins/baz/.i18nrc.json, + /plugins/baz/common/index.ts, + /plugins/baz/kibana.json, + /plugins/baz/package.json, + /plugins/baz/public/application.tsx, + /plugins/baz/public/components/app.tsx, + /plugins/baz/public/index.scss, + /plugins/baz/public/index.ts, + /plugins/baz/public/plugin.ts, + /plugins/baz/public/types.ts, + /plugins/baz/README.md, + /plugins/baz/translations/ja-JP.json, + /plugins/baz/tsconfig.json, + ] + `); +}); diff --git a/packages/kbn-plugin-generator/src/render_template.ts b/packages/kbn-plugin-generator/src/render_template.ts new file mode 100644 index 0000000000000..18bdcf1be1a6b --- /dev/null +++ b/packages/kbn-plugin-generator/src/render_template.ts @@ -0,0 +1,127 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import Path from 'path'; +import { pipeline } from 'stream'; +import { promisify } from 'util'; + +import vfs from 'vinyl-fs'; +import prettier from 'prettier'; +import { REPO_ROOT } from '@kbn/dev-utils'; +import ejs from 'ejs'; + +import { snakeCase, camelCase, upperCamelCase } from './casing'; +import { excludeFiles, tapFileStream } from './streams'; +import { Answers } from './ask_questions'; + +const asyncPipeline = promisify(pipeline); + +/** + * Stream all the files from the template directory, ignoring + * certain files based on the answers, process the .ejs templates + * to the output files they represent, renaming the .ejs files to + * remove that extension, then run every file through prettier + * before writing the files to the output directory. + */ +export async function renderTemplates({ + outputDir, + answers, +}: { + outputDir: string; + answers: Answers; +}) { + const prettierConfig = await prettier.resolveConfig(process.cwd()); + + const defaultTemplateData = { + name: answers.name, + + internalPlugin: !!answers.internal, + thirdPartyPlugin: !answers.internal, + + hasServer: !!answers.server, + hasUi: !!answers.ui, + + camelCase, + snakeCase, + upperCamelCase, + }; + + await asyncPipeline( + vfs.src(['**/*'], { + dot: true, + buffer: true, + nodir: true, + cwd: Path.resolve(__dirname, '../template'), + }), + + // exclude files from the template based on selected options, patterns + // are matched without the .ejs extension + excludeFiles( + ([] as string[]).concat( + answers.ui ? [] : 'public/**/*', + answers.ui && !answers.internal ? [] : ['translations/**/*', 'i18nrc.json'], + answers.server ? [] : 'server/**/*', + !answers.internal ? [] : ['eslintrc.js', 'tsconfig.json', 'package.json', '.gitignore'] + ) + ), + + // render .ejs templates and rename to not use .ejs extension + tapFileStream((file) => { + if (file.extname !== '.ejs') { + return; + } + + const templateData = { + ...defaultTemplateData, + importFromRoot(rootRelative: string) { + const filesOutputDirname = Path.dirname(Path.resolve(outputDir, file.relative)); + const target = Path.resolve(REPO_ROOT, rootRelative); + return Path.relative(filesOutputDirname, target); + }, + }; + + // render source and write back to file object + file.contents = Buffer.from( + ejs.render(file.contents.toString('utf8'), templateData, { + beautify: false, + }) + ); + + // file.stem is the basename but without the extension + file.basename = file.stem; + }), + + // format each file with prettier + tapFileStream((file) => { + if (!file.extname) { + return; + } + + file.contents = Buffer.from( + prettier.format(file.contents.toString('utf8'), { + ...prettierConfig, + filepath: file.path, + }) + ); + }), + + // write files to disk + vfs.dest(outputDir) + ); +} diff --git a/packages/kbn-plugin-generator/src/streams.ts b/packages/kbn-plugin-generator/src/streams.ts new file mode 100644 index 0000000000000..976008e879dd3 --- /dev/null +++ b/packages/kbn-plugin-generator/src/streams.ts @@ -0,0 +1,73 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { Transform } from 'stream'; + +import File from 'vinyl'; +import { Minimatch } from 'minimatch'; + +interface BufferedFile extends File { + contents: Buffer; + isDirectory(): false; +} + +/** + * Create a transform stream that processes Vinyl fs streams and + * calls a function for each file, allowing the function to either + * mutate the file, replace it with another file (return a new File + * object), or drop it from the stream (return null) + */ +export const tapFileStream = ( + fn: (file: BufferedFile) => File | void | null | Promise +) => + new Transform({ + objectMode: true, + transform(file: BufferedFile, _, cb) { + Promise.resolve(file) + .then(fn) + .then( + (result) => { + // drop the file when null is returned + if (result === null) { + cb(); + } else { + cb(undefined, result || file); + } + }, + (error) => cb(error) + ); + }, + }); + +export const excludeFiles = (globs: string[]) => { + const patterns = globs.map( + (g) => + new Minimatch(g, { + matchBase: true, + }) + ); + + return tapFileStream((file) => { + const path = file.relative.replace(/\.ejs$/, ''); + const exclude = patterns.some((p) => p.match(path)); + if (exclude) { + return null; + } + }); +}; diff --git a/packages/kbn-plugin-generator/template/.eslintrc.js.ejs b/packages/kbn-plugin-generator/template/.eslintrc.js.ejs new file mode 100644 index 0000000000000..d063fc481b718 --- /dev/null +++ b/packages/kbn-plugin-generator/template/.eslintrc.js.ejs @@ -0,0 +1,10 @@ +module.exports = { + root: true, + extends: [ + '@elastic/eslint-config-kibana', + 'plugin:@elastic/eui/recommended' + ], + rules: { + '@kbn/eslint/require-license-header': 'off', + }, +}; diff --git a/packages/kbn-plugin-generator/template/.gitignore b/packages/kbn-plugin-generator/template/.gitignore new file mode 100644 index 0000000000000..c3dca1b96fcc2 --- /dev/null +++ b/packages/kbn-plugin-generator/template/.gitignore @@ -0,0 +1,2 @@ +/build +/target diff --git a/packages/kbn-plugin-generator/template/.i18nrc.json.ejs b/packages/kbn-plugin-generator/template/.i18nrc.json.ejs new file mode 100644 index 0000000000000..280fb5cca62b9 --- /dev/null +++ b/packages/kbn-plugin-generator/template/.i18nrc.json.ejs @@ -0,0 +1,9 @@ +{ + "prefix": "<%= camelCase(name) %>", + "paths": { + "<%= camelCase(name) %>": "." + }, + "translations": [ + "translations/ja-JP.json" + ] +} diff --git a/packages/kbn-plugin-generator/sao_template/template/README.md b/packages/kbn-plugin-generator/template/README.md.ejs similarity index 66% rename from packages/kbn-plugin-generator/sao_template/template/README.md rename to packages/kbn-plugin-generator/template/README.md.ejs index 008d500abbbf5..5f30bf0463305 100755 --- a/packages/kbn-plugin-generator/sao_template/template/README.md +++ b/packages/kbn-plugin-generator/template/README.md.ejs @@ -1,8 +1,6 @@ # <%= name %> -<%- (description || '').split('\n').map(function (line) { - return '> ' + line -}).join('\n') %> +A Kibana plugin --- diff --git a/packages/kbn-plugin-generator/sao_template/template/common/index.ts b/packages/kbn-plugin-generator/template/common/index.ts.ejs similarity index 100% rename from packages/kbn-plugin-generator/sao_template/template/common/index.ts rename to packages/kbn-plugin-generator/template/common/index.ts.ejs diff --git a/packages/kbn-plugin-generator/sao_template/template/kibana.json b/packages/kbn-plugin-generator/template/kibana.json.ejs similarity index 74% rename from packages/kbn-plugin-generator/sao_template/template/kibana.json rename to packages/kbn-plugin-generator/template/kibana.json.ejs index f8bb07040abeb..698a394e0d0b5 100644 --- a/packages/kbn-plugin-generator/sao_template/template/kibana.json +++ b/packages/kbn-plugin-generator/template/kibana.json.ejs @@ -1,6 +1,7 @@ { "id": "<%= camelCase(name) %>", - "version": "<%= kbnVersion %>", + "version": "1.0.0", + "kibanaVersion": "kibana", "server": <%= hasServer %>, "ui": <%= hasUi %>, "requiredPlugins": ["navigation"], diff --git a/packages/kbn-plugin-generator/template/package.json.ejs b/packages/kbn-plugin-generator/template/package.json.ejs new file mode 100644 index 0000000000000..cbd59894ca47c --- /dev/null +++ b/packages/kbn-plugin-generator/template/package.json.ejs @@ -0,0 +1,8 @@ +{ + "name": "<%= camelCase(name) %>", + "version": "0.0.0", + "private": true, + "scripts": { + "kbn": "node ../../scripts/kbn" + } +} diff --git a/packages/kbn-plugin-generator/template/public/application.tsx.ejs b/packages/kbn-plugin-generator/template/public/application.tsx.ejs new file mode 100644 index 0000000000000..678d7ccc04681 --- /dev/null +++ b/packages/kbn-plugin-generator/template/public/application.tsx.ejs @@ -0,0 +1,24 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import { AppMountParameters, CoreStart } from '<%= importFromRoot('src/core/public') %>'; +import { AppPluginStartDependencies } from './types'; +import { <%= upperCamelCase(name) %>App } from './components/app'; + + +export const renderApp = ( + { notifications, http }: CoreStart, + { navigation }: AppPluginStartDependencies, + { appBasePath, element }: AppMountParameters +) => { + ReactDOM.render( + <<%= upperCamelCase(name) %>App + basename={appBasePath} + notifications={notifications} + http={http} + navigation={navigation} + />, + element + ); + + return () => ReactDOM.unmountComponentAtNode(element); +}; diff --git a/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx b/packages/kbn-plugin-generator/template/public/components/app.tsx.ejs similarity index 62% rename from packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx rename to packages/kbn-plugin-generator/template/public/components/app.tsx.ejs index d75bd2f01ef23..c3e33788464fb 100644 --- a/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx +++ b/packages/kbn-plugin-generator/template/public/components/app.tsx.ejs @@ -1,22 +1,3 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - import React, { useState } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage, I18nProvider } from '@kbn/i18n/react'; @@ -35,36 +16,36 @@ import { EuiText, } from '@elastic/eui'; -import { CoreStart } from '<%= relRoot %>/../src/core/public'; -import { NavigationPublicPluginStart } from '<%= relRoot %>/../src/plugins/navigation/public'; +import { CoreStart } from '<%= importFromRoot('src/core/public') %>'; +import { NavigationPublicPluginStart } from '<%= importFromRoot('src/plugins/navigation/public') %>'; import { PLUGIN_ID, PLUGIN_NAME } from '../../common'; -interface <%= upperCamelCaseName %>AppDeps { +interface <%= upperCamelCase(name) %>AppDeps { basename: string; notifications: CoreStart['notifications']; http: CoreStart['http']; navigation: NavigationPublicPluginStart; } -export const <%= upperCamelCaseName %>App = ({ basename, notifications, http, navigation }: <%= upperCamelCaseName %>AppDeps) => { +export const <%= upperCamelCase(name) %>App = ({ basename, notifications, http, navigation }: <%= upperCamelCase(name) %>AppDeps) => { // Use React hooks to manage state. const [timestamp, setTimestamp] = useState(); const onClickHandler = () => { -<%_ if (generateApi) { -%> - // Use the core http service to make a response to the server API. - http.get('/api/<%= snakeCase(name) %>/example').then(res => { - setTimestamp(res.time); - // Use the core notifications service to display a success message. - notifications.toasts.addSuccess(i18n.translate('<%= camelCase(name) %>.dataUpdated', { - defaultMessage: 'Data updated', - })); - }); -<%_ } else { -%> - setTimestamp(new Date().toISOString()); - notifications.toasts.addSuccess(PLUGIN_NAME); -<%_ } -%> + <% if (hasServer) { %> + // Use the core http service to make a response to the server API. + http.get('/api/<%= snakeCase(name) %>/example').then(res => { + setTimestamp(res.time); + // Use the core notifications service to display a success message. + notifications.toasts.addSuccess(i18n.translate('<%= camelCase(name) %>.dataUpdated', { + defaultMessage: 'Data updated', + })); + }); + <% } else { %> + setTimestamp(new Date().toISOString()); + notifications.toasts.addSuccess(PLUGIN_NAME); + <% } %> }; // Render the application DOM. @@ -115,7 +96,10 @@ export const <%= upperCamelCaseName %>App = ({ basename, notifications, http, na />

- + diff --git a/packages/kbn-plugin-generator/sao_template/template/public/index.scss b/packages/kbn-plugin-generator/template/public/index.scss similarity index 100% rename from packages/kbn-plugin-generator/sao_template/template/public/index.scss rename to packages/kbn-plugin-generator/template/public/index.scss diff --git a/packages/kbn-plugin-generator/template/public/index.ts.ejs b/packages/kbn-plugin-generator/template/public/index.ts.ejs new file mode 100644 index 0000000000000..f859f34bee2ee --- /dev/null +++ b/packages/kbn-plugin-generator/template/public/index.ts.ejs @@ -0,0 +1,14 @@ +import './index.scss'; + +import { <%= upperCamelCase(name) %>Plugin } from './plugin'; + +// This exports static code and TypeScript types, +// as well as, Kibana Platform `plugin()` initializer. +export function plugin() { + return new <%= upperCamelCase(name) %>Plugin(); +} +export { + <%= upperCamelCase(name) %>PluginSetup, + <%= upperCamelCase(name) %>PluginStart, +} from './types'; + diff --git a/packages/kbn-plugin-generator/sao_template/template/public/plugin.ts b/packages/kbn-plugin-generator/template/public/plugin.ts.ejs similarity index 68% rename from packages/kbn-plugin-generator/sao_template/template/public/plugin.ts rename to packages/kbn-plugin-generator/template/public/plugin.ts.ejs index 76f7f1a6f9908..1090430ab7f87 100644 --- a/packages/kbn-plugin-generator/sao_template/template/public/plugin.ts +++ b/packages/kbn-plugin-generator/template/public/plugin.ts.ejs @@ -1,12 +1,12 @@ import { i18n } from '@kbn/i18n'; -import { AppMountParameters, CoreSetup, CoreStart, Plugin } from '<%= relRoot %>/src/core/public'; -import { <%= upperCamelCaseName %>PluginSetup, <%= upperCamelCaseName %>PluginStart, AppPluginStartDependencies } from './types'; +import { AppMountParameters, CoreSetup, CoreStart, Plugin } from '<%= importFromRoot('src/core/public') %>'; +import { <%= upperCamelCase(name) %>PluginSetup, <%= upperCamelCase(name) %>PluginStart, AppPluginStartDependencies } from './types'; import { PLUGIN_NAME } from '../common'; -export class <%= upperCamelCaseName %>Plugin - implements Plugin<<%= upperCamelCaseName %>PluginSetup, <%= upperCamelCaseName %>PluginStart> { - - public setup(core: CoreSetup): <%= upperCamelCaseName %>PluginSetup { +export class <%= upperCamelCase(name) %>Plugin + implements Plugin<<%= upperCamelCase(name) %>PluginSetup, <%= upperCamelCase(name) %>PluginStart> { + + public setup(core: CoreSetup): <%= upperCamelCase(name) %>PluginSetup { // Register an application into the side navigation menu core.application.register({ id: '<%= camelCase(name) %>', @@ -34,7 +34,7 @@ export class <%= upperCamelCaseName %>Plugin }; } - public start(core: CoreStart): <%= upperCamelCaseName %>PluginStart { + public start(core: CoreStart): <%= upperCamelCase(name) %>PluginStart { return {}; } diff --git a/packages/kbn-plugin-generator/template/public/types.ts.ejs b/packages/kbn-plugin-generator/template/public/types.ts.ejs new file mode 100644 index 0000000000000..e33db549ccd04 --- /dev/null +++ b/packages/kbn-plugin-generator/template/public/types.ts.ejs @@ -0,0 +1,11 @@ +import { NavigationPublicPluginStart } from '<%= importFromRoot('src/plugins/navigation/public') %>'; + +export interface <%= upperCamelCase(name) %>PluginSetup { + getGreeting: () => string; +} +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface <%= upperCamelCase(name) %>PluginStart {} + +export interface AppPluginStartDependencies { + navigation: NavigationPublicPluginStart +}; diff --git a/packages/kbn-plugin-generator/template/server/index.ts.ejs b/packages/kbn-plugin-generator/template/server/index.ts.ejs new file mode 100644 index 0000000000000..f6b40f2ee0642 --- /dev/null +++ b/packages/kbn-plugin-generator/template/server/index.ts.ejs @@ -0,0 +1,15 @@ +import { PluginInitializerContext } from '<%= importFromRoot('src/core/server') %>'; +import { <%= upperCamelCase(name) %>Plugin } from './plugin'; + + +// This exports static code and TypeScript types, +// as well as, Kibana Platform `plugin()` initializer. + + export function plugin(initializerContext: PluginInitializerContext) { + return new <%= upperCamelCase(name) %>Plugin(initializerContext); +} + +export { + <%= upperCamelCase(name) %>PluginSetup, + <%= upperCamelCase(name) %>PluginStart, +} from './types'; diff --git a/packages/kbn-plugin-generator/template/server/plugin.ts.ejs b/packages/kbn-plugin-generator/template/server/plugin.ts.ejs new file mode 100644 index 0000000000000..b91e793653003 --- /dev/null +++ b/packages/kbn-plugin-generator/template/server/plugin.ts.ejs @@ -0,0 +1,40 @@ +import { + PluginInitializerContext, + CoreSetup, + CoreStart, + Plugin, + Logger +} from '<%= importFromRoot('src/core/server') %>'; + +import { + <%= upperCamelCase(name) %>PluginSetup, + <%= upperCamelCase(name) %>PluginStart +} from './types'; +import { defineRoutes } from './routes'; + +export class <%= upperCamelCase(name) %>Plugin + implements Plugin<<%= upperCamelCase(name) %>PluginSetup, <%= upperCamelCase(name) %>PluginStart> { + + private readonly logger: Logger; + + constructor(initializerContext: PluginInitializerContext) { + this.logger = initializerContext.logger.get(); + } + + public setup(core: CoreSetup) { + this.logger.debug('<%= name %>: Setup'); + const router = core.http.createRouter(); + + // Register server side APIs + defineRoutes(router); + + return {}; + } + + public start(core: CoreStart) { + this.logger.debug('<%= name %>: Started'); + return {}; + } + + public stop() {} +} diff --git a/packages/kbn-plugin-generator/sao_template/template/server/routes/index.ts b/packages/kbn-plugin-generator/template/server/routes/index.ts.ejs similarity index 81% rename from packages/kbn-plugin-generator/sao_template/template/server/routes/index.ts rename to packages/kbn-plugin-generator/template/server/routes/index.ts.ejs index d8bb00f0dea6c..475200ca21632 100644 --- a/packages/kbn-plugin-generator/sao_template/template/server/routes/index.ts +++ b/packages/kbn-plugin-generator/template/server/routes/index.ts.ejs @@ -1,4 +1,5 @@ -import { IRouter } from '<%= relRoot %>/../src/core/server'; +import { IRouter } from '<%= importFromRoot('src/core/server') %>'; + export function defineRoutes(router: IRouter) { router.get( diff --git a/packages/kbn-plugin-generator/sao_template/template/server/types.ts b/packages/kbn-plugin-generator/template/server/types.ts.ejs similarity index 52% rename from packages/kbn-plugin-generator/sao_template/template/server/types.ts rename to packages/kbn-plugin-generator/template/server/types.ts.ejs index adbc5e93f03c5..2ed6a8436bec4 100644 --- a/packages/kbn-plugin-generator/sao_template/template/server/types.ts +++ b/packages/kbn-plugin-generator/template/server/types.ts.ejs @@ -1,4 +1,4 @@ // eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface <%= upperCamelCaseName %>PluginSetup {} +export interface <%= upperCamelCase(name) %>PluginSetup {} // eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface <%= upperCamelCaseName %>PluginStart {} +export interface <%= upperCamelCase(name) %>PluginStart {} diff --git a/packages/kbn-plugin-generator/template/translations/ja-JP.json.ejs b/packages/kbn-plugin-generator/template/translations/ja-JP.json.ejs new file mode 100644 index 0000000000000..134f96481bcad --- /dev/null +++ b/packages/kbn-plugin-generator/template/translations/ja-JP.json.ejs @@ -0,0 +1,81 @@ +{ + "formats": { + "number": { + "currency": { + "style": "currency" + }, + "percent": { + "style": "percent" + } + }, + "date": { + "short": { + "month": "numeric", + "day": "numeric", + "year": "2-digit" + }, + "medium": { + "month": "short", + "day": "numeric", + "year": "numeric" + }, + "long": { + "month": "long", + "day": "numeric", + "year": "numeric" + }, + "full": { + "weekday": "long", + "month": "long", + "day": "numeric", + "year": "numeric" + } + }, + "time": { + "short": { + "hour": "numeric", + "minute": "numeric" + }, + "medium": { + "hour": "numeric", + "minute": "numeric", + "second": "numeric" + }, + "long": { + "hour": "numeric", + "minute": "numeric", + "second": "numeric", + "timeZoneName": "short" + }, + "full": { + "hour": "numeric", + "minute": "numeric", + "second": "numeric", + "timeZoneName": "short" + } + }, + "relative": { + "years": { + "units": "year" + }, + "months": { + "units": "month" + }, + "days": { + "units": "day" + }, + "hours": { + "units": "hour" + }, + "minutes": { + "units": "minute" + }, + "seconds": { + "units": "second" + } + } + }, + "messages": { + "<%= camelCase(name) %>.buttonText": "Translate me to Japanese", + } +} diff --git a/packages/kbn-plugin-generator/sao_template/template/tsconfig.json b/packages/kbn-plugin-generator/template/tsconfig.json.ejs similarity index 100% rename from packages/kbn-plugin-generator/sao_template/template/tsconfig.json rename to packages/kbn-plugin-generator/template/tsconfig.json.ejs diff --git a/packages/kbn-plugin-generator/tsconfig.json b/packages/kbn-plugin-generator/tsconfig.json index fe0f7112f1fa9..fc88223dae4b2 100644 --- a/packages/kbn-plugin-generator/tsconfig.json +++ b/packages/kbn-plugin-generator/tsconfig.json @@ -1,5 +1,12 @@ { "extends": "../../tsconfig.json", - "include": ["**/*", "index.js.d.ts"], - "exclude": ["sao_template/template/*"] + "compilerOptions": { + "outDir": "target", + "target": "ES2019", + "declaration": true, + "declarationMap": true, + "sourceMap": true + }, + "include": ["src/**/*"], + "exclude": ["src/template/*"] } diff --git a/packages/kbn-pm/dist/index.js b/packages/kbn-pm/dist/index.js index 339f16eaf8593..1d4c13e605f27 100644 --- a/packages/kbn-pm/dist/index.js +++ b/packages/kbn-pm/dist/index.js @@ -94,7 +94,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _cli__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "run", function() { return _cli__WEBPACK_IMPORTED_MODULE_0__["run"]; }); -/* harmony import */ var _production__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(505); +/* harmony import */ var _production__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(503); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "buildProductionProjects", function() { return _production__WEBPACK_IMPORTED_MODULE_1__["buildProductionProjects"]; }); /* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(145); @@ -103,10 +103,10 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _utils_project__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(163); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Project", function() { return _utils_project__WEBPACK_IMPORTED_MODULE_3__["Project"]; }); -/* harmony import */ var _utils_workspaces__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(287); +/* harmony import */ var _utils_workspaces__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(279); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "copyWorkspacePackages", function() { return _utils_workspaces__WEBPACK_IMPORTED_MODULE_4__["copyWorkspacePackages"]; }); -/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(288); +/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(280); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "getProjectPaths", function() { return _config__WEBPACK_IMPORTED_MODULE_5__["getProjectPaths"]; }); /* @@ -150,7 +150,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _kbn_dev_utils_tooling_log__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(5); /* harmony import */ var _kbn_dev_utils_tooling_log__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_kbn_dev_utils_tooling_log__WEBPACK_IMPORTED_MODULE_3__); /* harmony import */ var _commands__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(127); -/* harmony import */ var _run__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(498); +/* harmony import */ var _run__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(496); /* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(143); /* * Licensed to Elasticsearch B.V. under one or more contributor @@ -8762,9 +8762,9 @@ exports.ToolingLogCollectingWriter = ToolingLogCollectingWriter; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "commands", function() { return commands; }); /* harmony import */ var _bootstrap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(128); -/* harmony import */ var _clean__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(295); -/* harmony import */ var _run__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(397); -/* harmony import */ var _watch__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(398); +/* harmony import */ var _clean__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(287); +/* harmony import */ var _run__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(395); +/* harmony import */ var _watch__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(396); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -8805,8 +8805,8 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); /* harmony import */ var _utils_parallelize__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(144); /* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(145); -/* harmony import */ var _utils_project_checksums__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(289); -/* harmony import */ var _utils_bootstrap_cache_file__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(294); +/* harmony import */ var _utils_project_checksums__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(281); +/* harmony import */ var _utils_bootstrap_cache_file__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(286); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -9393,6 +9393,14 @@ if (typeof Symbol === 'function' && typeof Symbol.for === 'function') { function noop () {} +function publishQueue(context, queue) { + Object.defineProperty(context, gracefulQueue, { + get: function() { + return queue + } + }) +} + var debug = noop if (util.debuglog) debug = util.debuglog('gfs4') @@ -9404,14 +9412,10 @@ else if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) } // Once time initialization -if (!global[gracefulQueue]) { +if (!fs[gracefulQueue]) { // This queue can be shared by multiple loaded instances - var queue = [] - Object.defineProperty(global, gracefulQueue, { - get: function() { - return queue - } - }) + var queue = global[gracefulQueue] || [] + publishQueue(fs, queue) // Patch fs.close/closeSync to shared queue version, because we need // to retry() whenever a close happens *anywhere* in the program. @@ -9451,12 +9455,16 @@ if (!global[gracefulQueue]) { if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) { process.on('exit', function() { - debug(global[gracefulQueue]) - __webpack_require__(139).equal(global[gracefulQueue].length, 0) + debug(fs[gracefulQueue]) + __webpack_require__(139).equal(fs[gracefulQueue].length, 0) }) } } +if (!global[gracefulQueue]) { + publishQueue(global, fs[gracefulQueue]); +} + module.exports = patch(clone(fs)) if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH && !fs.__patched) { module.exports = patch(fs) @@ -9706,11 +9714,11 @@ function patch (fs) { function enqueue (elem) { debug('ENQUEUE', elem[0].name, elem[1]) - global[gracefulQueue].push(elem) + fs[gracefulQueue].push(elem) } function retry () { - var elem = global[gracefulQueue].shift() + var elem = fs[gracefulQueue].shift() if (elem) { debug('RETRY', elem[0].name, elem[1]) elem[0].apply(null, elem[1]) @@ -10814,7 +10822,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(util__WEBPACK_IMPORTED_MODULE_2__); /* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(162); /* harmony import */ var _project__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(163); -/* harmony import */ var _workspaces__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(287); +/* harmony import */ var _workspaces__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(279); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -14425,7 +14433,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(162); /* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(143); /* harmony import */ var _package_json__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(164); -/* harmony import */ var _scripts__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(233); +/* harmony import */ var _scripts__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(225); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } @@ -22347,7 +22355,7 @@ module.exports = JSON.parse("{\"repositories\":\"'repositories' (plural) Not sup const path = __webpack_require__(4); const writeJsonFile = __webpack_require__(214); -const sortKeys = __webpack_require__(228); +const sortKeys = __webpack_require__(220); const dependencyKeys = new Set([ 'dependencies', @@ -22418,12 +22426,12 @@ module.exports.sync = (filePath, data, options) => { "use strict"; const path = __webpack_require__(4); -const fs = __webpack_require__(215); -const writeFileAtomic = __webpack_require__(219); -const sortKeys = __webpack_require__(228); -const makeDir = __webpack_require__(230); -const pify = __webpack_require__(231); -const detectIndent = __webpack_require__(232); +const fs = __webpack_require__(132); +const writeFileAtomic = __webpack_require__(215); +const sortKeys = __webpack_require__(220); +const makeDir = __webpack_require__(222); +const pify = __webpack_require__(223); +const detectIndent = __webpack_require__(224); const init = (fn, filePath, data, options) => { if (!filePath) { @@ -22498,8363 +22506,8020 @@ module.exports.sync = (filePath, data, options) => { /* 215 */ /***/ (function(module, exports, __webpack_require__) { -var fs = __webpack_require__(133) -var polyfills = __webpack_require__(216) -var legacy = __webpack_require__(217) -var clone = __webpack_require__(218) +"use strict"; -var queue = [] +module.exports = writeFile +module.exports.sync = writeFileSync +module.exports._getTmpname = getTmpname // for testing +module.exports._cleanupOnExit = cleanupOnExit -var util = __webpack_require__(111) +var fs = __webpack_require__(132) +var MurmurHash3 = __webpack_require__(216) +var onExit = __webpack_require__(217) +var path = __webpack_require__(4) +var activeFiles = {} -function noop () {} +// if we run inside of a worker_thread, `process.pid` is not unique +/* istanbul ignore next */ +var threadId = (function getId () { + try { + var workerThreads = __webpack_require__(219) -var debug = noop -if (util.debuglog) - debug = util.debuglog('gfs4') -else if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) - debug = function() { - var m = util.format.apply(util, arguments) - m = 'GFS4: ' + m.split(/\n/).join('\nGFS4: ') - console.error(m) + /// if we are in main thread, this is set to `0` + return workerThreads.threadId + } catch (e) { + // worker_threads are not available, fallback to 0 + return 0 } +})() -if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) { - process.on('exit', function() { - debug(queue) - __webpack_require__(139).equal(queue.length, 0) - }) -} - -module.exports = patch(clone(fs)) -if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH && !fs.__patched) { - module.exports = patch(fs) - fs.__patched = true; +var invocations = 0 +function getTmpname (filename) { + return filename + '.' + + MurmurHash3(__filename) + .hash(String(process.pid)) + .hash(String(threadId)) + .hash(String(++invocations)) + .result() } -// Always patch fs.close/closeSync, because we want to -// retry() whenever a close happens *anywhere* in the program. -// This is essential when multiple graceful-fs instances are -// in play at the same time. -module.exports.close = (function (fs$close) { return function (fd, cb) { - return fs$close.call(fs, fd, function (err) { - if (!err) - retry() - - if (typeof cb === 'function') - cb.apply(this, arguments) - }) -}})(fs.close) - -module.exports.closeSync = (function (fs$closeSync) { return function (fd) { - // Note that graceful-fs also retries when fs.closeSync() fails. - // Looks like a bug to me, although it's probably a harmless one. - var rval = fs$closeSync.apply(fs, arguments) - retry() - return rval -}})(fs.closeSync) - -// Only patch fs once, otherwise we'll run into a memory leak if -// graceful-fs is loaded multiple times, such as in test environments that -// reset the loaded modules between tests. -// We look for the string `graceful-fs` from the comment above. This -// way we are not adding any extra properties and it will detect if older -// versions of graceful-fs are installed. -if (!/\bgraceful-fs\b/.test(fs.closeSync.toString())) { - fs.closeSync = module.exports.closeSync; - fs.close = module.exports.close; +function cleanupOnExit (tmpfile) { + return function () { + try { + fs.unlinkSync(typeof tmpfile === 'function' ? tmpfile() : tmpfile) + } catch (_) {} + } } -function patch (fs) { - // Everything that references the open() function needs to be in here - polyfills(fs) - fs.gracefulify = patch - fs.FileReadStream = ReadStream; // Legacy name. - fs.FileWriteStream = WriteStream; // Legacy name. - fs.createReadStream = createReadStream - fs.createWriteStream = createWriteStream - var fs$readFile = fs.readFile - fs.readFile = readFile - function readFile (path, options, cb) { - if (typeof options === 'function') - cb = options, options = null - - return go$readFile(path, options, cb) - - function go$readFile (path, options, cb) { - return fs$readFile(path, options, function (err) { - if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) - enqueue([go$readFile, [path, options, cb]]) - else { - if (typeof cb === 'function') - cb.apply(this, arguments) - retry() - } - }) +function writeFile (filename, data, options, callback) { + if (options) { + if (options instanceof Function) { + callback = options + options = {} + } else if (typeof options === 'string') { + options = { encoding: options } } + } else { + options = {} } - var fs$writeFile = fs.writeFile - fs.writeFile = writeFile - function writeFile (path, data, options, cb) { - if (typeof options === 'function') - cb = options, options = null + var Promise = options.Promise || global.Promise + var truename + var fd + var tmpfile + /* istanbul ignore next -- The closure only gets called when onExit triggers */ + var removeOnExitHandler = onExit(cleanupOnExit(() => tmpfile)) + var absoluteName = path.resolve(filename) - return go$writeFile(path, data, options, cb) + new Promise(function serializeSameFile (resolve) { + // make a queue if it doesn't already exist + if (!activeFiles[absoluteName]) activeFiles[absoluteName] = [] - function go$writeFile (path, data, options, cb) { - return fs$writeFile(path, data, options, function (err) { - if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) - enqueue([go$writeFile, [path, data, options, cb]]) - else { - if (typeof cb === 'function') - cb.apply(this, arguments) - retry() - } + activeFiles[absoluteName].push(resolve) // add this job to the queue + if (activeFiles[absoluteName].length === 1) resolve() // kick off the first one + }).then(function getRealPath () { + return new Promise(function (resolve) { + fs.realpath(filename, function (_, realname) { + truename = realname || filename + tmpfile = getTmpname(truename) + resolve() }) - } - } - - var fs$appendFile = fs.appendFile - if (fs$appendFile) - fs.appendFile = appendFile - function appendFile (path, data, options, cb) { - if (typeof options === 'function') - cb = options, options = null - - return go$appendFile(path, data, options, cb) + }) + }).then(function stat () { + return new Promise(function stat (resolve) { + if (options.mode && options.chown) resolve() + else { + // Either mode or chown is not explicitly set + // Default behavior is to copy it from original file + fs.stat(truename, function (err, stats) { + if (err || !stats) resolve() + else { + options = Object.assign({}, options) - function go$appendFile (path, data, options, cb) { - return fs$appendFile(path, data, options, function (err) { - if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) - enqueue([go$appendFile, [path, data, options, cb]]) - else { - if (typeof cb === 'function') - cb.apply(this, arguments) - retry() - } + if (options.mode == null) { + options.mode = stats.mode + } + if (options.chown == null && process.getuid) { + options.chown = { uid: stats.uid, gid: stats.gid } + } + resolve() + } + }) + } + }) + }).then(function thenWriteFile () { + return new Promise(function (resolve, reject) { + fs.open(tmpfile, 'w', options.mode, function (err, _fd) { + fd = _fd + if (err) reject(err) + else resolve() + }) + }) + }).then(function write () { + return new Promise(function (resolve, reject) { + if (Buffer.isBuffer(data)) { + fs.write(fd, data, 0, data.length, 0, function (err) { + if (err) reject(err) + else resolve() + }) + } else if (data != null) { + fs.write(fd, String(data), 0, String(options.encoding || 'utf8'), function (err) { + if (err) reject(err) + else resolve() + }) + } else resolve() + }) + }).then(function syncAndClose () { + return new Promise(function (resolve, reject) { + if (options.fsync !== false) { + fs.fsync(fd, function (err) { + if (err) fs.close(fd, () => reject(err)) + else fs.close(fd, resolve) + }) + } else { + fs.close(fd, resolve) + } + }) + }).then(function chown () { + fd = null + if (options.chown) { + return new Promise(function (resolve, reject) { + fs.chown(tmpfile, options.chown.uid, options.chown.gid, function (err) { + if (err) reject(err) + else resolve() + }) }) } - } - - var fs$readdir = fs.readdir - fs.readdir = readdir - function readdir (path, options, cb) { - var args = [path] - if (typeof options !== 'function') { - args.push(options) - } else { - cb = options + }).then(function chmod () { + if (options.mode) { + return new Promise(function (resolve, reject) { + fs.chmod(tmpfile, options.mode, function (err) { + if (err) reject(err) + else resolve() + }) + }) } - args.push(go$readdir$cb) - - return go$readdir(args) - - function go$readdir$cb (err, files) { - if (files && files.sort) - files.sort() + }).then(function rename () { + return new Promise(function (resolve, reject) { + fs.rename(tmpfile, truename, function (err) { + if (err) reject(err) + else resolve() + }) + }) + }).then(function success () { + removeOnExitHandler() + callback() + }, function fail (err) { + return new Promise(resolve => { + return fd ? fs.close(fd, resolve) : resolve() + }).then(() => { + removeOnExitHandler() + fs.unlink(tmpfile, function () { + callback(err) + }) + }) + }).then(function checkQueue () { + activeFiles[absoluteName].shift() // remove the element added by serializeSameFile + if (activeFiles[absoluteName].length > 0) { + activeFiles[absoluteName][0]() // start next job if one is pending + } else delete activeFiles[absoluteName] + }) +} - if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) - enqueue([go$readdir, [args]]) +function writeFileSync (filename, data, options) { + if (typeof options === 'string') options = { encoding: options } + else if (!options) options = {} + try { + filename = fs.realpathSync(filename) + } catch (ex) { + // it's ok, it'll happen on a not yet existing file + } + var tmpfile = getTmpname(filename) - else { - if (typeof cb === 'function') - cb.apply(this, arguments) - retry() + if (!options.mode || !options.chown) { + // Either mode or chown is not explicitly set + // Default behavior is to copy it from original file + try { + var stats = fs.statSync(filename) + options = Object.assign({}, options) + if (!options.mode) { + options.mode = stats.mode + } + if (!options.chown && process.getuid) { + options.chown = { uid: stats.uid, gid: stats.gid } } + } catch (ex) { + // ignore stat errors } } - function go$readdir (args) { - return fs$readdir.apply(fs, args) - } + var fd + var cleanup = cleanupOnExit(tmpfile) + var removeOnExitHandler = onExit(cleanup) - if (process.version.substr(0, 4) === 'v0.8') { - var legStreams = legacy(fs) - ReadStream = legStreams.ReadStream - WriteStream = legStreams.WriteStream + try { + fd = fs.openSync(tmpfile, 'w', options.mode) + if (Buffer.isBuffer(data)) { + fs.writeSync(fd, data, 0, data.length, 0) + } else if (data != null) { + fs.writeSync(fd, String(data), 0, String(options.encoding || 'utf8')) + } + if (options.fsync !== false) { + fs.fsyncSync(fd) + } + fs.closeSync(fd) + if (options.chown) fs.chownSync(tmpfile, options.chown.uid, options.chown.gid) + if (options.mode) fs.chmodSync(tmpfile, options.mode) + fs.renameSync(tmpfile, filename) + removeOnExitHandler() + } catch (err) { + if (fd) { + try { + fs.closeSync(fd) + } catch (ex) { + // ignore close errors at this stage, error may have closed fd already. + } + } + removeOnExitHandler() + cleanup() + throw err } +} - var fs$ReadStream = fs.ReadStream - if (fs$ReadStream) { - ReadStream.prototype = Object.create(fs$ReadStream.prototype) - ReadStream.prototype.open = ReadStream$open - } - var fs$WriteStream = fs.WriteStream - if (fs$WriteStream) { - WriteStream.prototype = Object.create(fs$WriteStream.prototype) - WriteStream.prototype.open = WriteStream$open - } +/***/ }), +/* 216 */ +/***/ (function(module, exports, __webpack_require__) { - fs.ReadStream = ReadStream - fs.WriteStream = WriteStream +/** + * @preserve + * JS Implementation of incremental MurmurHash3 (r150) (as of May 10, 2013) + * + * @author Jens Taylor + * @see http://github.com/homebrewing/brauhaus-diff + * @author Gary Court + * @see http://github.com/garycourt/murmurhash-js + * @author Austin Appleby + * @see http://sites.google.com/site/murmurhash/ + */ +(function(){ + var cache; - function ReadStream (path, options) { - if (this instanceof ReadStream) - return fs$ReadStream.apply(this, arguments), this - else - return ReadStream.apply(Object.create(ReadStream.prototype), arguments) - } + // Call this function without `new` to use the cached object (good for + // single-threaded environments), or with `new` to create a new object. + // + // @param {string} key A UTF-16 or ASCII string + // @param {number} seed An optional positive integer + // @return {object} A MurmurHash3 object for incremental hashing + function MurmurHash3(key, seed) { + var m = this instanceof MurmurHash3 ? this : cache; + m.reset(seed) + if (typeof key === 'string' && key.length > 0) { + m.hash(key); + } - function ReadStream$open () { - var that = this - open(that.path, that.flags, that.mode, function (err, fd) { - if (err) { - if (that.autoClose) - that.destroy() + if (m !== this) { + return m; + } + }; - that.emit('error', err) - } else { - that.fd = fd - that.emit('open', fd) - that.read() - } - }) - } + // Incrementally add a string to this hash + // + // @param {string} key A UTF-16 or ASCII string + // @return {object} this + MurmurHash3.prototype.hash = function(key) { + var h1, k1, i, top, len; - function WriteStream (path, options) { - if (this instanceof WriteStream) - return fs$WriteStream.apply(this, arguments), this - else - return WriteStream.apply(Object.create(WriteStream.prototype), arguments) - } + len = key.length; + this.len += len; - function WriteStream$open () { - var that = this - open(that.path, that.flags, that.mode, function (err, fd) { - if (err) { - that.destroy() - that.emit('error', err) - } else { - that.fd = fd - that.emit('open', fd) - } - }) - } + k1 = this.k1; + i = 0; + switch (this.rem) { + case 0: k1 ^= len > i ? (key.charCodeAt(i++) & 0xffff) : 0; + case 1: k1 ^= len > i ? (key.charCodeAt(i++) & 0xffff) << 8 : 0; + case 2: k1 ^= len > i ? (key.charCodeAt(i++) & 0xffff) << 16 : 0; + case 3: + k1 ^= len > i ? (key.charCodeAt(i) & 0xff) << 24 : 0; + k1 ^= len > i ? (key.charCodeAt(i++) & 0xff00) >> 8 : 0; + } - function createReadStream (path, options) { - return new ReadStream(path, options) - } + this.rem = (len + this.rem) & 3; // & 3 is same as % 4 + len -= this.rem; + if (len > 0) { + h1 = this.h1; + while (1) { + k1 = (k1 * 0x2d51 + (k1 & 0xffff) * 0xcc9e0000) & 0xffffffff; + k1 = (k1 << 15) | (k1 >>> 17); + k1 = (k1 * 0x3593 + (k1 & 0xffff) * 0x1b870000) & 0xffffffff; - function createWriteStream (path, options) { - return new WriteStream(path, options) - } + h1 ^= k1; + h1 = (h1 << 13) | (h1 >>> 19); + h1 = (h1 * 5 + 0xe6546b64) & 0xffffffff; - var fs$open = fs.open - fs.open = open - function open (path, flags, mode, cb) { - if (typeof mode === 'function') - cb = mode, mode = null + if (i >= len) { + break; + } - return go$open(path, flags, mode, cb) + k1 = ((key.charCodeAt(i++) & 0xffff)) ^ + ((key.charCodeAt(i++) & 0xffff) << 8) ^ + ((key.charCodeAt(i++) & 0xffff) << 16); + top = key.charCodeAt(i++); + k1 ^= ((top & 0xff) << 24) ^ + ((top & 0xff00) >> 8); + } - function go$open (path, flags, mode, cb) { - return fs$open(path, flags, mode, function (err, fd) { - if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) - enqueue([go$open, [path, flags, mode, cb]]) - else { - if (typeof cb === 'function') - cb.apply(this, arguments) - retry() + k1 = 0; + switch (this.rem) { + case 3: k1 ^= (key.charCodeAt(i + 2) & 0xffff) << 16; + case 2: k1 ^= (key.charCodeAt(i + 1) & 0xffff) << 8; + case 1: k1 ^= (key.charCodeAt(i) & 0xffff); + } + + this.h1 = h1; } - }) - } - } - return fs -} + this.k1 = k1; + return this; + }; -function enqueue (elem) { - debug('ENQUEUE', elem[0].name, elem[1]) - queue.push(elem) -} + // Get the result of this hash + // + // @return {number} The 32-bit hash + MurmurHash3.prototype.result = function() { + var k1, h1; + + k1 = this.k1; + h1 = this.h1; -function retry () { - var elem = queue.shift() - if (elem) { - debug('RETRY', elem[0].name, elem[1]) - elem[0].apply(null, elem[1]) - } -} + if (k1 > 0) { + k1 = (k1 * 0x2d51 + (k1 & 0xffff) * 0xcc9e0000) & 0xffffffff; + k1 = (k1 << 15) | (k1 >>> 17); + k1 = (k1 * 0x3593 + (k1 & 0xffff) * 0x1b870000) & 0xffffffff; + h1 ^= k1; + } + h1 ^= this.len; -/***/ }), -/* 216 */ -/***/ (function(module, exports, __webpack_require__) { - -var constants = __webpack_require__(135) - -var origCwd = process.cwd -var cwd = null - -var platform = process.env.GRACEFUL_FS_PLATFORM || process.platform - -process.cwd = function() { - if (!cwd) - cwd = origCwd.call(process) - return cwd -} -try { - process.cwd() -} catch (er) {} + h1 ^= h1 >>> 16; + h1 = (h1 * 0xca6b + (h1 & 0xffff) * 0x85eb0000) & 0xffffffff; + h1 ^= h1 >>> 13; + h1 = (h1 * 0xae35 + (h1 & 0xffff) * 0xc2b20000) & 0xffffffff; + h1 ^= h1 >>> 16; -var chdir = process.chdir -process.chdir = function(d) { - cwd = null - chdir.call(process, d) -} + return h1 >>> 0; + }; -module.exports = patch + // Reset the hash object for reuse + // + // @param {number} seed An optional positive integer + MurmurHash3.prototype.reset = function(seed) { + this.h1 = typeof seed === 'number' ? seed : 0; + this.rem = this.k1 = this.len = 0; + return this; + }; -function patch (fs) { - // (re-)implement some things that are known busted or missing. + // A cached object to use. This can be safely used if you're in a single- + // threaded environment, otherwise you need to create new hashes to use. + cache = new MurmurHash3(); - // lchmod, broken prior to 0.6.2 - // back-port the fix here. - if (constants.hasOwnProperty('O_SYMLINK') && - process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)) { - patchLchmod(fs) - } + if (true) { + module.exports = MurmurHash3; + } else {} +}()); - // lutimes implementation, or no-op - if (!fs.lutimes) { - patchLutimes(fs) - } - // https://github.com/isaacs/node-graceful-fs/issues/4 - // Chown should not fail on einval or eperm if non-root. - // It should not fail on enosys ever, as this just indicates - // that a fs doesn't support the intended operation. +/***/ }), +/* 217 */ +/***/ (function(module, exports, __webpack_require__) { - fs.chown = chownFix(fs.chown) - fs.fchown = chownFix(fs.fchown) - fs.lchown = chownFix(fs.lchown) +// Note: since nyc uses this module to output coverage, any lines +// that are in the direct sync flow of nyc's outputCoverage are +// ignored, since we can never get coverage for them. +var assert = __webpack_require__(139) +var signals = __webpack_require__(218) - fs.chmod = chmodFix(fs.chmod) - fs.fchmod = chmodFix(fs.fchmod) - fs.lchmod = chmodFix(fs.lchmod) +var EE = __webpack_require__(155) +/* istanbul ignore if */ +if (typeof EE !== 'function') { + EE = EE.EventEmitter +} - fs.chownSync = chownFixSync(fs.chownSync) - fs.fchownSync = chownFixSync(fs.fchownSync) - fs.lchownSync = chownFixSync(fs.lchownSync) +var emitter +if (process.__signal_exit_emitter__) { + emitter = process.__signal_exit_emitter__ +} else { + emitter = process.__signal_exit_emitter__ = new EE() + emitter.count = 0 + emitter.emitted = {} +} - fs.chmodSync = chmodFixSync(fs.chmodSync) - fs.fchmodSync = chmodFixSync(fs.fchmodSync) - fs.lchmodSync = chmodFixSync(fs.lchmodSync) +// Because this emitter is a global, we have to check to see if a +// previous version of this library failed to enable infinite listeners. +// I know what you're about to say. But literally everything about +// signal-exit is a compromise with evil. Get used to it. +if (!emitter.infinite) { + emitter.setMaxListeners(Infinity) + emitter.infinite = true +} - fs.stat = statFix(fs.stat) - fs.fstat = statFix(fs.fstat) - fs.lstat = statFix(fs.lstat) +module.exports = function (cb, opts) { + assert.equal(typeof cb, 'function', 'a callback must be provided for exit handler') - fs.statSync = statFixSync(fs.statSync) - fs.fstatSync = statFixSync(fs.fstatSync) - fs.lstatSync = statFixSync(fs.lstatSync) + if (loaded === false) { + load() + } - // if lchmod/lchown do not exist, then make them no-ops - if (!fs.lchmod) { - fs.lchmod = function (path, mode, cb) { - if (cb) process.nextTick(cb) - } - fs.lchmodSync = function () {} + var ev = 'exit' + if (opts && opts.alwaysLast) { + ev = 'afterexit' } - if (!fs.lchown) { - fs.lchown = function (path, uid, gid, cb) { - if (cb) process.nextTick(cb) + + var remove = function () { + emitter.removeListener(ev, cb) + if (emitter.listeners('exit').length === 0 && + emitter.listeners('afterexit').length === 0) { + unload() } - fs.lchownSync = function () {} } + emitter.on(ev, cb) - // on Windows, A/V software can lock the directory, causing this - // to fail with an EACCES or EPERM if the directory contains newly - // created files. Try again on failure, for up to 60 seconds. + return remove +} - // Set the timeout this long because some Windows Anti-Virus, such as Parity - // bit9, may lock files for up to a minute, causing npm package install - // failures. Also, take care to yield the scheduler. Windows scheduling gives - // CPU to a busy looping process, which can cause the program causing the lock - // contention to be starved of CPU by node, so the contention doesn't resolve. - if (platform === "win32") { - fs.rename = (function (fs$rename) { return function (from, to, cb) { - var start = Date.now() - var backoff = 0; - fs$rename(from, to, function CB (er) { - if (er - && (er.code === "EACCES" || er.code === "EPERM") - && Date.now() - start < 60000) { - setTimeout(function() { - fs.stat(to, function (stater, st) { - if (stater && stater.code === "ENOENT") - fs$rename(from, to, CB); - else - cb(er) - }) - }, backoff) - if (backoff < 100) - backoff += 10; - return; - } - if (cb) cb(er) - }) - }})(fs.rename) +module.exports.unload = unload +function unload () { + if (!loaded) { + return } + loaded = false - // if read() returns EAGAIN, then just try it again. - fs.read = (function (fs$read) { return function (fd, buffer, offset, length, position, callback_) { - var callback - if (callback_ && typeof callback_ === 'function') { - var eagCounter = 0 - callback = function (er, _, __) { - if (er && er.code === 'EAGAIN' && eagCounter < 10) { - eagCounter ++ - return fs$read.call(fs, fd, buffer, offset, length, position, callback) - } - callback_.apply(this, arguments) - } - } - return fs$read.call(fs, fd, buffer, offset, length, position, callback) - }})(fs.read) - - fs.readSync = (function (fs$readSync) { return function (fd, buffer, offset, length, position) { - var eagCounter = 0 - while (true) { - try { - return fs$readSync.call(fs, fd, buffer, offset, length, position) - } catch (er) { - if (er.code === 'EAGAIN' && eagCounter < 10) { - eagCounter ++ - continue - } - throw er - } - } - }})(fs.readSync) - - function patchLchmod (fs) { - fs.lchmod = function (path, mode, callback) { - fs.open( path - , constants.O_WRONLY | constants.O_SYMLINK - , mode - , function (err, fd) { - if (err) { - if (callback) callback(err) - return - } - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - fs.fchmod(fd, mode, function (err) { - fs.close(fd, function(err2) { - if (callback) callback(err || err2) - }) - }) - }) - } + signals.forEach(function (sig) { + try { + process.removeListener(sig, sigListeners[sig]) + } catch (er) {} + }) + process.emit = originalProcessEmit + process.reallyExit = originalProcessReallyExit + emitter.count -= 1 +} - fs.lchmodSync = function (path, mode) { - var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK, mode) +function emit (event, code, signal) { + if (emitter.emitted[event]) { + return + } + emitter.emitted[event] = true + emitter.emit(event, code, signal) +} - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - var threw = true - var ret - try { - ret = fs.fchmodSync(fd, mode) - threw = false - } finally { - if (threw) { - try { - fs.closeSync(fd) - } catch (er) {} - } else { - fs.closeSync(fd) - } - } - return ret +// { : , ... } +var sigListeners = {} +signals.forEach(function (sig) { + sigListeners[sig] = function listener () { + // If there are no other listeners, an exit is coming! + // Simplest way: remove us and then re-send the signal. + // We know that this will kill the process, so we can + // safely emit now. + var listeners = process.listeners(sig) + if (listeners.length === emitter.count) { + unload() + emit('exit', null, sig) + /* istanbul ignore next */ + emit('afterexit', null, sig) + /* istanbul ignore next */ + process.kill(process.pid, sig) } } +}) - function patchLutimes (fs) { - if (constants.hasOwnProperty("O_SYMLINK")) { - fs.lutimes = function (path, at, mt, cb) { - fs.open(path, constants.O_SYMLINK, function (er, fd) { - if (er) { - if (cb) cb(er) - return - } - fs.futimes(fd, at, mt, function (er) { - fs.close(fd, function (er2) { - if (cb) cb(er || er2) - }) - }) - }) - } - - fs.lutimesSync = function (path, at, mt) { - var fd = fs.openSync(path, constants.O_SYMLINK) - var ret - var threw = true - try { - ret = fs.futimesSync(fd, at, mt) - threw = false - } finally { - if (threw) { - try { - fs.closeSync(fd) - } catch (er) {} - } else { - fs.closeSync(fd) - } - } - return ret - } +module.exports.signals = function () { + return signals +} - } else { - fs.lutimes = function (_a, _b, _c, cb) { if (cb) process.nextTick(cb) } - fs.lutimesSync = function () {} - } - } +module.exports.load = load - function chmodFix (orig) { - if (!orig) return orig - return function (target, mode, cb) { - return orig.call(fs, target, mode, function (er) { - if (chownErOk(er)) er = null - if (cb) cb.apply(this, arguments) - }) - } - } +var loaded = false - function chmodFixSync (orig) { - if (!orig) return orig - return function (target, mode) { - try { - return orig.call(fs, target, mode) - } catch (er) { - if (!chownErOk(er)) throw er - } - } +function load () { + if (loaded) { + return } + loaded = true + // This is the number of onSignalExit's that are in play. + // It's important so that we can count the correct number of + // listeners on signals, and don't wait for the other one to + // handle it instead of us. + emitter.count += 1 - function chownFix (orig) { - if (!orig) return orig - return function (target, uid, gid, cb) { - return orig.call(fs, target, uid, gid, function (er) { - if (chownErOk(er)) er = null - if (cb) cb.apply(this, arguments) - }) + signals = signals.filter(function (sig) { + try { + process.on(sig, sigListeners[sig]) + return true + } catch (er) { + return false } - } + }) - function chownFixSync (orig) { - if (!orig) return orig - return function (target, uid, gid) { - try { - return orig.call(fs, target, uid, gid) - } catch (er) { - if (!chownErOk(er)) throw er - } - } - } + process.emit = processEmit + process.reallyExit = processReallyExit +} +var originalProcessReallyExit = process.reallyExit +function processReallyExit (code) { + process.exitCode = code || 0 + emit('exit', process.exitCode, null) + /* istanbul ignore next */ + emit('afterexit', process.exitCode, null) + /* istanbul ignore next */ + originalProcessReallyExit.call(process, process.exitCode) +} - function statFix (orig) { - if (!orig) return orig - // Older versions of Node erroneously returned signed integers for - // uid + gid. - return function (target, cb) { - return orig.call(fs, target, function (er, stats) { - if (!stats) return cb.apply(this, arguments) - if (stats.uid < 0) stats.uid += 0x100000000 - if (stats.gid < 0) stats.gid += 0x100000000 - if (cb) cb.apply(this, arguments) - }) +var originalProcessEmit = process.emit +function processEmit (ev, arg) { + if (ev === 'exit') { + if (arg !== undefined) { + process.exitCode = arg } + var ret = originalProcessEmit.apply(this, arguments) + emit('exit', process.exitCode, null) + /* istanbul ignore next */ + emit('afterexit', process.exitCode, null) + return ret + } else { + return originalProcessEmit.apply(this, arguments) } +} - function statFixSync (orig) { - if (!orig) return orig - // Older versions of Node erroneously returned signed integers for - // uid + gid. - return function (target) { - var stats = orig.call(fs, target) - if (stats.uid < 0) stats.uid += 0x100000000 - if (stats.gid < 0) stats.gid += 0x100000000 - return stats; - } - } - // ENOSYS means that the fs doesn't support the op. Just ignore - // that, because it doesn't matter. - // - // if there's no getuid, or if getuid() is something other - // than 0, and the error is EINVAL or EPERM, then just ignore - // it. - // - // This specific case is a silent failure in cp, install, tar, - // and most other unix tools that manage permissions. - // - // When running as root, or if other types of errors are - // encountered, then it's strict. - function chownErOk (er) { - if (!er) - return true +/***/ }), +/* 218 */ +/***/ (function(module, exports) { - if (er.code === "ENOSYS") - return true +// This is not the set of all possible signals. +// +// It IS, however, the set of all signals that trigger +// an exit on either Linux or BSD systems. Linux is a +// superset of the signal names supported on BSD, and +// the unknown signals just fail to register, so we can +// catch that easily enough. +// +// Don't bother with SIGKILL. It's uncatchable, which +// means that we can't fire any callbacks anyway. +// +// If a user does happen to register a handler on a non- +// fatal signal like SIGWINCH or something, and then +// exit, it'll end up firing `process.emit('exit')`, so +// the handler will be fired anyway. +// +// SIGBUS, SIGFPE, SIGSEGV and SIGILL, when not raised +// artificially, inherently leave the process in a +// state from which it is not safe to try and enter JS +// listeners. +module.exports = [ + 'SIGABRT', + 'SIGALRM', + 'SIGHUP', + 'SIGINT', + 'SIGTERM' +] - var nonroot = !process.getuid || process.getuid() !== 0 - if (nonroot) { - if (er.code === "EINVAL" || er.code === "EPERM") - return true - } +if (process.platform !== 'win32') { + module.exports.push( + 'SIGVTALRM', + 'SIGXCPU', + 'SIGXFSZ', + 'SIGUSR2', + 'SIGTRAP', + 'SIGSYS', + 'SIGQUIT', + 'SIGIOT' + // should detect profiler and enable/disable accordingly. + // see #21 + // 'SIGPROF' + ) +} - return false - } +if (process.platform === 'linux') { + module.exports.push( + 'SIGIO', + 'SIGPOLL', + 'SIGPWR', + 'SIGSTKFLT', + 'SIGUNUSED' + ) } /***/ }), -/* 217 */ -/***/ (function(module, exports, __webpack_require__) { - -var Stream = __webpack_require__(137).Stream +/* 219 */ +/***/ (function(module, exports) { -module.exports = legacy +module.exports = require(undefined); -function legacy (fs) { - return { - ReadStream: ReadStream, - WriteStream: WriteStream - } +/***/ }), +/* 220 */ +/***/ (function(module, exports, __webpack_require__) { - function ReadStream (path, options) { - if (!(this instanceof ReadStream)) return new ReadStream(path, options); +"use strict"; - Stream.call(this); +const isPlainObj = __webpack_require__(221); - var self = this; +module.exports = (obj, opts) => { + if (!isPlainObj(obj)) { + throw new TypeError('Expected a plain object'); + } - this.path = path; - this.fd = null; - this.readable = true; - this.paused = false; + opts = opts || {}; - this.flags = 'r'; - this.mode = 438; /*=0666*/ - this.bufferSize = 64 * 1024; + // DEPRECATED + if (typeof opts === 'function') { + throw new TypeError('Specify the compare function as an option instead'); + } - options = options || {}; - - // Mixin options into this - var keys = Object.keys(options); - for (var index = 0, length = keys.length; index < length; index++) { - var key = keys[index]; - this[key] = options[key]; - } - - if (this.encoding) this.setEncoding(this.encoding); + const deep = opts.deep; + const seenInput = []; + const seenOutput = []; - if (this.start !== undefined) { - if ('number' !== typeof this.start) { - throw TypeError('start must be a Number'); - } - if (this.end === undefined) { - this.end = Infinity; - } else if ('number' !== typeof this.end) { - throw TypeError('end must be a Number'); - } + const sortKeys = x => { + const seenIndex = seenInput.indexOf(x); - if (this.start > this.end) { - throw new Error('start must be <= end'); - } + if (seenIndex !== -1) { + return seenOutput[seenIndex]; + } - this.pos = this.start; - } + const ret = {}; + const keys = Object.keys(x).sort(opts.compare); - if (this.fd !== null) { - process.nextTick(function() { - self._read(); - }); - return; - } + seenInput.push(x); + seenOutput.push(ret); - fs.open(this.path, this.flags, this.mode, function (err, fd) { - if (err) { - self.emit('error', err); - self.readable = false; - return; - } + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + const val = x[key]; - self.fd = fd; - self.emit('open', fd); - self._read(); - }) - } + if (deep && Array.isArray(val)) { + const retArr = []; - function WriteStream (path, options) { - if (!(this instanceof WriteStream)) return new WriteStream(path, options); + for (let j = 0; j < val.length; j++) { + retArr[j] = isPlainObj(val[j]) ? sortKeys(val[j]) : val[j]; + } - Stream.call(this); + ret[key] = retArr; + continue; + } - this.path = path; - this.fd = null; - this.writable = true; + ret[key] = deep && isPlainObj(val) ? sortKeys(val) : val; + } - this.flags = 'w'; - this.encoding = 'binary'; - this.mode = 438; /*=0666*/ - this.bytesWritten = 0; + return ret; + }; - options = options || {}; + return sortKeys(obj); +}; - // Mixin options into this - var keys = Object.keys(options); - for (var index = 0, length = keys.length; index < length; index++) { - var key = keys[index]; - this[key] = options[key]; - } - if (this.start !== undefined) { - if ('number' !== typeof this.start) { - throw TypeError('start must be a Number'); - } - if (this.start < 0) { - throw new Error('start must be >= zero'); - } +/***/ }), +/* 221 */ +/***/ (function(module, exports, __webpack_require__) { - this.pos = this.start; - } +"use strict"; - this.busy = false; - this._queue = []; +var toString = Object.prototype.toString; - if (this.fd === null) { - this._open = fs.open; - this._queue.push([this._open, this.path, this.flags, this.mode, undefined]); - this.flush(); - } - } -} +module.exports = function (x) { + var prototype; + return toString.call(x) === '[object Object]' && (prototype = Object.getPrototypeOf(x), prototype === null || prototype === Object.getPrototypeOf({})); +}; /***/ }), -/* 218 */ +/* 222 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +const fs = __webpack_require__(133); +const path = __webpack_require__(4); +const pify = __webpack_require__(223); +const semver = __webpack_require__(189); -module.exports = clone - -function clone (obj) { - if (obj === null || typeof obj !== 'object') - return obj - - if (obj instanceof Object) - var copy = { __proto__: obj.__proto__ } - else - var copy = Object.create(null) - - Object.getOwnPropertyNames(obj).forEach(function (key) { - Object.defineProperty(copy, key, Object.getOwnPropertyDescriptor(obj, key)) - }) - - return copy -} +const defaults = { + mode: 0o777 & (~process.umask()), + fs +}; +const useNativeRecursiveOption = semver.satisfies(process.version, '>=10.12.0'); -/***/ }), -/* 219 */ -/***/ (function(module, exports, __webpack_require__) { +// https://github.com/nodejs/node/issues/8987 +// https://github.com/libuv/libuv/pull/1088 +const checkPath = pth => { + if (process.platform === 'win32') { + const pathHasInvalidWinCharacters = /[<>:"|?*]/.test(pth.replace(path.parse(pth).root, '')); -"use strict"; + if (pathHasInvalidWinCharacters) { + const error = new Error(`Path contains invalid characters: ${pth}`); + error.code = 'EINVAL'; + throw error; + } + } +}; -module.exports = writeFile -module.exports.sync = writeFileSync -module.exports._getTmpname = getTmpname // for testing -module.exports._cleanupOnExit = cleanupOnExit +const permissionError = pth => { + // This replicates the exception of `fs.mkdir` with native the + // `recusive` option when run on an invalid drive under Windows. + const error = new Error(`operation not permitted, mkdir '${pth}'`); + error.code = 'EPERM'; + error.errno = -4048; + error.path = pth; + error.syscall = 'mkdir'; + return error; +}; -var fs = __webpack_require__(220) -var MurmurHash3 = __webpack_require__(224) -var onExit = __webpack_require__(225) -var path = __webpack_require__(4) -var activeFiles = {} +const makeDir = (input, options) => Promise.resolve().then(() => { + checkPath(input); + options = Object.assign({}, defaults, options); -// if we run inside of a worker_thread, `process.pid` is not unique -/* istanbul ignore next */ -var threadId = (function getId () { - try { - var workerThreads = __webpack_require__(227) + // TODO: Use util.promisify when targeting Node.js 8 + const mkdir = pify(options.fs.mkdir); + const stat = pify(options.fs.stat); - /// if we are in main thread, this is set to `0` - return workerThreads.threadId - } catch (e) { - // worker_threads are not available, fallback to 0 - return 0 - } -})() + if (useNativeRecursiveOption && options.fs.mkdir === fs.mkdir) { + const pth = path.resolve(input); -var invocations = 0 -function getTmpname (filename) { - return filename + '.' + - MurmurHash3(__filename) - .hash(String(process.pid)) - .hash(String(threadId)) - .hash(String(++invocations)) - .result() -} + return mkdir(pth, { + mode: options.mode, + recursive: true + }).then(() => pth); + } -function cleanupOnExit (tmpfile) { - return function () { - try { - fs.unlinkSync(typeof tmpfile === 'function' ? tmpfile() : tmpfile) - } catch (_) {} - } -} + const make = pth => { + return mkdir(pth, options.mode) + .then(() => pth) + .catch(error => { + if (error.code === 'EPERM') { + throw error; + } -function writeFile (filename, data, options, callback) { - if (options) { - if (options instanceof Function) { - callback = options - options = {} - } else if (typeof options === 'string') { - options = { encoding: options } - } - } else { - options = {} - } + if (error.code === 'ENOENT') { + if (path.dirname(pth) === pth) { + throw permissionError(pth); + } - var Promise = options.Promise || global.Promise - var truename - var fd - var tmpfile - /* istanbul ignore next -- The closure only gets called when onExit triggers */ - var removeOnExitHandler = onExit(cleanupOnExit(() => tmpfile)) - var absoluteName = path.resolve(filename) + if (error.message.includes('null bytes')) { + throw error; + } - new Promise(function serializeSameFile (resolve) { - // make a queue if it doesn't already exist - if (!activeFiles[absoluteName]) activeFiles[absoluteName] = [] + return make(path.dirname(pth)).then(() => make(pth)); + } - activeFiles[absoluteName].push(resolve) // add this job to the queue - if (activeFiles[absoluteName].length === 1) resolve() // kick off the first one - }).then(function getRealPath () { - return new Promise(function (resolve) { - fs.realpath(filename, function (_, realname) { - truename = realname || filename - tmpfile = getTmpname(truename) - resolve() - }) - }) - }).then(function stat () { - return new Promise(function stat (resolve) { - if (options.mode && options.chown) resolve() - else { - // Either mode or chown is not explicitly set - // Default behavior is to copy it from original file - fs.stat(truename, function (err, stats) { - if (err || !stats) resolve() - else { - options = Object.assign({}, options) + return stat(pth) + .then(stats => stats.isDirectory() ? pth : Promise.reject()) + .catch(() => { + throw error; + }); + }); + }; - if (options.mode == null) { - options.mode = stats.mode - } - if (options.chown == null && process.getuid) { - options.chown = { uid: stats.uid, gid: stats.gid } - } - resolve() - } - }) - } - }) - }).then(function thenWriteFile () { - return new Promise(function (resolve, reject) { - fs.open(tmpfile, 'w', options.mode, function (err, _fd) { - fd = _fd - if (err) reject(err) - else resolve() - }) - }) - }).then(function write () { - return new Promise(function (resolve, reject) { - if (Buffer.isBuffer(data)) { - fs.write(fd, data, 0, data.length, 0, function (err) { - if (err) reject(err) - else resolve() - }) - } else if (data != null) { - fs.write(fd, String(data), 0, String(options.encoding || 'utf8'), function (err) { - if (err) reject(err) - else resolve() - }) - } else resolve() - }) - }).then(function syncAndClose () { - return new Promise(function (resolve, reject) { - if (options.fsync !== false) { - fs.fsync(fd, function (err) { - if (err) fs.close(fd, () => reject(err)) - else fs.close(fd, resolve) - }) - } else { - fs.close(fd, resolve) - } - }) - }).then(function chown () { - fd = null - if (options.chown) { - return new Promise(function (resolve, reject) { - fs.chown(tmpfile, options.chown.uid, options.chown.gid, function (err) { - if (err) reject(err) - else resolve() - }) - }) - } - }).then(function chmod () { - if (options.mode) { - return new Promise(function (resolve, reject) { - fs.chmod(tmpfile, options.mode, function (err) { - if (err) reject(err) - else resolve() - }) - }) - } - }).then(function rename () { - return new Promise(function (resolve, reject) { - fs.rename(tmpfile, truename, function (err) { - if (err) reject(err) - else resolve() - }) - }) - }).then(function success () { - removeOnExitHandler() - callback() - }, function fail (err) { - return new Promise(resolve => { - return fd ? fs.close(fd, resolve) : resolve() - }).then(() => { - removeOnExitHandler() - fs.unlink(tmpfile, function () { - callback(err) - }) - }) - }).then(function checkQueue () { - activeFiles[absoluteName].shift() // remove the element added by serializeSameFile - if (activeFiles[absoluteName].length > 0) { - activeFiles[absoluteName][0]() // start next job if one is pending - } else delete activeFiles[absoluteName] - }) -} + return make(path.resolve(input)); +}); -function writeFileSync (filename, data, options) { - if (typeof options === 'string') options = { encoding: options } - else if (!options) options = {} - try { - filename = fs.realpathSync(filename) - } catch (ex) { - // it's ok, it'll happen on a not yet existing file - } - var tmpfile = getTmpname(filename) +module.exports = makeDir; +module.exports.default = makeDir; - if (!options.mode || !options.chown) { - // Either mode or chown is not explicitly set - // Default behavior is to copy it from original file - try { - var stats = fs.statSync(filename) - options = Object.assign({}, options) - if (!options.mode) { - options.mode = stats.mode - } - if (!options.chown && process.getuid) { - options.chown = { uid: stats.uid, gid: stats.gid } - } - } catch (ex) { - // ignore stat errors - } - } +module.exports.sync = (input, options) => { + checkPath(input); + options = Object.assign({}, defaults, options); - var fd - var cleanup = cleanupOnExit(tmpfile) - var removeOnExitHandler = onExit(cleanup) + if (useNativeRecursiveOption && options.fs.mkdirSync === fs.mkdirSync) { + const pth = path.resolve(input); - try { - fd = fs.openSync(tmpfile, 'w', options.mode) - if (Buffer.isBuffer(data)) { - fs.writeSync(fd, data, 0, data.length, 0) - } else if (data != null) { - fs.writeSync(fd, String(data), 0, String(options.encoding || 'utf8')) - } - if (options.fsync !== false) { - fs.fsyncSync(fd) - } - fs.closeSync(fd) - if (options.chown) fs.chownSync(tmpfile, options.chown.uid, options.chown.gid) - if (options.mode) fs.chmodSync(tmpfile, options.mode) - fs.renameSync(tmpfile, filename) - removeOnExitHandler() - } catch (err) { - if (fd) { - try { - fs.closeSync(fd) - } catch (ex) { - // ignore close errors at this stage, error may have closed fd already. - } - } - removeOnExitHandler() - cleanup() - throw err - } -} + fs.mkdirSync(pth, { + mode: options.mode, + recursive: true + }); + return pth; + } -/***/ }), -/* 220 */ -/***/ (function(module, exports, __webpack_require__) { + const make = pth => { + try { + options.fs.mkdirSync(pth, options.mode); + } catch (error) { + if (error.code === 'EPERM') { + throw error; + } -var fs = __webpack_require__(133) -var polyfills = __webpack_require__(221) -var legacy = __webpack_require__(223) -var queue = [] + if (error.code === 'ENOENT') { + if (path.dirname(pth) === pth) { + throw permissionError(pth); + } -var util = __webpack_require__(111) + if (error.message.includes('null bytes')) { + throw error; + } -function noop () {} + make(path.dirname(pth)); + return make(pth); + } -var debug = noop -if (util.debuglog) - debug = util.debuglog('gfs4') -else if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) - debug = function() { - var m = util.format.apply(util, arguments) - m = 'GFS4: ' + m.split(/\n/).join('\nGFS4: ') - console.error(m) - } + try { + if (!options.fs.statSync(pth).isDirectory()) { + throw new Error('The path is not a directory'); + } + } catch (_) { + throw error; + } + } -if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) { - process.on('exit', function() { - debug(queue) - __webpack_require__(139).equal(queue.length, 0) - }) -} + return pth; + }; -module.exports = patch(__webpack_require__(222)) -if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH) { - module.exports = patch(fs) -} + return make(path.resolve(input)); +}; -// Always patch fs.close/closeSync, because we want to -// retry() whenever a close happens *anywhere* in the program. -// This is essential when multiple graceful-fs instances are -// in play at the same time. -module.exports.close = -fs.close = (function (fs$close) { return function (fd, cb) { - return fs$close.call(fs, fd, function (err) { - if (!err) - retry() - if (typeof cb === 'function') - cb.apply(this, arguments) - }) -}})(fs.close) +/***/ }), +/* 223 */ +/***/ (function(module, exports, __webpack_require__) { -module.exports.closeSync = -fs.closeSync = (function (fs$closeSync) { return function (fd) { - // Note that graceful-fs also retries when fs.closeSync() fails. - // Looks like a bug to me, although it's probably a harmless one. - var rval = fs$closeSync.apply(fs, arguments) - retry() - return rval -}})(fs.closeSync) +"use strict"; -function patch (fs) { - // Everything that references the open() function needs to be in here - polyfills(fs) - fs.gracefulify = patch - fs.FileReadStream = ReadStream; // Legacy name. - fs.FileWriteStream = WriteStream; // Legacy name. - fs.createReadStream = createReadStream - fs.createWriteStream = createWriteStream - var fs$readFile = fs.readFile - fs.readFile = readFile - function readFile (path, options, cb) { - if (typeof options === 'function') - cb = options, options = null - return go$readFile(path, options, cb) +const processFn = (fn, options) => function (...args) { + const P = options.promiseModule; - function go$readFile (path, options, cb) { - return fs$readFile(path, options, function (err) { - if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) - enqueue([go$readFile, [path, options, cb]]) - else { - if (typeof cb === 'function') - cb.apply(this, arguments) - retry() - } - }) - } - } + return new P((resolve, reject) => { + if (options.multiArgs) { + args.push((...result) => { + if (options.errorFirst) { + if (result[0]) { + reject(result); + } else { + result.shift(); + resolve(result); + } + } else { + resolve(result); + } + }); + } else if (options.errorFirst) { + args.push((error, result) => { + if (error) { + reject(error); + } else { + resolve(result); + } + }); + } else { + args.push(resolve); + } - var fs$writeFile = fs.writeFile - fs.writeFile = writeFile - function writeFile (path, data, options, cb) { - if (typeof options === 'function') - cb = options, options = null + fn.apply(this, args); + }); +}; - return go$writeFile(path, data, options, cb) +module.exports = (input, options) => { + options = Object.assign({ + exclude: [/.+(Sync|Stream)$/], + errorFirst: true, + promiseModule: Promise + }, options); - function go$writeFile (path, data, options, cb) { - return fs$writeFile(path, data, options, function (err) { - if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) - enqueue([go$writeFile, [path, data, options, cb]]) - else { - if (typeof cb === 'function') - cb.apply(this, arguments) - retry() - } - }) - } - } + const objType = typeof input; + if (!(input !== null && (objType === 'object' || objType === 'function'))) { + throw new TypeError(`Expected \`input\` to be a \`Function\` or \`Object\`, got \`${input === null ? 'null' : objType}\``); + } - var fs$appendFile = fs.appendFile - if (fs$appendFile) - fs.appendFile = appendFile - function appendFile (path, data, options, cb) { - if (typeof options === 'function') - cb = options, options = null + const filter = key => { + const match = pattern => typeof pattern === 'string' ? key === pattern : pattern.test(key); + return options.include ? options.include.some(match) : !options.exclude.some(match); + }; - return go$appendFile(path, data, options, cb) + let ret; + if (objType === 'function') { + ret = function (...args) { + return options.excludeMain ? input(...args) : processFn(input, options).apply(this, args); + }; + } else { + ret = Object.create(Object.getPrototypeOf(input)); + } - function go$appendFile (path, data, options, cb) { - return fs$appendFile(path, data, options, function (err) { - if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) - enqueue([go$appendFile, [path, data, options, cb]]) - else { - if (typeof cb === 'function') - cb.apply(this, arguments) - retry() - } - }) - } - } + for (const key in input) { // eslint-disable-line guard-for-in + const property = input[key]; + ret[key] = typeof property === 'function' && filter(key) ? processFn(property, options) : property; + } - var fs$readdir = fs.readdir - fs.readdir = readdir - function readdir (path, options, cb) { - var args = [path] - if (typeof options !== 'function') { - args.push(options) - } else { - cb = options - } - args.push(go$readdir$cb) + return ret; +}; - return go$readdir(args) - function go$readdir$cb (err, files) { - if (files && files.sort) - files.sort() +/***/ }), +/* 224 */ +/***/ (function(module, exports, __webpack_require__) { - if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) - enqueue([go$readdir, [args]]) - else { - if (typeof cb === 'function') - cb.apply(this, arguments) - retry() - } - } - } +"use strict"; - function go$readdir (args) { - return fs$readdir.apply(fs, args) - } - if (process.version.substr(0, 4) === 'v0.8') { - var legStreams = legacy(fs) - ReadStream = legStreams.ReadStream - WriteStream = legStreams.WriteStream - } +// detect either spaces or tabs but not both to properly handle tabs +// for indentation and spaces for alignment +const INDENT_RE = /^(?:( )+|\t+)/; - var fs$ReadStream = fs.ReadStream - ReadStream.prototype = Object.create(fs$ReadStream.prototype) - ReadStream.prototype.open = ReadStream$open +function getMostUsed(indents) { + let result = 0; + let maxUsed = 0; + let maxWeight = 0; - var fs$WriteStream = fs.WriteStream - WriteStream.prototype = Object.create(fs$WriteStream.prototype) - WriteStream.prototype.open = WriteStream$open + for (const entry of indents) { + // TODO: use destructuring when targeting Node.js 6 + const key = entry[0]; + const val = entry[1]; - fs.ReadStream = ReadStream - fs.WriteStream = WriteStream + const u = val[0]; + const w = val[1]; - function ReadStream (path, options) { - if (this instanceof ReadStream) - return fs$ReadStream.apply(this, arguments), this - else - return ReadStream.apply(Object.create(ReadStream.prototype), arguments) - } + if (u > maxUsed || (u === maxUsed && w > maxWeight)) { + maxUsed = u; + maxWeight = w; + result = Number(key); + } + } - function ReadStream$open () { - var that = this - open(that.path, that.flags, that.mode, function (err, fd) { - if (err) { - if (that.autoClose) - that.destroy() + return result; +} - that.emit('error', err) - } else { - that.fd = fd - that.emit('open', fd) - that.read() - } - }) - } +module.exports = str => { + if (typeof str !== 'string') { + throw new TypeError('Expected a string'); + } - function WriteStream (path, options) { - if (this instanceof WriteStream) - return fs$WriteStream.apply(this, arguments), this - else - return WriteStream.apply(Object.create(WriteStream.prototype), arguments) - } + // used to see if tabs or spaces are the most used + let tabs = 0; + let spaces = 0; - function WriteStream$open () { - var that = this - open(that.path, that.flags, that.mode, function (err, fd) { - if (err) { - that.destroy() - that.emit('error', err) - } else { - that.fd = fd - that.emit('open', fd) - } - }) - } + // remember the size of previous line's indentation + let prev = 0; - function createReadStream (path, options) { - return new ReadStream(path, options) - } + // remember how many indents/unindents as occurred for a given size + // and how much lines follow a given indentation + // + // indents = { + // 3: [1, 0], + // 4: [1, 5], + // 5: [1, 0], + // 12: [1, 0], + // } + const indents = new Map(); - function createWriteStream (path, options) { - return new WriteStream(path, options) - } + // pointer to the array of last used indent + let current; - var fs$open = fs.open - fs.open = open - function open (path, flags, mode, cb) { - if (typeof mode === 'function') - cb = mode, mode = null + // whether the last action was an indent (opposed to an unindent) + let isIndent; - return go$open(path, flags, mode, cb) + for (const line of str.split(/\n/g)) { + if (!line) { + // ignore empty lines + continue; + } - function go$open (path, flags, mode, cb) { - return fs$open(path, flags, mode, function (err, fd) { - if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) - enqueue([go$open, [path, flags, mode, cb]]) - else { - if (typeof cb === 'function') - cb.apply(this, arguments) - retry() - } - }) - } - } + let indent; + const matches = line.match(INDENT_RE); - return fs -} + if (matches) { + indent = matches[0].length; -function enqueue (elem) { - debug('ENQUEUE', elem[0].name, elem[1]) - queue.push(elem) -} + if (matches[1]) { + spaces++; + } else { + tabs++; + } + } else { + indent = 0; + } -function retry () { - var elem = queue.shift() - if (elem) { - debug('RETRY', elem[0].name, elem[1]) - elem[0].apply(null, elem[1]) - } -} + const diff = indent - prev; + prev = indent; + + if (diff) { + // an indent or unindent has been detected + + isIndent = diff > 0; + + current = indents.get(isIndent ? diff : -diff); + + if (current) { + current[0]++; + } else { + current = [1, 0]; + indents.set(diff, current); + } + } else if (current) { + // if the last action was an indent, increment the weight + current[1] += Number(isIndent); + } + } + + const amount = getMostUsed(indents); + + let type; + let indent; + if (!amount) { + type = null; + indent = ''; + } else if (spaces >= tabs) { + type = 'space'; + indent = ' '.repeat(amount); + } else { + type = 'tab'; + indent = '\t'.repeat(amount); + } + + return { + amount, + type, + indent + }; +}; /***/ }), -/* 221 */ -/***/ (function(module, exports, __webpack_require__) { +/* 225 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -var fs = __webpack_require__(222) -var constants = __webpack_require__(135) +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "installInDir", function() { return installInDir; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "runScriptInPackage", function() { return runScriptInPackage; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "runScriptInPackageStreaming", function() { return runScriptInPackageStreaming; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "yarnWorkspacesInfo", function() { return yarnWorkspacesInfo; }); +/* harmony import */ var _child_process__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(226); +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ -var origCwd = process.cwd -var cwd = null +const YARN_EXEC = process.env.npm_execpath || 'yarn'; -var platform = process.env.GRACEFUL_FS_PLATFORM || process.platform +/** + * Install all dependencies in the given directory + */ +async function installInDir(directory, extraArgs = []) { + const options = ['install', '--non-interactive', ...extraArgs]; // We pass the mutex flag to ensure only one instance of yarn runs at any + // given time (e.g. to avoid conflicts). -process.cwd = function() { - if (!cwd) - cwd = origCwd.call(process) - return cwd + await Object(_child_process__WEBPACK_IMPORTED_MODULE_0__["spawn"])(YARN_EXEC, options, { + cwd: directory + }); } -try { - process.cwd() -} catch (er) {} +/** + * Run script in the given directory + */ -var chdir = process.chdir -process.chdir = function(d) { - cwd = null - chdir.call(process, d) +async function runScriptInPackage(script, args, pkg) { + const execOpts = { + cwd: pkg.path + }; + await Object(_child_process__WEBPACK_IMPORTED_MODULE_0__["spawn"])(YARN_EXEC, ['run', script, ...args], execOpts); } +/** + * Run script in the given directory + */ -module.exports = patch - -function patch (fs) { - // (re-)implement some things that are known busted or missing. +function runScriptInPackageStreaming({ + script, + args, + pkg, + debug +}) { + const execOpts = { + cwd: pkg.path + }; + return Object(_child_process__WEBPACK_IMPORTED_MODULE_0__["spawnStreaming"])(YARN_EXEC, ['run', script, ...args], execOpts, { + prefix: pkg.name, + debug + }); +} +async function yarnWorkspacesInfo(directory) { + const { + stdout + } = await Object(_child_process__WEBPACK_IMPORTED_MODULE_0__["spawn"])(YARN_EXEC, ['--json', 'workspaces', 'info'], { + cwd: directory, + stdio: 'pipe' + }); - // lchmod, broken prior to 0.6.2 - // back-port the fix here. - if (constants.hasOwnProperty('O_SYMLINK') && - process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)) { - patchLchmod(fs) + try { + return JSON.parse(JSON.parse(stdout).data); + } catch (error) { + throw new Error(`'yarn workspaces info --json' produced unexpected output: \n${stdout}`); } +} - // lutimes implementation, or no-op - if (!fs.lutimes) { - patchLutimes(fs) - } +/***/ }), +/* 226 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { - // https://github.com/isaacs/node-graceful-fs/issues/4 - // Chown should not fail on einval or eperm if non-root. - // It should not fail on enosys ever, as this just indicates - // that a fs doesn't support the intended operation. +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "spawn", function() { return spawn; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "spawnStreaming", function() { return spawnStreaming; }); +/* harmony import */ var stream__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(137); +/* harmony import */ var stream__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(stream__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(227); +/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(chalk__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(236); +/* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(execa__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var strong_log_transformer__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(271); +/* harmony import */ var strong_log_transformer__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(strong_log_transformer__WEBPACK_IMPORTED_MODULE_3__); +/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(143); +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - fs.chown = chownFix(fs.chown) - fs.fchown = chownFix(fs.fchown) - fs.lchown = chownFix(fs.lchown) +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - fs.chmod = chmodFix(fs.chmod) - fs.fchmod = chmodFix(fs.fchmod) - fs.lchmod = chmodFix(fs.lchmod) +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - fs.chownSync = chownFixSync(fs.chownSync) - fs.fchownSync = chownFixSync(fs.fchownSync) - fs.lchownSync = chownFixSync(fs.lchownSync) +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ - fs.chmodSync = chmodFixSync(fs.chmodSync) - fs.fchmodSync = chmodFixSync(fs.fchmodSync) - fs.lchmodSync = chmodFixSync(fs.lchmodSync) - fs.stat = statFix(fs.stat) - fs.fstat = statFix(fs.fstat) - fs.lstat = statFix(fs.lstat) - fs.statSync = statFixSync(fs.statSync) - fs.fstatSync = statFixSync(fs.fstatSync) - fs.lstatSync = statFixSync(fs.lstatSync) - // if lchmod/lchown do not exist, then make them no-ops - if (!fs.lchmod) { - fs.lchmod = function (path, mode, cb) { - if (cb) process.nextTick(cb) - } - fs.lchmodSync = function () {} - } - if (!fs.lchown) { - fs.lchown = function (path, uid, gid, cb) { - if (cb) process.nextTick(cb) - } - fs.lchownSync = function () {} - } - // on Windows, A/V software can lock the directory, causing this - // to fail with an EACCES or EPERM if the directory contains newly - // created files. Try again on failure, for up to 60 seconds. +const colorWheel = [chalk__WEBPACK_IMPORTED_MODULE_1___default.a.cyan, chalk__WEBPACK_IMPORTED_MODULE_1___default.a.magenta, chalk__WEBPACK_IMPORTED_MODULE_1___default.a.blue, chalk__WEBPACK_IMPORTED_MODULE_1___default.a.yellow, chalk__WEBPACK_IMPORTED_MODULE_1___default.a.green]; - // Set the timeout this long because some Windows Anti-Virus, such as Parity - // bit9, may lock files for up to a minute, causing npm package install - // failures. Also, take care to yield the scheduler. Windows scheduling gives - // CPU to a busy looping process, which can cause the program causing the lock - // contention to be starved of CPU by node, so the contention doesn't resolve. - if (platform === "win32") { - fs.rename = (function (fs$rename) { return function (from, to, cb) { - var start = Date.now() - var backoff = 0; - fs$rename(from, to, function CB (er) { - if (er - && (er.code === "EACCES" || er.code === "EPERM") - && Date.now() - start < 60000) { - setTimeout(function() { - fs.stat(to, function (stater, st) { - if (stater && stater.code === "ENOENT") - fs$rename(from, to, CB); - else - cb(er) - }) - }, backoff) - if (backoff < 100) - backoff += 10; - return; - } - if (cb) cb(er) - }) - }})(fs.rename) - } - - // if read() returns EAGAIN, then just try it again. - fs.read = (function (fs$read) { return function (fd, buffer, offset, length, position, callback_) { - var callback - if (callback_ && typeof callback_ === 'function') { - var eagCounter = 0 - callback = function (er, _, __) { - if (er && er.code === 'EAGAIN' && eagCounter < 10) { - eagCounter ++ - return fs$read.call(fs, fd, buffer, offset, length, position, callback) - } - callback_.apply(this, arguments) - } - } - return fs$read.call(fs, fd, buffer, offset, length, position, callback) - }})(fs.read) +const getColor = () => { + const color = colorWheel.shift(); + colorWheel.push(color); + return color; +}; - fs.readSync = (function (fs$readSync) { return function (fd, buffer, offset, length, position) { - var eagCounter = 0 - while (true) { - try { - return fs$readSync.call(fs, fd, buffer, offset, length, position) - } catch (er) { - if (er.code === 'EAGAIN' && eagCounter < 10) { - eagCounter ++ - continue - } - throw er - } - } - }})(fs.readSync) +function spawn(command, args, opts) { + return execa__WEBPACK_IMPORTED_MODULE_2___default()(command, args, _objectSpread({ + stdio: 'inherit', + preferLocal: true + }, opts)); } -function patchLchmod (fs) { - fs.lchmod = function (path, mode, callback) { - fs.open( path - , constants.O_WRONLY | constants.O_SYMLINK - , mode - , function (err, fd) { - if (err) { - if (callback) callback(err) - return - } - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - fs.fchmod(fd, mode, function (err) { - fs.close(fd, function(err2) { - if (callback) callback(err || err2) - }) - }) - }) - } - - fs.lchmodSync = function (path, mode) { - var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK, mode) +function streamToLog(debug = true) { + return new stream__WEBPACK_IMPORTED_MODULE_0__["Writable"]({ + objectMode: true, - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - var threw = true - var ret - try { - ret = fs.fchmodSync(fd, mode) - threw = false - } finally { - if (threw) { - try { - fs.closeSync(fd) - } catch (er) {} + write(line, _, cb) { + if (line.endsWith('\n')) { + _log__WEBPACK_IMPORTED_MODULE_4__["log"][debug ? 'debug' : 'write'](line.slice(0, -1)); } else { - fs.closeSync(fd) + _log__WEBPACK_IMPORTED_MODULE_4__["log"][debug ? 'debug' : 'write'](line); } - } - return ret - } -} - -function patchLutimes (fs) { - if (constants.hasOwnProperty("O_SYMLINK")) { - fs.lutimes = function (path, at, mt, cb) { - fs.open(path, constants.O_SYMLINK, function (er, fd) { - if (er) { - if (cb) cb(er) - return - } - fs.futimes(fd, at, mt, function (er) { - fs.close(fd, function (er2) { - if (cb) cb(er || er2) - }) - }) - }) - } - fs.lutimesSync = function (path, at, mt) { - var fd = fs.openSync(path, constants.O_SYMLINK) - var ret - var threw = true - try { - ret = fs.futimesSync(fd, at, mt) - threw = false - } finally { - if (threw) { - try { - fs.closeSync(fd) - } catch (er) {} - } else { - fs.closeSync(fd) - } - } - return ret + cb(); } - } else { - fs.lutimes = function (_a, _b, _c, cb) { if (cb) process.nextTick(cb) } - fs.lutimesSync = function () {} - } -} - -function chmodFix (orig) { - if (!orig) return orig - return function (target, mode, cb) { - return orig.call(fs, target, mode, function (er) { - if (chownErOk(er)) er = null - if (cb) cb.apply(this, arguments) - }) - } + }); } -function chmodFixSync (orig) { - if (!orig) return orig - return function (target, mode) { - try { - return orig.call(fs, target, mode) - } catch (er) { - if (!chownErOk(er)) throw er - } - } +function spawnStreaming(command, args, opts, { + prefix, + debug +}) { + const spawned = execa__WEBPACK_IMPORTED_MODULE_2___default()(command, args, _objectSpread({ + stdio: ['ignore', 'pipe', 'pipe'], + preferLocal: true + }, opts)); + const color = getColor(); + const prefixedStdout = strong_log_transformer__WEBPACK_IMPORTED_MODULE_3___default()({ + tag: color.bold(prefix) + }); + const prefixedStderr = strong_log_transformer__WEBPACK_IMPORTED_MODULE_3___default()({ + mergeMultiline: true, + tag: color.bold(prefix) + }); + spawned.stdout.pipe(prefixedStdout).pipe(streamToLog(debug)); + spawned.stderr.pipe(prefixedStderr).pipe(streamToLog(debug)); + return spawned; } +/***/ }), +/* 227 */ +/***/ (function(module, exports, __webpack_require__) { -function chownFix (orig) { - if (!orig) return orig - return function (target, uid, gid, cb) { - return orig.call(fs, target, uid, gid, function (er) { - if (chownErOk(er)) er = null - if (cb) cb.apply(this, arguments) - }) - } -} - -function chownFixSync (orig) { - if (!orig) return orig - return function (target, uid, gid) { - try { - return orig.call(fs, target, uid, gid) - } catch (er) { - if (!chownErOk(er)) throw er - } - } -} +"use strict"; +const ansiStyles = __webpack_require__(228); +const {stdout: stdoutColor, stderr: stderrColor} = __webpack_require__(232); +const { + stringReplaceAll, + stringEncaseCRLFWithFirstIndex +} = __webpack_require__(234); -function statFix (orig) { - if (!orig) return orig - // Older versions of Node erroneously returned signed integers for - // uid + gid. - return function (target, cb) { - return orig.call(fs, target, function (er, stats) { - if (!stats) return cb.apply(this, arguments) - if (stats.uid < 0) stats.uid += 0x100000000 - if (stats.gid < 0) stats.gid += 0x100000000 - if (cb) cb.apply(this, arguments) - }) - } -} +const {isArray} = Array; -function statFixSync (orig) { - if (!orig) return orig - // Older versions of Node erroneously returned signed integers for - // uid + gid. - return function (target) { - var stats = orig.call(fs, target) - if (stats.uid < 0) stats.uid += 0x100000000 - if (stats.gid < 0) stats.gid += 0x100000000 - return stats; - } -} +// `supportsColor.level` → `ansiStyles.color[name]` mapping +const levelMapping = [ + 'ansi', + 'ansi', + 'ansi256', + 'ansi16m' +]; -// ENOSYS means that the fs doesn't support the op. Just ignore -// that, because it doesn't matter. -// -// if there's no getuid, or if getuid() is something other -// than 0, and the error is EINVAL or EPERM, then just ignore -// it. -// -// This specific case is a silent failure in cp, install, tar, -// and most other unix tools that manage permissions. -// -// When running as root, or if other types of errors are -// encountered, then it's strict. -function chownErOk (er) { - if (!er) - return true +const styles = Object.create(null); - if (er.code === "ENOSYS") - return true +const applyOptions = (object, options = {}) => { + if (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) { + throw new Error('The `level` option should be an integer from 0 to 3'); + } - var nonroot = !process.getuid || process.getuid() !== 0 - if (nonroot) { - if (er.code === "EINVAL" || er.code === "EPERM") - return true - } + // Detect level if not set manually + const colorLevel = stdoutColor ? stdoutColor.level : 0; + object.level = options.level === undefined ? colorLevel : options.level; +}; - return false +class ChalkClass { + constructor(options) { + // eslint-disable-next-line no-constructor-return + return chalkFactory(options); + } } +const chalkFactory = options => { + const chalk = {}; + applyOptions(chalk, options); -/***/ }), -/* 222 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var fs = __webpack_require__(133) + chalk.template = (...arguments_) => chalkTag(chalk.template, ...arguments_); -module.exports = clone(fs) + Object.setPrototypeOf(chalk, Chalk.prototype); + Object.setPrototypeOf(chalk.template, chalk); -function clone (obj) { - if (obj === null || typeof obj !== 'object') - return obj + chalk.template.constructor = () => { + throw new Error('`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.'); + }; - if (obj instanceof Object) - var copy = { __proto__: obj.__proto__ } - else - var copy = Object.create(null) + chalk.template.Instance = ChalkClass; - Object.getOwnPropertyNames(obj).forEach(function (key) { - Object.defineProperty(copy, key, Object.getOwnPropertyDescriptor(obj, key)) - }) + return chalk.template; +}; - return copy +function Chalk(options) { + return chalkFactory(options); } +for (const [styleName, style] of Object.entries(ansiStyles)) { + styles[styleName] = { + get() { + const builder = createBuilder(this, createStyler(style.open, style.close, this._styler), this._isEmpty); + Object.defineProperty(this, styleName, {value: builder}); + return builder; + } + }; +} -/***/ }), -/* 223 */ -/***/ (function(module, exports, __webpack_require__) { +styles.visible = { + get() { + const builder = createBuilder(this, this._styler, true); + Object.defineProperty(this, 'visible', {value: builder}); + return builder; + } +}; -var Stream = __webpack_require__(137).Stream +const usedModels = ['rgb', 'hex', 'keyword', 'hsl', 'hsv', 'hwb', 'ansi', 'ansi256']; -module.exports = legacy +for (const model of usedModels) { + styles[model] = { + get() { + const {level} = this; + return function (...arguments_) { + const styler = createStyler(ansiStyles.color[levelMapping[level]][model](...arguments_), ansiStyles.color.close, this._styler); + return createBuilder(this, styler, this._isEmpty); + }; + } + }; +} -function legacy (fs) { - return { - ReadStream: ReadStream, - WriteStream: WriteStream - } +for (const model of usedModels) { + const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1); + styles[bgModel] = { + get() { + const {level} = this; + return function (...arguments_) { + const styler = createStyler(ansiStyles.bgColor[levelMapping[level]][model](...arguments_), ansiStyles.bgColor.close, this._styler); + return createBuilder(this, styler, this._isEmpty); + }; + } + }; +} - function ReadStream (path, options) { - if (!(this instanceof ReadStream)) return new ReadStream(path, options); +const proto = Object.defineProperties(() => {}, { + ...styles, + level: { + enumerable: true, + get() { + return this._generator.level; + }, + set(level) { + this._generator.level = level; + } + } +}); - Stream.call(this); +const createStyler = (open, close, parent) => { + let openAll; + let closeAll; + if (parent === undefined) { + openAll = open; + closeAll = close; + } else { + openAll = parent.openAll + open; + closeAll = close + parent.closeAll; + } - var self = this; + return { + open, + close, + openAll, + closeAll, + parent + }; +}; - this.path = path; - this.fd = null; - this.readable = true; - this.paused = false; +const createBuilder = (self, _styler, _isEmpty) => { + const builder = (...arguments_) => { + if (isArray(arguments_[0]) && isArray(arguments_[0].raw)) { + // Called as a template literal, for example: chalk.red`2 + 3 = {bold ${2+3}}` + return applyStyle(builder, chalkTag(builder, ...arguments_)); + } - this.flags = 'r'; - this.mode = 438; /*=0666*/ - this.bufferSize = 64 * 1024; + // Single argument is hot path, implicit coercion is faster than anything + // eslint-disable-next-line no-implicit-coercion + return applyStyle(builder, (arguments_.length === 1) ? ('' + arguments_[0]) : arguments_.join(' ')); + }; - options = options || {}; + // We alter the prototype because we must return a function, but there is + // no way to create a function with a different prototype + Object.setPrototypeOf(builder, proto); - // Mixin options into this - var keys = Object.keys(options); - for (var index = 0, length = keys.length; index < length; index++) { - var key = keys[index]; - this[key] = options[key]; - } + builder._generator = self; + builder._styler = _styler; + builder._isEmpty = _isEmpty; - if (this.encoding) this.setEncoding(this.encoding); + return builder; +}; - if (this.start !== undefined) { - if ('number' !== typeof this.start) { - throw TypeError('start must be a Number'); - } - if (this.end === undefined) { - this.end = Infinity; - } else if ('number' !== typeof this.end) { - throw TypeError('end must be a Number'); - } +const applyStyle = (self, string) => { + if (self.level <= 0 || !string) { + return self._isEmpty ? '' : string; + } - if (this.start > this.end) { - throw new Error('start must be <= end'); - } + let styler = self._styler; - this.pos = this.start; - } + if (styler === undefined) { + return string; + } - if (this.fd !== null) { - process.nextTick(function() { - self._read(); - }); - return; - } + const {openAll, closeAll} = styler; + if (string.indexOf('\u001B') !== -1) { + while (styler !== undefined) { + // Replace any instances already present with a re-opening code + // otherwise only the part of the string until said closing code + // will be colored, and the rest will simply be 'plain'. + string = stringReplaceAll(string, styler.close, styler.open); - fs.open(this.path, this.flags, this.mode, function (err, fd) { - if (err) { - self.emit('error', err); - self.readable = false; - return; - } + styler = styler.parent; + } + } - self.fd = fd; - self.emit('open', fd); - self._read(); - }) - } + // We can move both next actions out of loop, because remaining actions in loop won't have + // any/visible effect on parts we add here. Close the styling before a linebreak and reopen + // after next line to fix a bleed issue on macOS: https://github.com/chalk/chalk/pull/92 + const lfIndex = string.indexOf('\n'); + if (lfIndex !== -1) { + string = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex); + } - function WriteStream (path, options) { - if (!(this instanceof WriteStream)) return new WriteStream(path, options); + return openAll + string + closeAll; +}; - Stream.call(this); +let template; +const chalkTag = (chalk, ...strings) => { + const [firstString] = strings; - this.path = path; - this.fd = null; - this.writable = true; + if (!isArray(firstString) || !isArray(firstString.raw)) { + // If chalk() was called by itself or with a string, + // return the string itself as a string. + return strings.join(' '); + } - this.flags = 'w'; - this.encoding = 'binary'; - this.mode = 438; /*=0666*/ - this.bytesWritten = 0; + const arguments_ = strings.slice(1); + const parts = [firstString.raw[0]]; - options = options || {}; + for (let i = 1; i < firstString.length; i++) { + parts.push( + String(arguments_[i - 1]).replace(/[{}\\]/g, '\\$&'), + String(firstString.raw[i]) + ); + } - // Mixin options into this - var keys = Object.keys(options); - for (var index = 0, length = keys.length; index < length; index++) { - var key = keys[index]; - this[key] = options[key]; - } + if (template === undefined) { + template = __webpack_require__(235); + } - if (this.start !== undefined) { - if ('number' !== typeof this.start) { - throw TypeError('start must be a Number'); - } - if (this.start < 0) { - throw new Error('start must be >= zero'); - } + return template(chalk, parts.join('')); +}; - this.pos = this.start; - } +Object.defineProperties(Chalk.prototype, styles); - this.busy = false; - this._queue = []; +const chalk = Chalk(); // eslint-disable-line new-cap +chalk.supportsColor = stdoutColor; +chalk.stderr = Chalk({level: stderrColor ? stderrColor.level : 0}); // eslint-disable-line new-cap +chalk.stderr.supportsColor = stderrColor; - if (this.fd === null) { - this._open = fs.open; - this._queue.push([this._open, this.path, this.flags, this.mode, undefined]); - this.flush(); - } - } -} +module.exports = chalk; /***/ }), -/* 224 */ +/* 228 */ /***/ (function(module, exports, __webpack_require__) { -/** - * @preserve - * JS Implementation of incremental MurmurHash3 (r150) (as of May 10, 2013) - * - * @author Jens Taylor - * @see http://github.com/homebrewing/brauhaus-diff - * @author Gary Court - * @see http://github.com/garycourt/murmurhash-js - * @author Austin Appleby - * @see http://sites.google.com/site/murmurhash/ - */ -(function(){ - var cache; +"use strict"; +/* WEBPACK VAR INJECTION */(function(module) { - // Call this function without `new` to use the cached object (good for - // single-threaded environments), or with `new` to create a new object. - // - // @param {string} key A UTF-16 or ASCII string - // @param {number} seed An optional positive integer - // @return {object} A MurmurHash3 object for incremental hashing - function MurmurHash3(key, seed) { - var m = this instanceof MurmurHash3 ? this : cache; - m.reset(seed) - if (typeof key === 'string' && key.length > 0) { - m.hash(key); - } +const wrapAnsi16 = (fn, offset) => (...args) => { + const code = fn(...args); + return `\u001B[${code + offset}m`; +}; - if (m !== this) { - return m; - } - }; +const wrapAnsi256 = (fn, offset) => (...args) => { + const code = fn(...args); + return `\u001B[${38 + offset};5;${code}m`; +}; - // Incrementally add a string to this hash - // - // @param {string} key A UTF-16 or ASCII string - // @return {object} this - MurmurHash3.prototype.hash = function(key) { - var h1, k1, i, top, len; +const wrapAnsi16m = (fn, offset) => (...args) => { + const rgb = fn(...args); + return `\u001B[${38 + offset};2;${rgb[0]};${rgb[1]};${rgb[2]}m`; +}; - len = key.length; - this.len += len; +const ansi2ansi = n => n; +const rgb2rgb = (r, g, b) => [r, g, b]; - k1 = this.k1; - i = 0; - switch (this.rem) { - case 0: k1 ^= len > i ? (key.charCodeAt(i++) & 0xffff) : 0; - case 1: k1 ^= len > i ? (key.charCodeAt(i++) & 0xffff) << 8 : 0; - case 2: k1 ^= len > i ? (key.charCodeAt(i++) & 0xffff) << 16 : 0; - case 3: - k1 ^= len > i ? (key.charCodeAt(i) & 0xff) << 24 : 0; - k1 ^= len > i ? (key.charCodeAt(i++) & 0xff00) >> 8 : 0; - } +const setLazyProperty = (object, property, get) => { + Object.defineProperty(object, property, { + get: () => { + const value = get(); - this.rem = (len + this.rem) & 3; // & 3 is same as % 4 - len -= this.rem; - if (len > 0) { - h1 = this.h1; - while (1) { - k1 = (k1 * 0x2d51 + (k1 & 0xffff) * 0xcc9e0000) & 0xffffffff; - k1 = (k1 << 15) | (k1 >>> 17); - k1 = (k1 * 0x3593 + (k1 & 0xffff) * 0x1b870000) & 0xffffffff; - - h1 ^= k1; - h1 = (h1 << 13) | (h1 >>> 19); - h1 = (h1 * 5 + 0xe6546b64) & 0xffffffff; - - if (i >= len) { - break; - } + Object.defineProperty(object, property, { + value, + enumerable: true, + configurable: true + }); - k1 = ((key.charCodeAt(i++) & 0xffff)) ^ - ((key.charCodeAt(i++) & 0xffff) << 8) ^ - ((key.charCodeAt(i++) & 0xffff) << 16); - top = key.charCodeAt(i++); - k1 ^= ((top & 0xff) << 24) ^ - ((top & 0xff00) >> 8); - } + return value; + }, + enumerable: true, + configurable: true + }); +}; - k1 = 0; - switch (this.rem) { - case 3: k1 ^= (key.charCodeAt(i + 2) & 0xffff) << 16; - case 2: k1 ^= (key.charCodeAt(i + 1) & 0xffff) << 8; - case 1: k1 ^= (key.charCodeAt(i) & 0xffff); - } +/** @type {typeof import('color-convert')} */ +let colorConvert; +const makeDynamicStyles = (wrap, targetSpace, identity, isBackground) => { + if (colorConvert === undefined) { + colorConvert = __webpack_require__(229); + } - this.h1 = h1; - } + const offset = isBackground ? 10 : 0; + const styles = {}; - this.k1 = k1; - return this; - }; + for (const [sourceSpace, suite] of Object.entries(colorConvert)) { + const name = sourceSpace === 'ansi16' ? 'ansi' : sourceSpace; + if (sourceSpace === targetSpace) { + styles[name] = wrap(identity, offset); + } else if (typeof suite === 'object') { + styles[name] = wrap(suite[targetSpace], offset); + } + } - // Get the result of this hash - // - // @return {number} The 32-bit hash - MurmurHash3.prototype.result = function() { - var k1, h1; - - k1 = this.k1; - h1 = this.h1; + return styles; +}; - if (k1 > 0) { - k1 = (k1 * 0x2d51 + (k1 & 0xffff) * 0xcc9e0000) & 0xffffffff; - k1 = (k1 << 15) | (k1 >>> 17); - k1 = (k1 * 0x3593 + (k1 & 0xffff) * 0x1b870000) & 0xffffffff; - h1 ^= k1; - } +function assembleStyles() { + const codes = new Map(); + const styles = { + modifier: { + reset: [0, 0], + // 21 isn't widely supported and 22 does the same thing + bold: [1, 22], + dim: [2, 22], + italic: [3, 23], + underline: [4, 24], + inverse: [7, 27], + hidden: [8, 28], + strikethrough: [9, 29] + }, + color: { + black: [30, 39], + red: [31, 39], + green: [32, 39], + yellow: [33, 39], + blue: [34, 39], + magenta: [35, 39], + cyan: [36, 39], + white: [37, 39], - h1 ^= this.len; + // Bright color + blackBright: [90, 39], + redBright: [91, 39], + greenBright: [92, 39], + yellowBright: [93, 39], + blueBright: [94, 39], + magentaBright: [95, 39], + cyanBright: [96, 39], + whiteBright: [97, 39] + }, + bgColor: { + bgBlack: [40, 49], + bgRed: [41, 49], + bgGreen: [42, 49], + bgYellow: [43, 49], + bgBlue: [44, 49], + bgMagenta: [45, 49], + bgCyan: [46, 49], + bgWhite: [47, 49], - h1 ^= h1 >>> 16; - h1 = (h1 * 0xca6b + (h1 & 0xffff) * 0x85eb0000) & 0xffffffff; - h1 ^= h1 >>> 13; - h1 = (h1 * 0xae35 + (h1 & 0xffff) * 0xc2b20000) & 0xffffffff; - h1 ^= h1 >>> 16; + // Bright color + bgBlackBright: [100, 49], + bgRedBright: [101, 49], + bgGreenBright: [102, 49], + bgYellowBright: [103, 49], + bgBlueBright: [104, 49], + bgMagentaBright: [105, 49], + bgCyanBright: [106, 49], + bgWhiteBright: [107, 49] + } + }; - return h1 >>> 0; - }; + // Alias bright black as gray (and grey) + styles.color.gray = styles.color.blackBright; + styles.bgColor.bgGray = styles.bgColor.bgBlackBright; + styles.color.grey = styles.color.blackBright; + styles.bgColor.bgGrey = styles.bgColor.bgBlackBright; - // Reset the hash object for reuse - // - // @param {number} seed An optional positive integer - MurmurHash3.prototype.reset = function(seed) { - this.h1 = typeof seed === 'number' ? seed : 0; - this.rem = this.k1 = this.len = 0; - return this; - }; + for (const [groupName, group] of Object.entries(styles)) { + for (const [styleName, style] of Object.entries(group)) { + styles[styleName] = { + open: `\u001B[${style[0]}m`, + close: `\u001B[${style[1]}m` + }; - // A cached object to use. This can be safely used if you're in a single- - // threaded environment, otherwise you need to create new hashes to use. - cache = new MurmurHash3(); + group[styleName] = styles[styleName]; - if (true) { - module.exports = MurmurHash3; - } else {} -}()); + codes.set(style[0], style[1]); + } + Object.defineProperty(styles, groupName, { + value: group, + enumerable: false + }); + } -/***/ }), -/* 225 */ -/***/ (function(module, exports, __webpack_require__) { + Object.defineProperty(styles, 'codes', { + value: codes, + enumerable: false + }); -// Note: since nyc uses this module to output coverage, any lines -// that are in the direct sync flow of nyc's outputCoverage are -// ignored, since we can never get coverage for them. -var assert = __webpack_require__(139) -var signals = __webpack_require__(226) + styles.color.close = '\u001B[39m'; + styles.bgColor.close = '\u001B[49m'; -var EE = __webpack_require__(155) -/* istanbul ignore if */ -if (typeof EE !== 'function') { - EE = EE.EventEmitter -} + setLazyProperty(styles.color, 'ansi', () => makeDynamicStyles(wrapAnsi16, 'ansi16', ansi2ansi, false)); + setLazyProperty(styles.color, 'ansi256', () => makeDynamicStyles(wrapAnsi256, 'ansi256', ansi2ansi, false)); + setLazyProperty(styles.color, 'ansi16m', () => makeDynamicStyles(wrapAnsi16m, 'rgb', rgb2rgb, false)); + setLazyProperty(styles.bgColor, 'ansi', () => makeDynamicStyles(wrapAnsi16, 'ansi16', ansi2ansi, true)); + setLazyProperty(styles.bgColor, 'ansi256', () => makeDynamicStyles(wrapAnsi256, 'ansi256', ansi2ansi, true)); + setLazyProperty(styles.bgColor, 'ansi16m', () => makeDynamicStyles(wrapAnsi16m, 'rgb', rgb2rgb, true)); -var emitter -if (process.__signal_exit_emitter__) { - emitter = process.__signal_exit_emitter__ -} else { - emitter = process.__signal_exit_emitter__ = new EE() - emitter.count = 0 - emitter.emitted = {} + return styles; } -// Because this emitter is a global, we have to check to see if a -// previous version of this library failed to enable infinite listeners. -// I know what you're about to say. But literally everything about -// signal-exit is a compromise with evil. Get used to it. -if (!emitter.infinite) { - emitter.setMaxListeners(Infinity) - emitter.infinite = true -} +// Make the export immutable +Object.defineProperty(module, 'exports', { + enumerable: true, + get: assembleStyles +}); -module.exports = function (cb, opts) { - assert.equal(typeof cb, 'function', 'a callback must be provided for exit handler') +/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(114)(module))) - if (loaded === false) { - load() - } +/***/ }), +/* 229 */ +/***/ (function(module, exports, __webpack_require__) { - var ev = 'exit' - if (opts && opts.alwaysLast) { - ev = 'afterexit' - } +const conversions = __webpack_require__(230); +const route = __webpack_require__(231); - var remove = function () { - emitter.removeListener(ev, cb) - if (emitter.listeners('exit').length === 0 && - emitter.listeners('afterexit').length === 0) { - unload() - } - } - emitter.on(ev, cb) +const convert = {}; - return remove -} +const models = Object.keys(conversions); -module.exports.unload = unload -function unload () { - if (!loaded) { - return - } - loaded = false +function wrapRaw(fn) { + const wrappedFn = function (...args) { + const arg0 = args[0]; + if (arg0 === undefined || arg0 === null) { + return arg0; + } - signals.forEach(function (sig) { - try { - process.removeListener(sig, sigListeners[sig]) - } catch (er) {} - }) - process.emit = originalProcessEmit - process.reallyExit = originalProcessReallyExit - emitter.count -= 1 -} + if (arg0.length > 1) { + args = arg0; + } -function emit (event, code, signal) { - if (emitter.emitted[event]) { - return - } - emitter.emitted[event] = true - emitter.emit(event, code, signal) -} + return fn(args); + }; -// { : , ... } -var sigListeners = {} -signals.forEach(function (sig) { - sigListeners[sig] = function listener () { - // If there are no other listeners, an exit is coming! - // Simplest way: remove us and then re-send the signal. - // We know that this will kill the process, so we can - // safely emit now. - var listeners = process.listeners(sig) - if (listeners.length === emitter.count) { - unload() - emit('exit', null, sig) - /* istanbul ignore next */ - emit('afterexit', null, sig) - /* istanbul ignore next */ - process.kill(process.pid, sig) - } - } -}) + // Preserve .conversion property if there is one + if ('conversion' in fn) { + wrappedFn.conversion = fn.conversion; + } -module.exports.signals = function () { - return signals + return wrappedFn; } -module.exports.load = load +function wrapRounded(fn) { + const wrappedFn = function (...args) { + const arg0 = args[0]; -var loaded = false + if (arg0 === undefined || arg0 === null) { + return arg0; + } -function load () { - if (loaded) { - return - } - loaded = true + if (arg0.length > 1) { + args = arg0; + } - // This is the number of onSignalExit's that are in play. - // It's important so that we can count the correct number of - // listeners on signals, and don't wait for the other one to - // handle it instead of us. - emitter.count += 1 + const result = fn(args); - signals = signals.filter(function (sig) { - try { - process.on(sig, sigListeners[sig]) - return true - } catch (er) { - return false - } - }) + // We're assuming the result is an array here. + // see notice in conversions.js; don't use box types + // in conversion functions. + if (typeof result === 'object') { + for (let len = result.length, i = 0; i < len; i++) { + result[i] = Math.round(result[i]); + } + } - process.emit = processEmit - process.reallyExit = processReallyExit -} + return result; + }; -var originalProcessReallyExit = process.reallyExit -function processReallyExit (code) { - process.exitCode = code || 0 - emit('exit', process.exitCode, null) - /* istanbul ignore next */ - emit('afterexit', process.exitCode, null) - /* istanbul ignore next */ - originalProcessReallyExit.call(process, process.exitCode) -} + // Preserve .conversion property if there is one + if ('conversion' in fn) { + wrappedFn.conversion = fn.conversion; + } -var originalProcessEmit = process.emit -function processEmit (ev, arg) { - if (ev === 'exit') { - if (arg !== undefined) { - process.exitCode = arg - } - var ret = originalProcessEmit.apply(this, arguments) - emit('exit', process.exitCode, null) - /* istanbul ignore next */ - emit('afterexit', process.exitCode, null) - return ret - } else { - return originalProcessEmit.apply(this, arguments) - } + return wrappedFn; } +models.forEach(fromModel => { + convert[fromModel] = {}; -/***/ }), -/* 226 */ -/***/ (function(module, exports) { - -// This is not the set of all possible signals. -// -// It IS, however, the set of all signals that trigger -// an exit on either Linux or BSD systems. Linux is a -// superset of the signal names supported on BSD, and -// the unknown signals just fail to register, so we can -// catch that easily enough. -// -// Don't bother with SIGKILL. It's uncatchable, which -// means that we can't fire any callbacks anyway. -// -// If a user does happen to register a handler on a non- -// fatal signal like SIGWINCH or something, and then -// exit, it'll end up firing `process.emit('exit')`, so -// the handler will be fired anyway. -// -// SIGBUS, SIGFPE, SIGSEGV and SIGILL, when not raised -// artificially, inherently leave the process in a -// state from which it is not safe to try and enter JS -// listeners. -module.exports = [ - 'SIGABRT', - 'SIGALRM', - 'SIGHUP', - 'SIGINT', - 'SIGTERM' -] + Object.defineProperty(convert[fromModel], 'channels', {value: conversions[fromModel].channels}); + Object.defineProperty(convert[fromModel], 'labels', {value: conversions[fromModel].labels}); -if (process.platform !== 'win32') { - module.exports.push( - 'SIGVTALRM', - 'SIGXCPU', - 'SIGXFSZ', - 'SIGUSR2', - 'SIGTRAP', - 'SIGSYS', - 'SIGQUIT', - 'SIGIOT' - // should detect profiler and enable/disable accordingly. - // see #21 - // 'SIGPROF' - ) -} + const routes = route(fromModel); + const routeModels = Object.keys(routes); -if (process.platform === 'linux') { - module.exports.push( - 'SIGIO', - 'SIGPOLL', - 'SIGPWR', - 'SIGSTKFLT', - 'SIGUNUSED' - ) -} + routeModels.forEach(toModel => { + const fn = routes[toModel]; + convert[fromModel][toModel] = wrapRounded(fn); + convert[fromModel][toModel].raw = wrapRaw(fn); + }); +}); -/***/ }), -/* 227 */ -/***/ (function(module, exports) { +module.exports = convert; -module.exports = require(undefined); /***/ }), -/* 228 */ +/* 230 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; +/* MIT license */ +/* eslint-disable no-mixed-operators */ +const cssKeywords = __webpack_require__(117); -const isPlainObj = __webpack_require__(229); +// NOTE: conversions should only return primitive values (i.e. arrays, or +// values that give correct `typeof` results). +// do not use box values types (i.e. Number(), String(), etc.) -module.exports = (obj, opts) => { - if (!isPlainObj(obj)) { - throw new TypeError('Expected a plain object'); - } +const reverseKeywords = {}; +for (const key of Object.keys(cssKeywords)) { + reverseKeywords[cssKeywords[key]] = key; +} - opts = opts || {}; +const convert = { + rgb: {channels: 3, labels: 'rgb'}, + hsl: {channels: 3, labels: 'hsl'}, + hsv: {channels: 3, labels: 'hsv'}, + hwb: {channels: 3, labels: 'hwb'}, + cmyk: {channels: 4, labels: 'cmyk'}, + xyz: {channels: 3, labels: 'xyz'}, + lab: {channels: 3, labels: 'lab'}, + lch: {channels: 3, labels: 'lch'}, + hex: {channels: 1, labels: ['hex']}, + keyword: {channels: 1, labels: ['keyword']}, + ansi16: {channels: 1, labels: ['ansi16']}, + ansi256: {channels: 1, labels: ['ansi256']}, + hcg: {channels: 3, labels: ['h', 'c', 'g']}, + apple: {channels: 3, labels: ['r16', 'g16', 'b16']}, + gray: {channels: 1, labels: ['gray']} +}; - // DEPRECATED - if (typeof opts === 'function') { - throw new TypeError('Specify the compare function as an option instead'); +module.exports = convert; + +// Hide .channels and .labels properties +for (const model of Object.keys(convert)) { + if (!('channels' in convert[model])) { + throw new Error('missing channels property: ' + model); } - const deep = opts.deep; - const seenInput = []; - const seenOutput = []; + if (!('labels' in convert[model])) { + throw new Error('missing channel labels property: ' + model); + } - const sortKeys = x => { - const seenIndex = seenInput.indexOf(x); + if (convert[model].labels.length !== convert[model].channels) { + throw new Error('channel and label counts mismatch: ' + model); + } - if (seenIndex !== -1) { - return seenOutput[seenIndex]; - } + const {channels, labels} = convert[model]; + delete convert[model].channels; + delete convert[model].labels; + Object.defineProperty(convert[model], 'channels', {value: channels}); + Object.defineProperty(convert[model], 'labels', {value: labels}); +} - const ret = {}; - const keys = Object.keys(x).sort(opts.compare); +convert.rgb.hsl = function (rgb) { + const r = rgb[0] / 255; + const g = rgb[1] / 255; + const b = rgb[2] / 255; + const min = Math.min(r, g, b); + const max = Math.max(r, g, b); + const delta = max - min; + let h; + let s; - seenInput.push(x); - seenOutput.push(ret); + if (max === min) { + h = 0; + } else if (r === max) { + h = (g - b) / delta; + } else if (g === max) { + h = 2 + (b - r) / delta; + } else if (b === max) { + h = 4 + (r - g) / delta; + } - for (let i = 0; i < keys.length; i++) { - const key = keys[i]; - const val = x[key]; + h = Math.min(h * 60, 360); - if (deep && Array.isArray(val)) { - const retArr = []; + if (h < 0) { + h += 360; + } - for (let j = 0; j < val.length; j++) { - retArr[j] = isPlainObj(val[j]) ? sortKeys(val[j]) : val[j]; - } + const l = (min + max) / 2; - ret[key] = retArr; - continue; - } + if (max === min) { + s = 0; + } else if (l <= 0.5) { + s = delta / (max + min); + } else { + s = delta / (2 - max - min); + } - ret[key] = deep && isPlainObj(val) ? sortKeys(val) : val; - } + return [h, s * 100, l * 100]; +}; - return ret; +convert.rgb.hsv = function (rgb) { + let rdif; + let gdif; + let bdif; + let h; + let s; + + const r = rgb[0] / 255; + const g = rgb[1] / 255; + const b = rgb[2] / 255; + const v = Math.max(r, g, b); + const diff = v - Math.min(r, g, b); + const diffc = function (c) { + return (v - c) / 6 / diff + 1 / 2; }; - return sortKeys(obj); -}; + if (diff === 0) { + h = 0; + s = 0; + } else { + s = diff / v; + rdif = diffc(r); + gdif = diffc(g); + bdif = diffc(b); + + if (r === v) { + h = bdif - gdif; + } else if (g === v) { + h = (1 / 3) + rdif - bdif; + } else if (b === v) { + h = (2 / 3) + gdif - rdif; + } + if (h < 0) { + h += 1; + } else if (h > 1) { + h -= 1; + } + } -/***/ }), -/* 229 */ -/***/ (function(module, exports, __webpack_require__) { + return [ + h * 360, + s * 100, + v * 100 + ]; +}; -"use strict"; +convert.rgb.hwb = function (rgb) { + const r = rgb[0]; + const g = rgb[1]; + let b = rgb[2]; + const h = convert.rgb.hsl(rgb)[0]; + const w = 1 / 255 * Math.min(r, Math.min(g, b)); -var toString = Object.prototype.toString; + b = 1 - 1 / 255 * Math.max(r, Math.max(g, b)); -module.exports = function (x) { - var prototype; - return toString.call(x) === '[object Object]' && (prototype = Object.getPrototypeOf(x), prototype === null || prototype === Object.getPrototypeOf({})); + return [h, w * 100, b * 100]; }; +convert.rgb.cmyk = function (rgb) { + const r = rgb[0] / 255; + const g = rgb[1] / 255; + const b = rgb[2] / 255; -/***/ }), -/* 230 */ -/***/ (function(module, exports, __webpack_require__) { + const k = Math.min(1 - r, 1 - g, 1 - b); + const c = (1 - r - k) / (1 - k) || 0; + const m = (1 - g - k) / (1 - k) || 0; + const y = (1 - b - k) / (1 - k) || 0; -"use strict"; + return [c * 100, m * 100, y * 100, k * 100]; +}; -const fs = __webpack_require__(133); -const path = __webpack_require__(4); -const pify = __webpack_require__(231); -const semver = __webpack_require__(189); +function comparativeDistance(x, y) { + /* + See https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance + */ + return ( + ((x[0] - y[0]) ** 2) + + ((x[1] - y[1]) ** 2) + + ((x[2] - y[2]) ** 2) + ); +} -const defaults = { - mode: 0o777 & (~process.umask()), - fs -}; +convert.rgb.keyword = function (rgb) { + const reversed = reverseKeywords[rgb]; + if (reversed) { + return reversed; + } -const useNativeRecursiveOption = semver.satisfies(process.version, '>=10.12.0'); + let currentClosestDistance = Infinity; + let currentClosestKeyword; -// https://github.com/nodejs/node/issues/8987 -// https://github.com/libuv/libuv/pull/1088 -const checkPath = pth => { - if (process.platform === 'win32') { - const pathHasInvalidWinCharacters = /[<>:"|?*]/.test(pth.replace(path.parse(pth).root, '')); + for (const keyword of Object.keys(cssKeywords)) { + const value = cssKeywords[keyword]; - if (pathHasInvalidWinCharacters) { - const error = new Error(`Path contains invalid characters: ${pth}`); - error.code = 'EINVAL'; - throw error; + // Compute comparative distance + const distance = comparativeDistance(rgb, value); + + // Check if its less, if so set as closest + if (distance < currentClosestDistance) { + currentClosestDistance = distance; + currentClosestKeyword = keyword; } } -}; -const permissionError = pth => { - // This replicates the exception of `fs.mkdir` with native the - // `recusive` option when run on an invalid drive under Windows. - const error = new Error(`operation not permitted, mkdir '${pth}'`); - error.code = 'EPERM'; - error.errno = -4048; - error.path = pth; - error.syscall = 'mkdir'; - return error; + return currentClosestKeyword; }; -const makeDir = (input, options) => Promise.resolve().then(() => { - checkPath(input); - options = Object.assign({}, defaults, options); - - // TODO: Use util.promisify when targeting Node.js 8 - const mkdir = pify(options.fs.mkdir); - const stat = pify(options.fs.stat); - - if (useNativeRecursiveOption && options.fs.mkdir === fs.mkdir) { - const pth = path.resolve(input); - - return mkdir(pth, { - mode: options.mode, - recursive: true - }).then(() => pth); - } +convert.keyword.rgb = function (keyword) { + return cssKeywords[keyword]; +}; - const make = pth => { - return mkdir(pth, options.mode) - .then(() => pth) - .catch(error => { - if (error.code === 'EPERM') { - throw error; - } +convert.rgb.xyz = function (rgb) { + let r = rgb[0] / 255; + let g = rgb[1] / 255; + let b = rgb[2] / 255; - if (error.code === 'ENOENT') { - if (path.dirname(pth) === pth) { - throw permissionError(pth); - } + // Assume sRGB + r = r > 0.04045 ? (((r + 0.055) / 1.055) ** 2.4) : (r / 12.92); + g = g > 0.04045 ? (((g + 0.055) / 1.055) ** 2.4) : (g / 12.92); + b = b > 0.04045 ? (((b + 0.055) / 1.055) ** 2.4) : (b / 12.92); - if (error.message.includes('null bytes')) { - throw error; - } + const x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805); + const y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722); + const z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505); - return make(path.dirname(pth)).then(() => make(pth)); - } + return [x * 100, y * 100, z * 100]; +}; - return stat(pth) - .then(stats => stats.isDirectory() ? pth : Promise.reject()) - .catch(() => { - throw error; - }); - }); - }; +convert.rgb.lab = function (rgb) { + const xyz = convert.rgb.xyz(rgb); + let x = xyz[0]; + let y = xyz[1]; + let z = xyz[2]; - return make(path.resolve(input)); -}); + x /= 95.047; + y /= 100; + z /= 108.883; -module.exports = makeDir; -module.exports.default = makeDir; + x = x > 0.008856 ? (x ** (1 / 3)) : (7.787 * x) + (16 / 116); + y = y > 0.008856 ? (y ** (1 / 3)) : (7.787 * y) + (16 / 116); + z = z > 0.008856 ? (z ** (1 / 3)) : (7.787 * z) + (16 / 116); -module.exports.sync = (input, options) => { - checkPath(input); - options = Object.assign({}, defaults, options); + const l = (116 * y) - 16; + const a = 500 * (x - y); + const b = 200 * (y - z); - if (useNativeRecursiveOption && options.fs.mkdirSync === fs.mkdirSync) { - const pth = path.resolve(input); + return [l, a, b]; +}; - fs.mkdirSync(pth, { - mode: options.mode, - recursive: true - }); +convert.hsl.rgb = function (hsl) { + const h = hsl[0] / 360; + const s = hsl[1] / 100; + const l = hsl[2] / 100; + let t2; + let t3; + let val; - return pth; + if (s === 0) { + val = l * 255; + return [val, val, val]; } - const make = pth => { - try { - options.fs.mkdirSync(pth, options.mode); - } catch (error) { - if (error.code === 'EPERM') { - throw error; - } + if (l < 0.5) { + t2 = l * (1 + s); + } else { + t2 = l + s - l * s; + } - if (error.code === 'ENOENT') { - if (path.dirname(pth) === pth) { - throw permissionError(pth); - } + const t1 = 2 * l - t2; - if (error.message.includes('null bytes')) { - throw error; - } + const rgb = [0, 0, 0]; + for (let i = 0; i < 3; i++) { + t3 = h + 1 / 3 * -(i - 1); + if (t3 < 0) { + t3++; + } - make(path.dirname(pth)); - return make(pth); - } + if (t3 > 1) { + t3--; + } - try { - if (!options.fs.statSync(pth).isDirectory()) { - throw new Error('The path is not a directory'); - } - } catch (_) { - throw error; - } + if (6 * t3 < 1) { + val = t1 + (t2 - t1) * 6 * t3; + } else if (2 * t3 < 1) { + val = t2; + } else if (3 * t3 < 2) { + val = t1 + (t2 - t1) * (2 / 3 - t3) * 6; + } else { + val = t1; } - return pth; - }; + rgb[i] = val * 255; + } - return make(path.resolve(input)); + return rgb; }; +convert.hsl.hsv = function (hsl) { + const h = hsl[0]; + let s = hsl[1] / 100; + let l = hsl[2] / 100; + let smin = s; + const lmin = Math.max(l, 0.01); -/***/ }), -/* 231 */ -/***/ (function(module, exports, __webpack_require__) { + l *= 2; + s *= (l <= 1) ? l : 2 - l; + smin *= lmin <= 1 ? lmin : 2 - lmin; + const v = (l + s) / 2; + const sv = l === 0 ? (2 * smin) / (lmin + smin) : (2 * s) / (l + s); -"use strict"; + return [h, sv * 100, v * 100]; +}; +convert.hsv.rgb = function (hsv) { + const h = hsv[0] / 60; + const s = hsv[1] / 100; + let v = hsv[2] / 100; + const hi = Math.floor(h) % 6; -const processFn = (fn, options) => function (...args) { - const P = options.promiseModule; + const f = h - Math.floor(h); + const p = 255 * v * (1 - s); + const q = 255 * v * (1 - (s * f)); + const t = 255 * v * (1 - (s * (1 - f))); + v *= 255; - return new P((resolve, reject) => { - if (options.multiArgs) { - args.push((...result) => { - if (options.errorFirst) { - if (result[0]) { - reject(result); - } else { - result.shift(); - resolve(result); - } - } else { - resolve(result); - } - }); - } else if (options.errorFirst) { - args.push((error, result) => { - if (error) { - reject(error); - } else { - resolve(result); - } - }); - } else { - args.push(resolve); - } + switch (hi) { + case 0: + return [v, t, p]; + case 1: + return [q, v, p]; + case 2: + return [p, v, t]; + case 3: + return [p, q, v]; + case 4: + return [t, p, v]; + case 5: + return [v, p, q]; + } +}; - fn.apply(this, args); - }); +convert.hsv.hsl = function (hsv) { + const h = hsv[0]; + const s = hsv[1] / 100; + const v = hsv[2] / 100; + const vmin = Math.max(v, 0.01); + let sl; + let l; + + l = (2 - s) * v; + const lmin = (2 - s) * vmin; + sl = s * vmin; + sl /= (lmin <= 1) ? lmin : 2 - lmin; + sl = sl || 0; + l /= 2; + + return [h, sl * 100, l * 100]; }; -module.exports = (input, options) => { - options = Object.assign({ - exclude: [/.+(Sync|Stream)$/], - errorFirst: true, - promiseModule: Promise - }, options); +// http://dev.w3.org/csswg/css-color/#hwb-to-rgb +convert.hwb.rgb = function (hwb) { + const h = hwb[0] / 360; + let wh = hwb[1] / 100; + let bl = hwb[2] / 100; + const ratio = wh + bl; + let f; - const objType = typeof input; - if (!(input !== null && (objType === 'object' || objType === 'function'))) { - throw new TypeError(`Expected \`input\` to be a \`Function\` or \`Object\`, got \`${input === null ? 'null' : objType}\``); + // Wh + bl cant be > 1 + if (ratio > 1) { + wh /= ratio; + bl /= ratio; } - const filter = key => { - const match = pattern => typeof pattern === 'string' ? key === pattern : pattern.test(key); - return options.include ? options.include.some(match) : !options.exclude.some(match); - }; + const i = Math.floor(6 * h); + const v = 1 - bl; + f = 6 * h - i; - let ret; - if (objType === 'function') { - ret = function (...args) { - return options.excludeMain ? input(...args) : processFn(input, options).apply(this, args); - }; - } else { - ret = Object.create(Object.getPrototypeOf(input)); + if ((i & 0x01) !== 0) { + f = 1 - f; } - for (const key in input) { // eslint-disable-line guard-for-in - const property = input[key]; - ret[key] = typeof property === 'function' && filter(key) ? processFn(property, options) : property; + const n = wh + f * (v - wh); // Linear interpolation + + let r; + let g; + let b; + /* eslint-disable max-statements-per-line,no-multi-spaces */ + switch (i) { + default: + case 6: + case 0: r = v; g = n; b = wh; break; + case 1: r = n; g = v; b = wh; break; + case 2: r = wh; g = v; b = n; break; + case 3: r = wh; g = n; b = v; break; + case 4: r = n; g = wh; b = v; break; + case 5: r = v; g = wh; b = n; break; } + /* eslint-enable max-statements-per-line,no-multi-spaces */ - return ret; + return [r * 255, g * 255, b * 255]; }; +convert.cmyk.rgb = function (cmyk) { + const c = cmyk[0] / 100; + const m = cmyk[1] / 100; + const y = cmyk[2] / 100; + const k = cmyk[3] / 100; -/***/ }), -/* 232 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; + const r = 1 - Math.min(1, c * (1 - k) + k); + const g = 1 - Math.min(1, m * (1 - k) + k); + const b = 1 - Math.min(1, y * (1 - k) + k); + return [r * 255, g * 255, b * 255]; +}; -// detect either spaces or tabs but not both to properly handle tabs -// for indentation and spaces for alignment -const INDENT_RE = /^(?:( )+|\t+)/; +convert.xyz.rgb = function (xyz) { + const x = xyz[0] / 100; + const y = xyz[1] / 100; + const z = xyz[2] / 100; + let r; + let g; + let b; -function getMostUsed(indents) { - let result = 0; - let maxUsed = 0; - let maxWeight = 0; + r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986); + g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415); + b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570); - for (const entry of indents) { - // TODO: use destructuring when targeting Node.js 6 - const key = entry[0]; - const val = entry[1]; + // Assume sRGB + r = r > 0.0031308 + ? ((1.055 * (r ** (1.0 / 2.4))) - 0.055) + : r * 12.92; - const u = val[0]; - const w = val[1]; + g = g > 0.0031308 + ? ((1.055 * (g ** (1.0 / 2.4))) - 0.055) + : g * 12.92; - if (u > maxUsed || (u === maxUsed && w > maxWeight)) { - maxUsed = u; - maxWeight = w; - result = Number(key); - } - } + b = b > 0.0031308 + ? ((1.055 * (b ** (1.0 / 2.4))) - 0.055) + : b * 12.92; - return result; -} - -module.exports = str => { - if (typeof str !== 'string') { - throw new TypeError('Expected a string'); - } + r = Math.min(Math.max(0, r), 1); + g = Math.min(Math.max(0, g), 1); + b = Math.min(Math.max(0, b), 1); - // used to see if tabs or spaces are the most used - let tabs = 0; - let spaces = 0; + return [r * 255, g * 255, b * 255]; +}; - // remember the size of previous line's indentation - let prev = 0; +convert.xyz.lab = function (xyz) { + let x = xyz[0]; + let y = xyz[1]; + let z = xyz[2]; - // remember how many indents/unindents as occurred for a given size - // and how much lines follow a given indentation - // - // indents = { - // 3: [1, 0], - // 4: [1, 5], - // 5: [1, 0], - // 12: [1, 0], - // } - const indents = new Map(); + x /= 95.047; + y /= 100; + z /= 108.883; - // pointer to the array of last used indent - let current; + x = x > 0.008856 ? (x ** (1 / 3)) : (7.787 * x) + (16 / 116); + y = y > 0.008856 ? (y ** (1 / 3)) : (7.787 * y) + (16 / 116); + z = z > 0.008856 ? (z ** (1 / 3)) : (7.787 * z) + (16 / 116); - // whether the last action was an indent (opposed to an unindent) - let isIndent; + const l = (116 * y) - 16; + const a = 500 * (x - y); + const b = 200 * (y - z); - for (const line of str.split(/\n/g)) { - if (!line) { - // ignore empty lines - continue; - } + return [l, a, b]; +}; - let indent; - const matches = line.match(INDENT_RE); +convert.lab.xyz = function (lab) { + const l = lab[0]; + const a = lab[1]; + const b = lab[2]; + let x; + let y; + let z; - if (matches) { - indent = matches[0].length; + y = (l + 16) / 116; + x = a / 500 + y; + z = y - b / 200; - if (matches[1]) { - spaces++; - } else { - tabs++; - } - } else { - indent = 0; - } + const y2 = y ** 3; + const x2 = x ** 3; + const z2 = z ** 3; + y = y2 > 0.008856 ? y2 : (y - 16 / 116) / 7.787; + x = x2 > 0.008856 ? x2 : (x - 16 / 116) / 7.787; + z = z2 > 0.008856 ? z2 : (z - 16 / 116) / 7.787; - const diff = indent - prev; - prev = indent; + x *= 95.047; + y *= 100; + z *= 108.883; - if (diff) { - // an indent or unindent has been detected + return [x, y, z]; +}; - isIndent = diff > 0; +convert.lab.lch = function (lab) { + const l = lab[0]; + const a = lab[1]; + const b = lab[2]; + let h; - current = indents.get(isIndent ? diff : -diff); + const hr = Math.atan2(b, a); + h = hr * 360 / 2 / Math.PI; - if (current) { - current[0]++; - } else { - current = [1, 0]; - indents.set(diff, current); - } - } else if (current) { - // if the last action was an indent, increment the weight - current[1] += Number(isIndent); - } + if (h < 0) { + h += 360; } - const amount = getMostUsed(indents); - - let type; - let indent; - if (!amount) { - type = null; - indent = ''; - } else if (spaces >= tabs) { - type = 'space'; - indent = ' '.repeat(amount); - } else { - type = 'tab'; - indent = '\t'.repeat(amount); - } + const c = Math.sqrt(a * a + b * b); - return { - amount, - type, - indent - }; + return [l, c, h]; }; +convert.lch.lab = function (lch) { + const l = lch[0]; + const c = lch[1]; + const h = lch[2]; -/***/ }), -/* 233 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + const hr = h / 360 * 2 * Math.PI; + const a = c * Math.cos(hr); + const b = c * Math.sin(hr); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "installInDir", function() { return installInDir; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "runScriptInPackage", function() { return runScriptInPackage; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "runScriptInPackageStreaming", function() { return runScriptInPackageStreaming; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "yarnWorkspacesInfo", function() { return yarnWorkspacesInfo; }); -/* harmony import */ var _child_process__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(234); -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ + return [l, a, b]; +}; -const YARN_EXEC = process.env.npm_execpath || 'yarn'; +convert.rgb.ansi16 = function (args, saturation = null) { + const [r, g, b] = args; + let value = saturation === null ? convert.rgb.hsv(args)[2] : saturation; // Hsv -> ansi16 optimization -/** - * Install all dependencies in the given directory - */ -async function installInDir(directory, extraArgs = []) { - const options = ['install', '--non-interactive', ...extraArgs]; // We pass the mutex flag to ensure only one instance of yarn runs at any - // given time (e.g. to avoid conflicts). + value = Math.round(value / 50); - await Object(_child_process__WEBPACK_IMPORTED_MODULE_0__["spawn"])(YARN_EXEC, options, { - cwd: directory - }); -} -/** - * Run script in the given directory - */ + if (value === 0) { + return 30; + } -async function runScriptInPackage(script, args, pkg) { - const execOpts = { - cwd: pkg.path - }; - await Object(_child_process__WEBPACK_IMPORTED_MODULE_0__["spawn"])(YARN_EXEC, ['run', script, ...args], execOpts); -} -/** - * Run script in the given directory - */ + let ansi = 30 + + ((Math.round(b / 255) << 2) + | (Math.round(g / 255) << 1) + | Math.round(r / 255)); -function runScriptInPackageStreaming({ - script, - args, - pkg, - debug -}) { - const execOpts = { - cwd: pkg.path - }; - return Object(_child_process__WEBPACK_IMPORTED_MODULE_0__["spawnStreaming"])(YARN_EXEC, ['run', script, ...args], execOpts, { - prefix: pkg.name, - debug - }); -} -async function yarnWorkspacesInfo(directory) { - const { - stdout - } = await Object(_child_process__WEBPACK_IMPORTED_MODULE_0__["spawn"])(YARN_EXEC, ['--json', 'workspaces', 'info'], { - cwd: directory, - stdio: 'pipe' - }); + if (value === 2) { + ansi += 60; + } - try { - return JSON.parse(JSON.parse(stdout).data); - } catch (error) { - throw new Error(`'yarn workspaces info --json' produced unexpected output: \n${stdout}`); - } -} + return ansi; +}; -/***/ }), -/* 234 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +convert.hsv.ansi16 = function (args) { + // Optimization here; we already know the value and don't need to get + // it converted for us. + return convert.rgb.ansi16(convert.hsv.rgb(args), args[2]); +}; -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "spawn", function() { return spawn; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "spawnStreaming", function() { return spawnStreaming; }); -/* harmony import */ var stream__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(137); -/* harmony import */ var stream__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(stream__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(235); -/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(chalk__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(244); -/* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(execa__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var strong_log_transformer__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(279); -/* harmony import */ var strong_log_transformer__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(strong_log_transformer__WEBPACK_IMPORTED_MODULE_3__); -/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(143); -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } +convert.rgb.ansi256 = function (args) { + const r = args[0]; + const g = args[1]; + const b = args[2]; -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + // We use the extended greyscale palette here, with the exception of + // black and white. normal palette only has 4 greyscale shades. + if (r === g && g === b) { + if (r < 8) { + return 16; + } -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + if (r > 248) { + return 231; + } -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ + return Math.round(((r - 8) / 247) * 24) + 232; + } + + const ansi = 16 + + (36 * Math.round(r / 255 * 5)) + + (6 * Math.round(g / 255 * 5)) + + Math.round(b / 255 * 5); + return ansi; +}; +convert.ansi16.rgb = function (args) { + let color = args % 10; + // Handle greyscale + if (color === 0 || color === 7) { + if (args > 50) { + color += 3.5; + } + color = color / 10.5 * 255; -const colorWheel = [chalk__WEBPACK_IMPORTED_MODULE_1___default.a.cyan, chalk__WEBPACK_IMPORTED_MODULE_1___default.a.magenta, chalk__WEBPACK_IMPORTED_MODULE_1___default.a.blue, chalk__WEBPACK_IMPORTED_MODULE_1___default.a.yellow, chalk__WEBPACK_IMPORTED_MODULE_1___default.a.green]; + return [color, color, color]; + } -const getColor = () => { - const color = colorWheel.shift(); - colorWheel.push(color); - return color; + const mult = (~~(args > 50) + 1) * 0.5; + const r = ((color & 1) * mult) * 255; + const g = (((color >> 1) & 1) * mult) * 255; + const b = (((color >> 2) & 1) * mult) * 255; + + return [r, g, b]; }; -function spawn(command, args, opts) { - return execa__WEBPACK_IMPORTED_MODULE_2___default()(command, args, _objectSpread({ - stdio: 'inherit', - preferLocal: true - }, opts)); -} +convert.ansi256.rgb = function (args) { + // Handle greyscale + if (args >= 232) { + const c = (args - 232) * 10 + 8; + return [c, c, c]; + } -function streamToLog(debug = true) { - return new stream__WEBPACK_IMPORTED_MODULE_0__["Writable"]({ - objectMode: true, + args -= 16; - write(line, _, cb) { - if (line.endsWith('\n')) { - _log__WEBPACK_IMPORTED_MODULE_4__["log"][debug ? 'debug' : 'write'](line.slice(0, -1)); - } else { - _log__WEBPACK_IMPORTED_MODULE_4__["log"][debug ? 'debug' : 'write'](line); - } + let rem; + const r = Math.floor(args / 36) / 5 * 255; + const g = Math.floor((rem = args % 36) / 6) / 5 * 255; + const b = (rem % 6) / 5 * 255; - cb(); - } + return [r, g, b]; +}; - }); -} +convert.rgb.hex = function (args) { + const integer = ((Math.round(args[0]) & 0xFF) << 16) + + ((Math.round(args[1]) & 0xFF) << 8) + + (Math.round(args[2]) & 0xFF); -function spawnStreaming(command, args, opts, { - prefix, - debug -}) { - const spawned = execa__WEBPACK_IMPORTED_MODULE_2___default()(command, args, _objectSpread({ - stdio: ['ignore', 'pipe', 'pipe'], - preferLocal: true - }, opts)); - const color = getColor(); - const prefixedStdout = strong_log_transformer__WEBPACK_IMPORTED_MODULE_3___default()({ - tag: color.bold(prefix) - }); - const prefixedStderr = strong_log_transformer__WEBPACK_IMPORTED_MODULE_3___default()({ - mergeMultiline: true, - tag: color.bold(prefix) - }); - spawned.stdout.pipe(prefixedStdout).pipe(streamToLog(debug)); - spawned.stderr.pipe(prefixedStderr).pipe(streamToLog(debug)); - return spawned; -} + const string = integer.toString(16).toUpperCase(); + return '000000'.substring(string.length) + string; +}; -/***/ }), -/* 235 */ -/***/ (function(module, exports, __webpack_require__) { +convert.hex.rgb = function (args) { + const match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i); + if (!match) { + return [0, 0, 0]; + } -"use strict"; + let colorString = match[0]; -const ansiStyles = __webpack_require__(236); -const {stdout: stdoutColor, stderr: stderrColor} = __webpack_require__(240); -const { - stringReplaceAll, - stringEncaseCRLFWithFirstIndex -} = __webpack_require__(242); + if (match[0].length === 3) { + colorString = colorString.split('').map(char => { + return char + char; + }).join(''); + } -const {isArray} = Array; + const integer = parseInt(colorString, 16); + const r = (integer >> 16) & 0xFF; + const g = (integer >> 8) & 0xFF; + const b = integer & 0xFF; -// `supportsColor.level` → `ansiStyles.color[name]` mapping -const levelMapping = [ - 'ansi', - 'ansi', - 'ansi256', - 'ansi16m' -]; + return [r, g, b]; +}; -const styles = Object.create(null); +convert.rgb.hcg = function (rgb) { + const r = rgb[0] / 255; + const g = rgb[1] / 255; + const b = rgb[2] / 255; + const max = Math.max(Math.max(r, g), b); + const min = Math.min(Math.min(r, g), b); + const chroma = (max - min); + let grayscale; + let hue; -const applyOptions = (object, options = {}) => { - if (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) { - throw new Error('The `level` option should be an integer from 0 to 3'); + if (chroma < 1) { + grayscale = min / (1 - chroma); + } else { + grayscale = 0; } - // Detect level if not set manually - const colorLevel = stdoutColor ? stdoutColor.level : 0; - object.level = options.level === undefined ? colorLevel : options.level; -}; - -class ChalkClass { - constructor(options) { - // eslint-disable-next-line no-constructor-return - return chalkFactory(options); + if (chroma <= 0) { + hue = 0; + } else + if (max === r) { + hue = ((g - b) / chroma) % 6; + } else + if (max === g) { + hue = 2 + (b - r) / chroma; + } else { + hue = 4 + (r - g) / chroma; } -} -const chalkFactory = options => { - const chalk = {}; - applyOptions(chalk, options); + hue /= 6; + hue %= 1; - chalk.template = (...arguments_) => chalkTag(chalk.template, ...arguments_); + return [hue * 360, chroma * 100, grayscale * 100]; +}; - Object.setPrototypeOf(chalk, Chalk.prototype); - Object.setPrototypeOf(chalk.template, chalk); +convert.hsl.hcg = function (hsl) { + const s = hsl[1] / 100; + const l = hsl[2] / 100; - chalk.template.constructor = () => { - throw new Error('`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.'); - }; + const c = l < 0.5 ? (2.0 * s * l) : (2.0 * s * (1.0 - l)); - chalk.template.Instance = ChalkClass; + let f = 0; + if (c < 1.0) { + f = (l - 0.5 * c) / (1.0 - c); + } - return chalk.template; + return [hsl[0], c * 100, f * 100]; }; -function Chalk(options) { - return chalkFactory(options); -} +convert.hsv.hcg = function (hsv) { + const s = hsv[1] / 100; + const v = hsv[2] / 100; -for (const [styleName, style] of Object.entries(ansiStyles)) { - styles[styleName] = { - get() { - const builder = createBuilder(this, createStyler(style.open, style.close, this._styler), this._isEmpty); - Object.defineProperty(this, styleName, {value: builder}); - return builder; - } - }; -} + const c = s * v; + let f = 0; -styles.visible = { - get() { - const builder = createBuilder(this, this._styler, true); - Object.defineProperty(this, 'visible', {value: builder}); - return builder; + if (c < 1.0) { + f = (v - c) / (1 - c); } + + return [hsv[0], c * 100, f * 100]; }; -const usedModels = ['rgb', 'hex', 'keyword', 'hsl', 'hsv', 'hwb', 'ansi', 'ansi256']; +convert.hcg.rgb = function (hcg) { + const h = hcg[0] / 360; + const c = hcg[1] / 100; + const g = hcg[2] / 100; -for (const model of usedModels) { - styles[model] = { - get() { - const {level} = this; - return function (...arguments_) { - const styler = createStyler(ansiStyles.color[levelMapping[level]][model](...arguments_), ansiStyles.color.close, this._styler); - return createBuilder(this, styler, this._isEmpty); - }; - } - }; -} + if (c === 0.0) { + return [g * 255, g * 255, g * 255]; + } -for (const model of usedModels) { - const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1); - styles[bgModel] = { - get() { - const {level} = this; - return function (...arguments_) { - const styler = createStyler(ansiStyles.bgColor[levelMapping[level]][model](...arguments_), ansiStyles.bgColor.close, this._styler); - return createBuilder(this, styler, this._isEmpty); - }; - } - }; -} + const pure = [0, 0, 0]; + const hi = (h % 1) * 6; + const v = hi % 1; + const w = 1 - v; + let mg = 0; -const proto = Object.defineProperties(() => {}, { - ...styles, - level: { - enumerable: true, - get() { - return this._generator.level; - }, - set(level) { - this._generator.level = level; - } + /* eslint-disable max-statements-per-line */ + switch (Math.floor(hi)) { + case 0: + pure[0] = 1; pure[1] = v; pure[2] = 0; break; + case 1: + pure[0] = w; pure[1] = 1; pure[2] = 0; break; + case 2: + pure[0] = 0; pure[1] = 1; pure[2] = v; break; + case 3: + pure[0] = 0; pure[1] = w; pure[2] = 1; break; + case 4: + pure[0] = v; pure[1] = 0; pure[2] = 1; break; + default: + pure[0] = 1; pure[1] = 0; pure[2] = w; } -}); + /* eslint-enable max-statements-per-line */ -const createStyler = (open, close, parent) => { - let openAll; - let closeAll; - if (parent === undefined) { - openAll = open; - closeAll = close; - } else { - openAll = parent.openAll + open; - closeAll = close + parent.closeAll; - } + mg = (1.0 - c) * g; - return { - open, - close, - openAll, - closeAll, - parent - }; + return [ + (c * pure[0] + mg) * 255, + (c * pure[1] + mg) * 255, + (c * pure[2] + mg) * 255 + ]; }; -const createBuilder = (self, _styler, _isEmpty) => { - const builder = (...arguments_) => { - if (isArray(arguments_[0]) && isArray(arguments_[0].raw)) { - // Called as a template literal, for example: chalk.red`2 + 3 = {bold ${2+3}}` - return applyStyle(builder, chalkTag(builder, ...arguments_)); - } - - // Single argument is hot path, implicit coercion is faster than anything - // eslint-disable-next-line no-implicit-coercion - return applyStyle(builder, (arguments_.length === 1) ? ('' + arguments_[0]) : arguments_.join(' ')); - }; +convert.hcg.hsv = function (hcg) { + const c = hcg[1] / 100; + const g = hcg[2] / 100; - // We alter the prototype because we must return a function, but there is - // no way to create a function with a different prototype - Object.setPrototypeOf(builder, proto); + const v = c + g * (1.0 - c); + let f = 0; - builder._generator = self; - builder._styler = _styler; - builder._isEmpty = _isEmpty; + if (v > 0.0) { + f = c / v; + } - return builder; + return [hcg[0], f * 100, v * 100]; }; -const applyStyle = (self, string) => { - if (self.level <= 0 || !string) { - return self._isEmpty ? '' : string; - } +convert.hcg.hsl = function (hcg) { + const c = hcg[1] / 100; + const g = hcg[2] / 100; - let styler = self._styler; + const l = g * (1.0 - c) + 0.5 * c; + let s = 0; - if (styler === undefined) { - return string; + if (l > 0.0 && l < 0.5) { + s = c / (2 * l); + } else + if (l >= 0.5 && l < 1.0) { + s = c / (2 * (1 - l)); } - const {openAll, closeAll} = styler; - if (string.indexOf('\u001B') !== -1) { - while (styler !== undefined) { - // Replace any instances already present with a re-opening code - // otherwise only the part of the string until said closing code - // will be colored, and the rest will simply be 'plain'. - string = stringReplaceAll(string, styler.close, styler.open); + return [hcg[0], s * 100, l * 100]; +}; - styler = styler.parent; - } - } +convert.hcg.hwb = function (hcg) { + const c = hcg[1] / 100; + const g = hcg[2] / 100; + const v = c + g * (1.0 - c); + return [hcg[0], (v - c) * 100, (1 - v) * 100]; +}; - // We can move both next actions out of loop, because remaining actions in loop won't have - // any/visible effect on parts we add here. Close the styling before a linebreak and reopen - // after next line to fix a bleed issue on macOS: https://github.com/chalk/chalk/pull/92 - const lfIndex = string.indexOf('\n'); - if (lfIndex !== -1) { - string = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex); +convert.hwb.hcg = function (hwb) { + const w = hwb[1] / 100; + const b = hwb[2] / 100; + const v = 1 - b; + const c = v - w; + let g = 0; + + if (c < 1) { + g = (v - c) / (1 - c); } - return openAll + string + closeAll; + return [hwb[0], c * 100, g * 100]; }; -let template; -const chalkTag = (chalk, ...strings) => { - const [firstString] = strings; +convert.apple.rgb = function (apple) { + return [(apple[0] / 65535) * 255, (apple[1] / 65535) * 255, (apple[2] / 65535) * 255]; +}; - if (!isArray(firstString) || !isArray(firstString.raw)) { - // If chalk() was called by itself or with a string, - // return the string itself as a string. - return strings.join(' '); - } +convert.rgb.apple = function (rgb) { + return [(rgb[0] / 255) * 65535, (rgb[1] / 255) * 65535, (rgb[2] / 255) * 65535]; +}; - const arguments_ = strings.slice(1); - const parts = [firstString.raw[0]]; +convert.gray.rgb = function (args) { + return [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255]; +}; - for (let i = 1; i < firstString.length; i++) { - parts.push( - String(arguments_[i - 1]).replace(/[{}\\]/g, '\\$&'), - String(firstString.raw[i]) - ); - } +convert.gray.hsl = function (args) { + return [0, 0, args[0]]; +}; - if (template === undefined) { - template = __webpack_require__(243); - } +convert.gray.hsv = convert.gray.hsl; - return template(chalk, parts.join('')); +convert.gray.hwb = function (gray) { + return [0, 100, gray[0]]; }; -Object.defineProperties(Chalk.prototype, styles); +convert.gray.cmyk = function (gray) { + return [0, 0, 0, gray[0]]; +}; -const chalk = Chalk(); // eslint-disable-line new-cap -chalk.supportsColor = stdoutColor; -chalk.stderr = Chalk({level: stderrColor ? stderrColor.level : 0}); // eslint-disable-line new-cap -chalk.stderr.supportsColor = stderrColor; +convert.gray.lab = function (gray) { + return [gray[0], 0, 0]; +}; -module.exports = chalk; +convert.gray.hex = function (gray) { + const val = Math.round(gray[0] / 100 * 255) & 0xFF; + const integer = (val << 16) + (val << 8) + val; + + const string = integer.toString(16).toUpperCase(); + return '000000'.substring(string.length) + string; +}; + +convert.rgb.gray = function (rgb) { + const val = (rgb[0] + rgb[1] + rgb[2]) / 3; + return [val / 255 * 100]; +}; /***/ }), -/* 236 */ +/* 231 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; -/* WEBPACK VAR INJECTION */(function(module) { +const conversions = __webpack_require__(230); -const wrapAnsi16 = (fn, offset) => (...args) => { - const code = fn(...args); - return `\u001B[${code + offset}m`; -}; +/* + This function routes a model to all other models. -const wrapAnsi256 = (fn, offset) => (...args) => { - const code = fn(...args); - return `\u001B[${38 + offset};5;${code}m`; -}; + all functions that are routed have a property `.conversion` attached + to the returned synthetic function. This property is an array + of strings, each with the steps in between the 'from' and 'to' + color models (inclusive). -const wrapAnsi16m = (fn, offset) => (...args) => { - const rgb = fn(...args); - return `\u001B[${38 + offset};2;${rgb[0]};${rgb[1]};${rgb[2]}m`; -}; + conversions that are not possible simply are not included. +*/ -const ansi2ansi = n => n; -const rgb2rgb = (r, g, b) => [r, g, b]; +function buildGraph() { + const graph = {}; + // https://jsperf.com/object-keys-vs-for-in-with-closure/3 + const models = Object.keys(conversions); -const setLazyProperty = (object, property, get) => { - Object.defineProperty(object, property, { - get: () => { - const value = get(); + for (let len = models.length, i = 0; i < len; i++) { + graph[models[i]] = { + // http://jsperf.com/1-vs-infinity + // micro-opt, but this is simple. + distance: -1, + parent: null + }; + } - Object.defineProperty(object, property, { - value, - enumerable: true, - configurable: true - }); + return graph; +} - return value; - }, - enumerable: true, - configurable: true - }); -}; +// https://en.wikipedia.org/wiki/Breadth-first_search +function deriveBFS(fromModel) { + const graph = buildGraph(); + const queue = [fromModel]; // Unshift -> queue -> pop -/** @type {typeof import('color-convert')} */ -let colorConvert; -const makeDynamicStyles = (wrap, targetSpace, identity, isBackground) => { - if (colorConvert === undefined) { - colorConvert = __webpack_require__(237); - } + graph[fromModel].distance = 0; - const offset = isBackground ? 10 : 0; - const styles = {}; + while (queue.length) { + const current = queue.pop(); + const adjacents = Object.keys(conversions[current]); - for (const [sourceSpace, suite] of Object.entries(colorConvert)) { - const name = sourceSpace === 'ansi16' ? 'ansi' : sourceSpace; - if (sourceSpace === targetSpace) { - styles[name] = wrap(identity, offset); - } else if (typeof suite === 'object') { - styles[name] = wrap(suite[targetSpace], offset); + for (let len = adjacents.length, i = 0; i < len; i++) { + const adjacent = adjacents[i]; + const node = graph[adjacent]; + + if (node.distance === -1) { + node.distance = graph[current].distance + 1; + node.parent = current; + queue.unshift(adjacent); + } } } - return styles; -}; + return graph; +} -function assembleStyles() { - const codes = new Map(); - const styles = { - modifier: { - reset: [0, 0], - // 21 isn't widely supported and 22 does the same thing - bold: [1, 22], - dim: [2, 22], - italic: [3, 23], - underline: [4, 24], - inverse: [7, 27], - hidden: [8, 28], - strikethrough: [9, 29] - }, - color: { - black: [30, 39], - red: [31, 39], - green: [32, 39], - yellow: [33, 39], - blue: [34, 39], - magenta: [35, 39], - cyan: [36, 39], - white: [37, 39], +function link(from, to) { + return function (args) { + return to(from(args)); + }; +} - // Bright color - blackBright: [90, 39], - redBright: [91, 39], - greenBright: [92, 39], - yellowBright: [93, 39], - blueBright: [94, 39], - magentaBright: [95, 39], - cyanBright: [96, 39], - whiteBright: [97, 39] - }, - bgColor: { - bgBlack: [40, 49], - bgRed: [41, 49], - bgGreen: [42, 49], - bgYellow: [43, 49], - bgBlue: [44, 49], - bgMagenta: [45, 49], - bgCyan: [46, 49], - bgWhite: [47, 49], +function wrapConversion(toModel, graph) { + const path = [graph[toModel].parent, toModel]; + let fn = conversions[graph[toModel].parent][toModel]; - // Bright color - bgBlackBright: [100, 49], - bgRedBright: [101, 49], - bgGreenBright: [102, 49], - bgYellowBright: [103, 49], - bgBlueBright: [104, 49], - bgMagentaBright: [105, 49], - bgCyanBright: [106, 49], - bgWhiteBright: [107, 49] - } - }; + let cur = graph[toModel].parent; + while (graph[cur].parent) { + path.unshift(graph[cur].parent); + fn = link(conversions[graph[cur].parent][cur], fn); + cur = graph[cur].parent; + } - // Alias bright black as gray (and grey) - styles.color.gray = styles.color.blackBright; - styles.bgColor.bgGray = styles.bgColor.bgBlackBright; - styles.color.grey = styles.color.blackBright; - styles.bgColor.bgGrey = styles.bgColor.bgBlackBright; + fn.conversion = path; + return fn; +} - for (const [groupName, group] of Object.entries(styles)) { - for (const [styleName, style] of Object.entries(group)) { - styles[styleName] = { - open: `\u001B[${style[0]}m`, - close: `\u001B[${style[1]}m` - }; +module.exports = function (fromModel) { + const graph = deriveBFS(fromModel); + const conversion = {}; - group[styleName] = styles[styleName]; + const models = Object.keys(graph); + for (let len = models.length, i = 0; i < len; i++) { + const toModel = models[i]; + const node = graph[toModel]; - codes.set(style[0], style[1]); + if (node.parent === null) { + // No possible conversion, or this node is the source model. + continue; } - Object.defineProperty(styles, groupName, { - value: group, - enumerable: false - }); + conversion[toModel] = wrapConversion(toModel, graph); } - Object.defineProperty(styles, 'codes', { - value: codes, - enumerable: false - }); - - styles.color.close = '\u001B[39m'; - styles.bgColor.close = '\u001B[49m'; - - setLazyProperty(styles.color, 'ansi', () => makeDynamicStyles(wrapAnsi16, 'ansi16', ansi2ansi, false)); - setLazyProperty(styles.color, 'ansi256', () => makeDynamicStyles(wrapAnsi256, 'ansi256', ansi2ansi, false)); - setLazyProperty(styles.color, 'ansi16m', () => makeDynamicStyles(wrapAnsi16m, 'rgb', rgb2rgb, false)); - setLazyProperty(styles.bgColor, 'ansi', () => makeDynamicStyles(wrapAnsi16, 'ansi16', ansi2ansi, true)); - setLazyProperty(styles.bgColor, 'ansi256', () => makeDynamicStyles(wrapAnsi256, 'ansi256', ansi2ansi, true)); - setLazyProperty(styles.bgColor, 'ansi16m', () => makeDynamicStyles(wrapAnsi16m, 'rgb', rgb2rgb, true)); - - return styles; -} + return conversion; +}; -// Make the export immutable -Object.defineProperty(module, 'exports', { - enumerable: true, - get: assembleStyles -}); -/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(114)(module))) /***/ }), -/* 237 */ +/* 232 */ /***/ (function(module, exports, __webpack_require__) { -const conversions = __webpack_require__(238); -const route = __webpack_require__(239); - -const convert = {}; +"use strict"; -const models = Object.keys(conversions); +const os = __webpack_require__(120); +const tty = __webpack_require__(121); +const hasFlag = __webpack_require__(233); -function wrapRaw(fn) { - const wrappedFn = function (...args) { - const arg0 = args[0]; - if (arg0 === undefined || arg0 === null) { - return arg0; - } +const {env} = process; - if (arg0.length > 1) { - args = arg0; - } +let forceColor; +if (hasFlag('no-color') || + hasFlag('no-colors') || + hasFlag('color=false') || + hasFlag('color=never')) { + forceColor = 0; +} else if (hasFlag('color') || + hasFlag('colors') || + hasFlag('color=true') || + hasFlag('color=always')) { + forceColor = 1; +} - return fn(args); - }; +if ('FORCE_COLOR' in env) { + if (env.FORCE_COLOR === 'true') { + forceColor = 1; + } else if (env.FORCE_COLOR === 'false') { + forceColor = 0; + } else { + forceColor = env.FORCE_COLOR.length === 0 ? 1 : Math.min(parseInt(env.FORCE_COLOR, 10), 3); + } +} - // Preserve .conversion property if there is one - if ('conversion' in fn) { - wrappedFn.conversion = fn.conversion; +function translateLevel(level) { + if (level === 0) { + return false; } - return wrappedFn; + return { + level, + hasBasic: true, + has256: level >= 2, + has16m: level >= 3 + }; } -function wrapRounded(fn) { - const wrappedFn = function (...args) { - const arg0 = args[0]; - - if (arg0 === undefined || arg0 === null) { - return arg0; - } +function supportsColor(haveStream, streamIsTTY) { + if (forceColor === 0) { + return 0; + } - if (arg0.length > 1) { - args = arg0; - } + if (hasFlag('color=16m') || + hasFlag('color=full') || + hasFlag('color=truecolor')) { + return 3; + } - const result = fn(args); + if (hasFlag('color=256')) { + return 2; + } - // We're assuming the result is an array here. - // see notice in conversions.js; don't use box types - // in conversion functions. - if (typeof result === 'object') { - for (let len = result.length, i = 0; i < len; i++) { - result[i] = Math.round(result[i]); - } - } + if (haveStream && !streamIsTTY && forceColor === undefined) { + return 0; + } - return result; - }; + const min = forceColor || 0; - // Preserve .conversion property if there is one - if ('conversion' in fn) { - wrappedFn.conversion = fn.conversion; + if (env.TERM === 'dumb') { + return min; } - return wrappedFn; -} - -models.forEach(fromModel => { - convert[fromModel] = {}; - - Object.defineProperty(convert[fromModel], 'channels', {value: conversions[fromModel].channels}); - Object.defineProperty(convert[fromModel], 'labels', {value: conversions[fromModel].labels}); - - const routes = route(fromModel); - const routeModels = Object.keys(routes); - - routeModels.forEach(toModel => { - const fn = routes[toModel]; - - convert[fromModel][toModel] = wrapRounded(fn); - convert[fromModel][toModel].raw = wrapRaw(fn); - }); -}); + if (process.platform === 'win32') { + // Windows 10 build 10586 is the first Windows release that supports 256 colors. + // Windows 10 build 14931 is the first release that supports 16m/TrueColor. + const osRelease = os.release().split('.'); + if ( + Number(osRelease[0]) >= 10 && + Number(osRelease[2]) >= 10586 + ) { + return Number(osRelease[2]) >= 14931 ? 3 : 2; + } -module.exports = convert; + return 1; + } + if ('CI' in env) { + if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI'].some(sign => sign in env) || env.CI_NAME === 'codeship') { + return 1; + } -/***/ }), -/* 238 */ -/***/ (function(module, exports, __webpack_require__) { + return min; + } -/* MIT license */ -/* eslint-disable no-mixed-operators */ -const cssKeywords = __webpack_require__(117); + if ('TEAMCITY_VERSION' in env) { + return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0; + } -// NOTE: conversions should only return primitive values (i.e. arrays, or -// values that give correct `typeof` results). -// do not use box values types (i.e. Number(), String(), etc.) + if ('GITHUB_ACTIONS' in env) { + return 1; + } -const reverseKeywords = {}; -for (const key of Object.keys(cssKeywords)) { - reverseKeywords[cssKeywords[key]] = key; -} + if (env.COLORTERM === 'truecolor') { + return 3; + } -const convert = { - rgb: {channels: 3, labels: 'rgb'}, - hsl: {channels: 3, labels: 'hsl'}, - hsv: {channels: 3, labels: 'hsv'}, - hwb: {channels: 3, labels: 'hwb'}, - cmyk: {channels: 4, labels: 'cmyk'}, - xyz: {channels: 3, labels: 'xyz'}, - lab: {channels: 3, labels: 'lab'}, - lch: {channels: 3, labels: 'lch'}, - hex: {channels: 1, labels: ['hex']}, - keyword: {channels: 1, labels: ['keyword']}, - ansi16: {channels: 1, labels: ['ansi16']}, - ansi256: {channels: 1, labels: ['ansi256']}, - hcg: {channels: 3, labels: ['h', 'c', 'g']}, - apple: {channels: 3, labels: ['r16', 'g16', 'b16']}, - gray: {channels: 1, labels: ['gray']} -}; + if ('TERM_PROGRAM' in env) { + const version = parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10); -module.exports = convert; + switch (env.TERM_PROGRAM) { + case 'iTerm.app': + return version >= 3 ? 3 : 2; + case 'Apple_Terminal': + return 2; + // No default + } + } -// Hide .channels and .labels properties -for (const model of Object.keys(convert)) { - if (!('channels' in convert[model])) { - throw new Error('missing channels property: ' + model); + if (/-256(color)?$/i.test(env.TERM)) { + return 2; } - if (!('labels' in convert[model])) { - throw new Error('missing channel labels property: ' + model); + if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) { + return 1; } - if (convert[model].labels.length !== convert[model].channels) { - throw new Error('channel and label counts mismatch: ' + model); + if ('COLORTERM' in env) { + return 1; } - const {channels, labels} = convert[model]; - delete convert[model].channels; - delete convert[model].labels; - Object.defineProperty(convert[model], 'channels', {value: channels}); - Object.defineProperty(convert[model], 'labels', {value: labels}); + return min; } -convert.rgb.hsl = function (rgb) { - const r = rgb[0] / 255; - const g = rgb[1] / 255; - const b = rgb[2] / 255; - const min = Math.min(r, g, b); - const max = Math.max(r, g, b); - const delta = max - min; - let h; - let s; +function getSupportLevel(stream) { + const level = supportsColor(stream, stream && stream.isTTY); + return translateLevel(level); +} - if (max === min) { - h = 0; - } else if (r === max) { - h = (g - b) / delta; - } else if (g === max) { - h = 2 + (b - r) / delta; - } else if (b === max) { - h = 4 + (r - g) / delta; - } +module.exports = { + supportsColor: getSupportLevel, + stdout: translateLevel(supportsColor(true, tty.isatty(1))), + stderr: translateLevel(supportsColor(true, tty.isatty(2))) +}; - h = Math.min(h * 60, 360); - if (h < 0) { - h += 360; - } +/***/ }), +/* 233 */ +/***/ (function(module, exports, __webpack_require__) { - const l = (min + max) / 2; +"use strict"; - if (max === min) { - s = 0; - } else if (l <= 0.5) { - s = delta / (max + min); - } else { - s = delta / (2 - max - min); - } - return [h, s * 100, l * 100]; +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); }; -convert.rgb.hsv = function (rgb) { - let rdif; - let gdif; - let bdif; - let h; - let s; - const r = rgb[0] / 255; - const g = rgb[1] / 255; - const b = rgb[2] / 255; - const v = Math.max(r, g, b); - const diff = v - Math.min(r, g, b); - const diffc = function (c) { - return (v - c) / 6 / diff + 1 / 2; - }; +/***/ }), +/* 234 */ +/***/ (function(module, exports, __webpack_require__) { - if (diff === 0) { - h = 0; - s = 0; - } else { - s = diff / v; - rdif = diffc(r); - gdif = diffc(g); - bdif = diffc(b); +"use strict"; - if (r === v) { - h = bdif - gdif; - } else if (g === v) { - h = (1 / 3) + rdif - bdif; - } else if (b === v) { - h = (2 / 3) + gdif - rdif; - } - if (h < 0) { - h += 1; - } else if (h > 1) { - h -= 1; - } +const stringReplaceAll = (string, substring, replacer) => { + let index = string.indexOf(substring); + if (index === -1) { + return string; } - return [ - h * 360, - s * 100, - v * 100 - ]; -}; + const substringLength = substring.length; + let endIndex = 0; + let returnValue = ''; + do { + returnValue += string.substr(endIndex, index - endIndex) + substring + replacer; + endIndex = index + substringLength; + index = string.indexOf(substring, endIndex); + } while (index !== -1); -convert.rgb.hwb = function (rgb) { - const r = rgb[0]; - const g = rgb[1]; - let b = rgb[2]; - const h = convert.rgb.hsl(rgb)[0]; - const w = 1 / 255 * Math.min(r, Math.min(g, b)); + returnValue += string.substr(endIndex); + return returnValue; +}; - b = 1 - 1 / 255 * Math.max(r, Math.max(g, b)); +const stringEncaseCRLFWithFirstIndex = (string, prefix, postfix, index) => { + let endIndex = 0; + let returnValue = ''; + do { + const gotCR = string[index - 1] === '\r'; + returnValue += string.substr(endIndex, (gotCR ? index - 1 : index) - endIndex) + prefix + (gotCR ? '\r\n' : '\n') + postfix; + endIndex = index + 1; + index = string.indexOf('\n', endIndex); + } while (index !== -1); - return [h, w * 100, b * 100]; + returnValue += string.substr(endIndex); + return returnValue; }; -convert.rgb.cmyk = function (rgb) { - const r = rgb[0] / 255; - const g = rgb[1] / 255; - const b = rgb[2] / 255; +module.exports = { + stringReplaceAll, + stringEncaseCRLFWithFirstIndex +}; - const k = Math.min(1 - r, 1 - g, 1 - b); - const c = (1 - r - k) / (1 - k) || 0; - const m = (1 - g - k) / (1 - k) || 0; - const y = (1 - b - k) / (1 - k) || 0; - return [c * 100, m * 100, y * 100, k * 100]; -}; +/***/ }), +/* 235 */ +/***/ (function(module, exports, __webpack_require__) { -function comparativeDistance(x, y) { - /* - See https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance - */ - return ( - ((x[0] - y[0]) ** 2) + - ((x[1] - y[1]) ** 2) + - ((x[2] - y[2]) ** 2) - ); -} +"use strict"; -convert.rgb.keyword = function (rgb) { - const reversed = reverseKeywords[rgb]; - if (reversed) { - return reversed; - } +const TEMPLATE_REGEX = /(?:\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi; +const STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g; +const STRING_REGEX = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$/; +const ESCAPE_REGEX = /\\(u(?:[a-f\d]{4}|{[a-f\d]{1,6}})|x[a-f\d]{2}|.)|([^\\])/gi; - let currentClosestDistance = Infinity; - let currentClosestKeyword; +const ESCAPES = new Map([ + ['n', '\n'], + ['r', '\r'], + ['t', '\t'], + ['b', '\b'], + ['f', '\f'], + ['v', '\v'], + ['0', '\0'], + ['\\', '\\'], + ['e', '\u001B'], + ['a', '\u0007'] +]); - for (const keyword of Object.keys(cssKeywords)) { - const value = cssKeywords[keyword]; +function unescape(c) { + const u = c[0] === 'u'; + const bracket = c[1] === '{'; - // Compute comparative distance - const distance = comparativeDistance(rgb, value); + if ((u && !bracket && c.length === 5) || (c[0] === 'x' && c.length === 3)) { + return String.fromCharCode(parseInt(c.slice(1), 16)); + } - // Check if its less, if so set as closest - if (distance < currentClosestDistance) { - currentClosestDistance = distance; - currentClosestKeyword = keyword; - } + if (u && bracket) { + return String.fromCodePoint(parseInt(c.slice(2, -1), 16)); } - return currentClosestKeyword; -}; + return ESCAPES.get(c) || c; +} -convert.keyword.rgb = function (keyword) { - return cssKeywords[keyword]; -}; +function parseArguments(name, arguments_) { + const results = []; + const chunks = arguments_.trim().split(/\s*,\s*/g); + let matches; -convert.rgb.xyz = function (rgb) { - let r = rgb[0] / 255; - let g = rgb[1] / 255; - let b = rgb[2] / 255; + for (const chunk of chunks) { + const number = Number(chunk); + if (!Number.isNaN(number)) { + results.push(number); + } else if ((matches = chunk.match(STRING_REGEX))) { + results.push(matches[2].replace(ESCAPE_REGEX, (m, escape, character) => escape ? unescape(escape) : character)); + } else { + throw new Error(`Invalid Chalk template style argument: ${chunk} (in style '${name}')`); + } + } - // Assume sRGB - r = r > 0.04045 ? (((r + 0.055) / 1.055) ** 2.4) : (r / 12.92); - g = g > 0.04045 ? (((g + 0.055) / 1.055) ** 2.4) : (g / 12.92); - b = b > 0.04045 ? (((b + 0.055) / 1.055) ** 2.4) : (b / 12.92); + return results; +} - const x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805); - const y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722); - const z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505); +function parseStyle(style) { + STYLE_REGEX.lastIndex = 0; - return [x * 100, y * 100, z * 100]; -}; + const results = []; + let matches; -convert.rgb.lab = function (rgb) { - const xyz = convert.rgb.xyz(rgb); - let x = xyz[0]; - let y = xyz[1]; - let z = xyz[2]; + while ((matches = STYLE_REGEX.exec(style)) !== null) { + const name = matches[1]; - x /= 95.047; - y /= 100; - z /= 108.883; + if (matches[2]) { + const args = parseArguments(name, matches[2]); + results.push([name].concat(args)); + } else { + results.push([name]); + } + } - x = x > 0.008856 ? (x ** (1 / 3)) : (7.787 * x) + (16 / 116); - y = y > 0.008856 ? (y ** (1 / 3)) : (7.787 * y) + (16 / 116); - z = z > 0.008856 ? (z ** (1 / 3)) : (7.787 * z) + (16 / 116); + return results; +} - const l = (116 * y) - 16; - const a = 500 * (x - y); - const b = 200 * (y - z); +function buildStyle(chalk, styles) { + const enabled = {}; - return [l, a, b]; -}; + for (const layer of styles) { + for (const style of layer.styles) { + enabled[style[0]] = layer.inverse ? null : style.slice(1); + } + } -convert.hsl.rgb = function (hsl) { - const h = hsl[0] / 360; - const s = hsl[1] / 100; - const l = hsl[2] / 100; - let t2; - let t3; - let val; + let current = chalk; + for (const [styleName, styles] of Object.entries(enabled)) { + if (!Array.isArray(styles)) { + continue; + } - if (s === 0) { - val = l * 255; - return [val, val, val]; - } + if (!(styleName in current)) { + throw new Error(`Unknown Chalk style: ${styleName}`); + } - if (l < 0.5) { - t2 = l * (1 + s); - } else { - t2 = l + s - l * s; + current = styles.length > 0 ? current[styleName](...styles) : current[styleName]; } - const t1 = 2 * l - t2; + return current; +} - const rgb = [0, 0, 0]; - for (let i = 0; i < 3; i++) { - t3 = h + 1 / 3 * -(i - 1); - if (t3 < 0) { - t3++; - } +module.exports = (chalk, temporary) => { + const styles = []; + const chunks = []; + let chunk = []; - if (t3 > 1) { - t3--; - } + // eslint-disable-next-line max-params + temporary.replace(TEMPLATE_REGEX, (m, escapeCharacter, inverse, style, close, character) => { + if (escapeCharacter) { + chunk.push(unescape(escapeCharacter)); + } else if (style) { + const string = chunk.join(''); + chunk = []; + chunks.push(styles.length === 0 ? string : buildStyle(chalk, styles)(string)); + styles.push({inverse, styles: parseStyle(style)}); + } else if (close) { + if (styles.length === 0) { + throw new Error('Found extraneous } in Chalk template literal'); + } - if (6 * t3 < 1) { - val = t1 + (t2 - t1) * 6 * t3; - } else if (2 * t3 < 1) { - val = t2; - } else if (3 * t3 < 2) { - val = t1 + (t2 - t1) * (2 / 3 - t3) * 6; + chunks.push(buildStyle(chalk, styles)(chunk.join(''))); + chunk = []; + styles.pop(); } else { - val = t1; + chunk.push(character); } + }); - rgb[i] = val * 255; + chunks.push(chunk.join('')); + + if (styles.length > 0) { + const errMessage = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? '' : 's'} (\`}\`)`; + throw new Error(errMessage); } - return rgb; + return chunks.join(''); }; -convert.hsl.hsv = function (hsl) { - const h = hsl[0]; - let s = hsl[1] / 100; - let l = hsl[2] / 100; - let smin = s; - const lmin = Math.max(l, 0.01); - l *= 2; - s *= (l <= 1) ? l : 2 - l; - smin *= lmin <= 1 ? lmin : 2 - lmin; - const v = (l + s) / 2; - const sv = l === 0 ? (2 * smin) / (lmin + smin) : (2 * s) / (l + s); +/***/ }), +/* 236 */ +/***/ (function(module, exports, __webpack_require__) { - return [h, sv * 100, v * 100]; -}; +"use strict"; -convert.hsv.rgb = function (hsv) { - const h = hsv[0] / 60; - const s = hsv[1] / 100; - let v = hsv[2] / 100; - const hi = Math.floor(h) % 6; +const path = __webpack_require__(4); +const childProcess = __webpack_require__(237); +const crossSpawn = __webpack_require__(238); +const stripFinalNewline = __webpack_require__(251); +const npmRunPath = __webpack_require__(252); +const onetime = __webpack_require__(253); +const makeError = __webpack_require__(255); +const normalizeStdio = __webpack_require__(260); +const {spawnedKill, spawnedCancel, setupTimeout, setExitHandler} = __webpack_require__(261); +const {handleInput, getSpawnedResult, makeAllStream, validateInputSync} = __webpack_require__(262); +const {mergePromise, getSpawnedPromise} = __webpack_require__(269); +const {joinCommand, parseCommand} = __webpack_require__(270); - const f = h - Math.floor(h); - const p = 255 * v * (1 - s); - const q = 255 * v * (1 - (s * f)); - const t = 255 * v * (1 - (s * (1 - f))); - v *= 255; +const DEFAULT_MAX_BUFFER = 1000 * 1000 * 100; - switch (hi) { - case 0: - return [v, t, p]; - case 1: - return [q, v, p]; - case 2: - return [p, v, t]; - case 3: - return [p, q, v]; - case 4: - return [t, p, v]; - case 5: - return [v, p, q]; +const getEnv = ({env: envOption, extendEnv, preferLocal, localDir, execPath}) => { + const env = extendEnv ? {...process.env, ...envOption} : envOption; + + if (preferLocal) { + return npmRunPath.env({env, cwd: localDir, execPath}); } + + return env; }; -convert.hsv.hsl = function (hsv) { - const h = hsv[0]; - const s = hsv[1] / 100; - const v = hsv[2] / 100; - const vmin = Math.max(v, 0.01); - let sl; - let l; +const handleArgs = (file, args, options = {}) => { + const parsed = crossSpawn._parse(file, args, options); + file = parsed.command; + args = parsed.args; + options = parsed.options; - l = (2 - s) * v; - const lmin = (2 - s) * vmin; - sl = s * vmin; - sl /= (lmin <= 1) ? lmin : 2 - lmin; - sl = sl || 0; - l /= 2; + options = { + maxBuffer: DEFAULT_MAX_BUFFER, + buffer: true, + stripFinalNewline: true, + extendEnv: true, + preferLocal: false, + localDir: options.cwd || process.cwd(), + execPath: process.execPath, + encoding: 'utf8', + reject: true, + cleanup: true, + all: false, + windowsHide: true, + ...options + }; - return [h, sl * 100, l * 100]; -}; + options.env = getEnv(options); -// http://dev.w3.org/csswg/css-color/#hwb-to-rgb -convert.hwb.rgb = function (hwb) { - const h = hwb[0] / 360; - let wh = hwb[1] / 100; - let bl = hwb[2] / 100; - const ratio = wh + bl; - let f; + options.stdio = normalizeStdio(options); - // Wh + bl cant be > 1 - if (ratio > 1) { - wh /= ratio; - bl /= ratio; + if (process.platform === 'win32' && path.basename(file, '.exe') === 'cmd') { + // #116 + args.unshift('/q'); } - const i = Math.floor(6 * h); - const v = 1 - bl; - f = 6 * h - i; + return {file, args, options, parsed}; +}; - if ((i & 0x01) !== 0) { - f = 1 - f; +const handleOutput = (options, value, error) => { + if (typeof value !== 'string' && !Buffer.isBuffer(value)) { + // When `execa.sync()` errors, we normalize it to '' to mimic `execa()` + return error === undefined ? undefined : ''; } - const n = wh + f * (v - wh); // Linear interpolation - - let r; - let g; - let b; - /* eslint-disable max-statements-per-line,no-multi-spaces */ - switch (i) { - default: - case 6: - case 0: r = v; g = n; b = wh; break; - case 1: r = n; g = v; b = wh; break; - case 2: r = wh; g = v; b = n; break; - case 3: r = wh; g = n; b = v; break; - case 4: r = n; g = wh; b = v; break; - case 5: r = v; g = wh; b = n; break; + if (options.stripFinalNewline) { + return stripFinalNewline(value); } - /* eslint-enable max-statements-per-line,no-multi-spaces */ - return [r * 255, g * 255, b * 255]; + return value; }; -convert.cmyk.rgb = function (cmyk) { - const c = cmyk[0] / 100; - const m = cmyk[1] / 100; - const y = cmyk[2] / 100; - const k = cmyk[3] / 100; +const execa = (file, args, options) => { + const parsed = handleArgs(file, args, options); + const command = joinCommand(file, args); - const r = 1 - Math.min(1, c * (1 - k) + k); - const g = 1 - Math.min(1, m * (1 - k) + k); - const b = 1 - Math.min(1, y * (1 - k) + k); + let spawned; + try { + spawned = childProcess.spawn(parsed.file, parsed.args, parsed.options); + } catch (error) { + // Ensure the returned error is always both a promise and a child process + const dummySpawned = new childProcess.ChildProcess(); + const errorPromise = Promise.reject(makeError({ + error, + stdout: '', + stderr: '', + all: '', + command, + parsed, + timedOut: false, + isCanceled: false, + killed: false + })); + return mergePromise(dummySpawned, errorPromise); + } - return [r * 255, g * 255, b * 255]; -}; + const spawnedPromise = getSpawnedPromise(spawned); + const timedPromise = setupTimeout(spawned, parsed.options, spawnedPromise); + const processDone = setExitHandler(spawned, parsed.options, timedPromise); -convert.xyz.rgb = function (xyz) { - const x = xyz[0] / 100; - const y = xyz[1] / 100; - const z = xyz[2] / 100; - let r; - let g; - let b; + const context = {isCanceled: false}; - r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986); - g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415); - b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570); + spawned.kill = spawnedKill.bind(null, spawned.kill.bind(spawned)); + spawned.cancel = spawnedCancel.bind(null, spawned, context); - // Assume sRGB - r = r > 0.0031308 - ? ((1.055 * (r ** (1.0 / 2.4))) - 0.055) - : r * 12.92; + const handlePromise = async () => { + const [{error, exitCode, signal, timedOut}, stdoutResult, stderrResult, allResult] = await getSpawnedResult(spawned, parsed.options, processDone); + const stdout = handleOutput(parsed.options, stdoutResult); + const stderr = handleOutput(parsed.options, stderrResult); + const all = handleOutput(parsed.options, allResult); - g = g > 0.0031308 - ? ((1.055 * (g ** (1.0 / 2.4))) - 0.055) - : g * 12.92; + if (error || exitCode !== 0 || signal !== null) { + const returnedError = makeError({ + error, + exitCode, + signal, + stdout, + stderr, + all, + command, + parsed, + timedOut, + isCanceled: context.isCanceled, + killed: spawned.killed + }); - b = b > 0.0031308 - ? ((1.055 * (b ** (1.0 / 2.4))) - 0.055) - : b * 12.92; + if (!parsed.options.reject) { + return returnedError; + } - r = Math.min(Math.max(0, r), 1); - g = Math.min(Math.max(0, g), 1); - b = Math.min(Math.max(0, b), 1); + throw returnedError; + } - return [r * 255, g * 255, b * 255]; -}; + return { + command, + exitCode: 0, + stdout, + stderr, + all, + failed: false, + timedOut: false, + isCanceled: false, + killed: false + }; + }; -convert.xyz.lab = function (xyz) { - let x = xyz[0]; - let y = xyz[1]; - let z = xyz[2]; + const handlePromiseOnce = onetime(handlePromise); - x /= 95.047; - y /= 100; - z /= 108.883; + crossSpawn._enoent.hookChildProcess(spawned, parsed.parsed); - x = x > 0.008856 ? (x ** (1 / 3)) : (7.787 * x) + (16 / 116); - y = y > 0.008856 ? (y ** (1 / 3)) : (7.787 * y) + (16 / 116); - z = z > 0.008856 ? (z ** (1 / 3)) : (7.787 * z) + (16 / 116); + handleInput(spawned, parsed.options.input); - const l = (116 * y) - 16; - const a = 500 * (x - y); - const b = 200 * (y - z); + spawned.all = makeAllStream(spawned, parsed.options); - return [l, a, b]; + return mergePromise(spawned, handlePromiseOnce); }; -convert.lab.xyz = function (lab) { - const l = lab[0]; - const a = lab[1]; - const b = lab[2]; - let x; - let y; - let z; +module.exports = execa; - y = (l + 16) / 116; - x = a / 500 + y; - z = y - b / 200; +module.exports.sync = (file, args, options) => { + const parsed = handleArgs(file, args, options); + const command = joinCommand(file, args); - const y2 = y ** 3; - const x2 = x ** 3; - const z2 = z ** 3; - y = y2 > 0.008856 ? y2 : (y - 16 / 116) / 7.787; - x = x2 > 0.008856 ? x2 : (x - 16 / 116) / 7.787; - z = z2 > 0.008856 ? z2 : (z - 16 / 116) / 7.787; + validateInputSync(parsed.options); - x *= 95.047; - y *= 100; - z *= 108.883; + let result; + try { + result = childProcess.spawnSync(parsed.file, parsed.args, parsed.options); + } catch (error) { + throw makeError({ + error, + stdout: '', + stderr: '', + all: '', + command, + parsed, + timedOut: false, + isCanceled: false, + killed: false + }); + } - return [x, y, z]; -}; + const stdout = handleOutput(parsed.options, result.stdout, result.error); + const stderr = handleOutput(parsed.options, result.stderr, result.error); -convert.lab.lch = function (lab) { - const l = lab[0]; - const a = lab[1]; - const b = lab[2]; - let h; + if (result.error || result.status !== 0 || result.signal !== null) { + const error = makeError({ + stdout, + stderr, + error: result.error, + signal: result.signal, + exitCode: result.status, + command, + parsed, + timedOut: result.error && result.error.code === 'ETIMEDOUT', + isCanceled: false, + killed: result.signal !== null + }); - const hr = Math.atan2(b, a); - h = hr * 360 / 2 / Math.PI; + if (!parsed.options.reject) { + return error; + } - if (h < 0) { - h += 360; + throw error; } - const c = Math.sqrt(a * a + b * b); - - return [l, c, h]; + return { + command, + exitCode: 0, + stdout, + stderr, + failed: false, + timedOut: false, + isCanceled: false, + killed: false + }; }; -convert.lch.lab = function (lch) { - const l = lch[0]; - const c = lch[1]; - const h = lch[2]; - - const hr = h / 360 * 2 * Math.PI; - const a = c * Math.cos(hr); - const b = c * Math.sin(hr); - - return [l, a, b]; +module.exports.command = (command, options) => { + const [file, ...args] = parseCommand(command); + return execa(file, args, options); }; -convert.rgb.ansi16 = function (args, saturation = null) { - const [r, g, b] = args; - let value = saturation === null ? convert.rgb.hsv(args)[2] : saturation; // Hsv -> ansi16 optimization - - value = Math.round(value / 50); +module.exports.commandSync = (command, options) => { + const [file, ...args] = parseCommand(command); + return execa.sync(file, args, options); +}; - if (value === 0) { - return 30; +module.exports.node = (scriptPath, args, options = {}) => { + if (args && !Array.isArray(args) && typeof args === 'object') { + options = args; + args = []; } - let ansi = 30 - + ((Math.round(b / 255) << 2) - | (Math.round(g / 255) << 1) - | Math.round(r / 255)); + const stdio = normalizeStdio.node(options); - if (value === 2) { - ansi += 60; - } + const {nodePath = process.execPath, nodeOptions = process.execArgv} = options; - return ansi; + return execa( + nodePath, + [ + ...nodeOptions, + scriptPath, + ...(Array.isArray(args) ? args : []) + ], + { + ...options, + stdin: undefined, + stdout: undefined, + stderr: undefined, + stdio, + shell: false + } + ); }; -convert.hsv.ansi16 = function (args) { - // Optimization here; we already know the value and don't need to get - // it converted for us. - return convert.rgb.ansi16(convert.hsv.rgb(args), args[2]); -}; -convert.rgb.ansi256 = function (args) { - const r = args[0]; - const g = args[1]; - const b = args[2]; +/***/ }), +/* 237 */ +/***/ (function(module, exports) { - // We use the extended greyscale palette here, with the exception of - // black and white. normal palette only has 4 greyscale shades. - if (r === g && g === b) { - if (r < 8) { - return 16; - } +module.exports = require("child_process"); - if (r > 248) { - return 231; - } +/***/ }), +/* 238 */ +/***/ (function(module, exports, __webpack_require__) { - return Math.round(((r - 8) / 247) * 24) + 232; - } +"use strict"; - const ansi = 16 - + (36 * Math.round(r / 255 * 5)) - + (6 * Math.round(g / 255 * 5)) - + Math.round(b / 255 * 5); - return ansi; -}; +const cp = __webpack_require__(237); +const parse = __webpack_require__(239); +const enoent = __webpack_require__(250); -convert.ansi16.rgb = function (args) { - let color = args % 10; +function spawn(command, args, options) { + // Parse the arguments + const parsed = parse(command, args, options); - // Handle greyscale - if (color === 0 || color === 7) { - if (args > 50) { - color += 3.5; - } + // Spawn the child process + const spawned = cp.spawn(parsed.command, parsed.args, parsed.options); - color = color / 10.5 * 255; + // Hook into child process "exit" event to emit an error if the command + // does not exists, see: https://github.com/IndigoUnited/node-cross-spawn/issues/16 + enoent.hookChildProcess(spawned, parsed); - return [color, color, color]; - } + return spawned; +} - const mult = (~~(args > 50) + 1) * 0.5; - const r = ((color & 1) * mult) * 255; - const g = (((color >> 1) & 1) * mult) * 255; - const b = (((color >> 2) & 1) * mult) * 255; +function spawnSync(command, args, options) { + // Parse the arguments + const parsed = parse(command, args, options); - return [r, g, b]; -}; + // Spawn the child process + const result = cp.spawnSync(parsed.command, parsed.args, parsed.options); -convert.ansi256.rgb = function (args) { - // Handle greyscale - if (args >= 232) { - const c = (args - 232) * 10 + 8; - return [c, c, c]; - } + // Analyze if the command does not exist, see: https://github.com/IndigoUnited/node-cross-spawn/issues/16 + result.error = result.error || enoent.verifyENOENTSync(result.status, parsed); - args -= 16; + return result; +} - let rem; - const r = Math.floor(args / 36) / 5 * 255; - const g = Math.floor((rem = args % 36) / 6) / 5 * 255; - const b = (rem % 6) / 5 * 255; +module.exports = spawn; +module.exports.spawn = spawn; +module.exports.sync = spawnSync; - return [r, g, b]; -}; +module.exports._parse = parse; +module.exports._enoent = enoent; -convert.rgb.hex = function (args) { - const integer = ((Math.round(args[0]) & 0xFF) << 16) - + ((Math.round(args[1]) & 0xFF) << 8) - + (Math.round(args[2]) & 0xFF); - const string = integer.toString(16).toUpperCase(); - return '000000'.substring(string.length) + string; -}; +/***/ }), +/* 239 */ +/***/ (function(module, exports, __webpack_require__) { -convert.hex.rgb = function (args) { - const match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i); - if (!match) { - return [0, 0, 0]; - } +"use strict"; - let colorString = match[0]; - if (match[0].length === 3) { - colorString = colorString.split('').map(char => { - return char + char; - }).join(''); - } +const path = __webpack_require__(4); +const resolveCommand = __webpack_require__(240); +const escape = __webpack_require__(246); +const readShebang = __webpack_require__(247); - const integer = parseInt(colorString, 16); - const r = (integer >> 16) & 0xFF; - const g = (integer >> 8) & 0xFF; - const b = integer & 0xFF; +const isWin = process.platform === 'win32'; +const isExecutableRegExp = /\.(?:com|exe)$/i; +const isCmdShimRegExp = /node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i; - return [r, g, b]; -}; +function detectShebang(parsed) { + parsed.file = resolveCommand(parsed); -convert.rgb.hcg = function (rgb) { - const r = rgb[0] / 255; - const g = rgb[1] / 255; - const b = rgb[2] / 255; - const max = Math.max(Math.max(r, g), b); - const min = Math.min(Math.min(r, g), b); - const chroma = (max - min); - let grayscale; - let hue; + const shebang = parsed.file && readShebang(parsed.file); - if (chroma < 1) { - grayscale = min / (1 - chroma); - } else { - grayscale = 0; - } + if (shebang) { + parsed.args.unshift(parsed.file); + parsed.command = shebang; - if (chroma <= 0) { - hue = 0; - } else - if (max === r) { - hue = ((g - b) / chroma) % 6; - } else - if (max === g) { - hue = 2 + (b - r) / chroma; - } else { - hue = 4 + (r - g) / chroma; - } + return resolveCommand(parsed); + } - hue /= 6; - hue %= 1; + return parsed.file; +} - return [hue * 360, chroma * 100, grayscale * 100]; -}; +function parseNonShell(parsed) { + if (!isWin) { + return parsed; + } -convert.hsl.hcg = function (hsl) { - const s = hsl[1] / 100; - const l = hsl[2] / 100; + // Detect & add support for shebangs + const commandFile = detectShebang(parsed); - const c = l < 0.5 ? (2.0 * s * l) : (2.0 * s * (1.0 - l)); + // We don't need a shell if the command filename is an executable + const needsShell = !isExecutableRegExp.test(commandFile); - let f = 0; - if (c < 1.0) { - f = (l - 0.5 * c) / (1.0 - c); - } + // If a shell is required, use cmd.exe and take care of escaping everything correctly + // Note that `forceShell` is an hidden option used only in tests + if (parsed.options.forceShell || needsShell) { + // Need to double escape meta chars if the command is a cmd-shim located in `node_modules/.bin/` + // The cmd-shim simply calls execute the package bin file with NodeJS, proxying any argument + // Because the escape of metachars with ^ gets interpreted when the cmd.exe is first called, + // we need to double escape them + const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile); - return [hsl[0], c * 100, f * 100]; -}; + // Normalize posix paths into OS compatible paths (e.g.: foo/bar -> foo\bar) + // This is necessary otherwise it will always fail with ENOENT in those cases + parsed.command = path.normalize(parsed.command); -convert.hsv.hcg = function (hsv) { - const s = hsv[1] / 100; - const v = hsv[2] / 100; - - const c = s * v; - let f = 0; + // Escape command & arguments + parsed.command = escape.command(parsed.command); + parsed.args = parsed.args.map((arg) => escape.argument(arg, needsDoubleEscapeMetaChars)); - if (c < 1.0) { - f = (v - c) / (1 - c); - } + const shellCommand = [parsed.command].concat(parsed.args).join(' '); - return [hsv[0], c * 100, f * 100]; -}; + parsed.args = ['/d', '/s', '/c', `"${shellCommand}"`]; + parsed.command = process.env.comspec || 'cmd.exe'; + parsed.options.windowsVerbatimArguments = true; // Tell node's spawn that the arguments are already escaped + } -convert.hcg.rgb = function (hcg) { - const h = hcg[0] / 360; - const c = hcg[1] / 100; - const g = hcg[2] / 100; + return parsed; +} - if (c === 0.0) { - return [g * 255, g * 255, g * 255]; - } +function parse(command, args, options) { + // Normalize arguments, similar to nodejs + if (args && !Array.isArray(args)) { + options = args; + args = null; + } - const pure = [0, 0, 0]; - const hi = (h % 1) * 6; - const v = hi % 1; - const w = 1 - v; - let mg = 0; + args = args ? args.slice(0) : []; // Clone array to avoid changing the original + options = Object.assign({}, options); // Clone object to avoid changing the original - /* eslint-disable max-statements-per-line */ - switch (Math.floor(hi)) { - case 0: - pure[0] = 1; pure[1] = v; pure[2] = 0; break; - case 1: - pure[0] = w; pure[1] = 1; pure[2] = 0; break; - case 2: - pure[0] = 0; pure[1] = 1; pure[2] = v; break; - case 3: - pure[0] = 0; pure[1] = w; pure[2] = 1; break; - case 4: - pure[0] = v; pure[1] = 0; pure[2] = 1; break; - default: - pure[0] = 1; pure[1] = 0; pure[2] = w; - } - /* eslint-enable max-statements-per-line */ + // Build our parsed object + const parsed = { + command, + args, + options, + file: undefined, + original: { + command, + args, + }, + }; - mg = (1.0 - c) * g; + // Delegate further parsing to shell or non-shell + return options.shell ? parsed : parseNonShell(parsed); +} - return [ - (c * pure[0] + mg) * 255, - (c * pure[1] + mg) * 255, - (c * pure[2] + mg) * 255 - ]; -}; +module.exports = parse; -convert.hcg.hsv = function (hcg) { - const c = hcg[1] / 100; - const g = hcg[2] / 100; - const v = c + g * (1.0 - c); - let f = 0; +/***/ }), +/* 240 */ +/***/ (function(module, exports, __webpack_require__) { - if (v > 0.0) { - f = c / v; - } +"use strict"; - return [hcg[0], f * 100, v * 100]; -}; -convert.hcg.hsl = function (hcg) { - const c = hcg[1] / 100; - const g = hcg[2] / 100; +const path = __webpack_require__(4); +const which = __webpack_require__(241); +const pathKey = __webpack_require__(245)(); - const l = g * (1.0 - c) + 0.5 * c; - let s = 0; +function resolveCommandAttempt(parsed, withoutPathExt) { + const cwd = process.cwd(); + const hasCustomCwd = parsed.options.cwd != null; + // Worker threads do not have process.chdir() + const shouldSwitchCwd = hasCustomCwd && process.chdir !== undefined; - if (l > 0.0 && l < 0.5) { - s = c / (2 * l); - } else - if (l >= 0.5 && l < 1.0) { - s = c / (2 * (1 - l)); - } + // If a custom `cwd` was specified, we need to change the process cwd + // because `which` will do stat calls but does not support a custom cwd + if (shouldSwitchCwd) { + try { + process.chdir(parsed.options.cwd); + } catch (err) { + /* Empty */ + } + } - return [hcg[0], s * 100, l * 100]; -}; + let resolved; -convert.hcg.hwb = function (hcg) { - const c = hcg[1] / 100; - const g = hcg[2] / 100; - const v = c + g * (1.0 - c); - return [hcg[0], (v - c) * 100, (1 - v) * 100]; -}; + try { + resolved = which.sync(parsed.command, { + path: (parsed.options.env || process.env)[pathKey], + pathExt: withoutPathExt ? path.delimiter : undefined, + }); + } catch (e) { + /* Empty */ + } finally { + if (shouldSwitchCwd) { + process.chdir(cwd); + } + } -convert.hwb.hcg = function (hwb) { - const w = hwb[1] / 100; - const b = hwb[2] / 100; - const v = 1 - b; - const c = v - w; - let g = 0; + // If we successfully resolved, ensure that an absolute path is returned + // Note that when a custom `cwd` was used, we need to resolve to an absolute path based on it + if (resolved) { + resolved = path.resolve(hasCustomCwd ? parsed.options.cwd : '', resolved); + } - if (c < 1) { - g = (v - c) / (1 - c); - } + return resolved; +} - return [hwb[0], c * 100, g * 100]; -}; +function resolveCommand(parsed) { + return resolveCommandAttempt(parsed) || resolveCommandAttempt(parsed, true); +} -convert.apple.rgb = function (apple) { - return [(apple[0] / 65535) * 255, (apple[1] / 65535) * 255, (apple[2] / 65535) * 255]; -}; +module.exports = resolveCommand; -convert.rgb.apple = function (rgb) { - return [(rgb[0] / 255) * 65535, (rgb[1] / 255) * 65535, (rgb[2] / 255) * 65535]; -}; -convert.gray.rgb = function (args) { - return [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255]; -}; +/***/ }), +/* 241 */ +/***/ (function(module, exports, __webpack_require__) { -convert.gray.hsl = function (args) { - return [0, 0, args[0]]; -}; +const isWindows = process.platform === 'win32' || + process.env.OSTYPE === 'cygwin' || + process.env.OSTYPE === 'msys' -convert.gray.hsv = convert.gray.hsl; +const path = __webpack_require__(4) +const COLON = isWindows ? ';' : ':' +const isexe = __webpack_require__(242) -convert.gray.hwb = function (gray) { - return [0, 100, gray[0]]; -}; +const getNotFoundError = (cmd) => + Object.assign(new Error(`not found: ${cmd}`), { code: 'ENOENT' }) -convert.gray.cmyk = function (gray) { - return [0, 0, 0, gray[0]]; -}; +const getPathInfo = (cmd, opt) => { + const colon = opt.colon || COLON -convert.gray.lab = function (gray) { - return [gray[0], 0, 0]; -}; + // If it has a slash, then we don't bother searching the pathenv. + // just check the file itself, and that's it. + const pathEnv = cmd.match(/\//) || isWindows && cmd.match(/\\/) ? [''] + : ( + [ + // windows always checks the cwd first + ...(isWindows ? [process.cwd()] : []), + ...(opt.path || process.env.PATH || + /* istanbul ignore next: very unusual */ '').split(colon), + ] + ) + const pathExtExe = isWindows + ? opt.pathExt || process.env.PATHEXT || '.EXE;.CMD;.BAT;.COM' + : '' + const pathExt = isWindows ? pathExtExe.split(colon) : [''] -convert.gray.hex = function (gray) { - const val = Math.round(gray[0] / 100 * 255) & 0xFF; - const integer = (val << 16) + (val << 8) + val; + if (isWindows) { + if (cmd.indexOf('.') !== -1 && pathExt[0] !== '') + pathExt.unshift('') + } - const string = integer.toString(16).toUpperCase(); - return '000000'.substring(string.length) + string; -}; + return { + pathEnv, + pathExt, + pathExtExe, + } +} -convert.rgb.gray = function (rgb) { - const val = (rgb[0] + rgb[1] + rgb[2]) / 3; - return [val / 255 * 100]; -}; +const which = (cmd, opt, cb) => { + if (typeof opt === 'function') { + cb = opt + opt = {} + } + if (!opt) + opt = {} + const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt) + const found = [] -/***/ }), -/* 239 */ -/***/ (function(module, exports, __webpack_require__) { + const step = i => new Promise((resolve, reject) => { + if (i === pathEnv.length) + return opt.all && found.length ? resolve(found) + : reject(getNotFoundError(cmd)) -const conversions = __webpack_require__(238); + const ppRaw = pathEnv[i] + const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw -/* - This function routes a model to all other models. + const pCmd = path.join(pathPart, cmd) + const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd + : pCmd - all functions that are routed have a property `.conversion` attached - to the returned synthetic function. This property is an array - of strings, each with the steps in between the 'from' and 'to' - color models (inclusive). + resolve(subStep(p, i, 0)) + }) - conversions that are not possible simply are not included. -*/ + const subStep = (p, i, ii) => new Promise((resolve, reject) => { + if (ii === pathExt.length) + return resolve(step(i + 1)) + const ext = pathExt[ii] + isexe(p + ext, { pathExt: pathExtExe }, (er, is) => { + if (!er && is) { + if (opt.all) + found.push(p + ext) + else + return resolve(p + ext) + } + return resolve(subStep(p, i, ii + 1)) + }) + }) -function buildGraph() { - const graph = {}; - // https://jsperf.com/object-keys-vs-for-in-with-closure/3 - const models = Object.keys(conversions); + return cb ? step(0).then(res => cb(null, res), cb) : step(0) +} - for (let len = models.length, i = 0; i < len; i++) { - graph[models[i]] = { - // http://jsperf.com/1-vs-infinity - // micro-opt, but this is simple. - distance: -1, - parent: null - }; - } +const whichSync = (cmd, opt) => { + opt = opt || {} - return graph; -} + const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt) + const found = [] -// https://en.wikipedia.org/wiki/Breadth-first_search -function deriveBFS(fromModel) { - const graph = buildGraph(); - const queue = [fromModel]; // Unshift -> queue -> pop + for (let i = 0; i < pathEnv.length; i ++) { + const ppRaw = pathEnv[i] + const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw - graph[fromModel].distance = 0; + const pCmd = path.join(pathPart, cmd) + const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd + : pCmd - while (queue.length) { - const current = queue.pop(); - const adjacents = Object.keys(conversions[current]); + for (let j = 0; j < pathExt.length; j ++) { + const cur = p + pathExt[j] + try { + const is = isexe.sync(cur, { pathExt: pathExtExe }) + if (is) { + if (opt.all) + found.push(cur) + else + return cur + } + } catch (ex) {} + } + } - for (let len = adjacents.length, i = 0; i < len; i++) { - const adjacent = adjacents[i]; - const node = graph[adjacent]; + if (opt.all && found.length) + return found - if (node.distance === -1) { - node.distance = graph[current].distance + 1; - node.parent = current; - queue.unshift(adjacent); - } - } - } + if (opt.nothrow) + return null - return graph; + throw getNotFoundError(cmd) } -function link(from, to) { - return function (args) { - return to(from(args)); - }; -} +module.exports = which +which.sync = whichSync -function wrapConversion(toModel, graph) { - const path = [graph[toModel].parent, toModel]; - let fn = conversions[graph[toModel].parent][toModel]; - let cur = graph[toModel].parent; - while (graph[cur].parent) { - path.unshift(graph[cur].parent); - fn = link(conversions[graph[cur].parent][cur], fn); - cur = graph[cur].parent; - } +/***/ }), +/* 242 */ +/***/ (function(module, exports, __webpack_require__) { - fn.conversion = path; - return fn; +var fs = __webpack_require__(133) +var core +if (process.platform === 'win32' || global.TESTING_WINDOWS) { + core = __webpack_require__(243) +} else { + core = __webpack_require__(244) } -module.exports = function (fromModel) { - const graph = deriveBFS(fromModel); - const conversion = {}; +module.exports = isexe +isexe.sync = sync - const models = Object.keys(graph); - for (let len = models.length, i = 0; i < len; i++) { - const toModel = models[i]; - const node = graph[toModel]; +function isexe (path, options, cb) { + if (typeof options === 'function') { + cb = options + options = {} + } - if (node.parent === null) { - // No possible conversion, or this node is the source model. - continue; - } + if (!cb) { + if (typeof Promise !== 'function') { + throw new TypeError('callback not provided') + } - conversion[toModel] = wrapConversion(toModel, graph); - } + return new Promise(function (resolve, reject) { + isexe(path, options || {}, function (er, is) { + if (er) { + reject(er) + } else { + resolve(is) + } + }) + }) + } - return conversion; -}; + core(path, options || {}, function (er, is) { + // ignore EACCES because that just means we aren't allowed to run it + if (er) { + if (er.code === 'EACCES' || options && options.ignoreErrors) { + er = null + is = false + } + } + cb(er, is) + }) +} +function sync (path, options) { + // my kingdom for a filtered catch + try { + return core.sync(path, options || {}) + } catch (er) { + if (options && options.ignoreErrors || er.code === 'EACCES') { + return false + } else { + throw er + } + } +} /***/ }), -/* 240 */ +/* 243 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; +module.exports = isexe +isexe.sync = sync -const os = __webpack_require__(120); -const tty = __webpack_require__(121); -const hasFlag = __webpack_require__(241); +var fs = __webpack_require__(133) -const {env} = process; +function checkPathExt (path, options) { + var pathext = options.pathExt !== undefined ? + options.pathExt : process.env.PATHEXT -let forceColor; -if (hasFlag('no-color') || - hasFlag('no-colors') || - hasFlag('color=false') || - hasFlag('color=never')) { - forceColor = 0; -} else if (hasFlag('color') || - hasFlag('colors') || - hasFlag('color=true') || - hasFlag('color=always')) { - forceColor = 1; -} + if (!pathext) { + return true + } -if ('FORCE_COLOR' in env) { - if (env.FORCE_COLOR === 'true') { - forceColor = 1; - } else if (env.FORCE_COLOR === 'false') { - forceColor = 0; - } else { - forceColor = env.FORCE_COLOR.length === 0 ? 1 : Math.min(parseInt(env.FORCE_COLOR, 10), 3); - } + pathext = pathext.split(';') + if (pathext.indexOf('') !== -1) { + return true + } + for (var i = 0; i < pathext.length; i++) { + var p = pathext[i].toLowerCase() + if (p && path.substr(-p.length).toLowerCase() === p) { + return true + } + } + return false } -function translateLevel(level) { - if (level === 0) { - return false; - } +function checkStat (stat, path, options) { + if (!stat.isSymbolicLink() && !stat.isFile()) { + return false + } + return checkPathExt(path, options) +} - return { - level, - hasBasic: true, - has256: level >= 2, - has16m: level >= 3 - }; +function isexe (path, options, cb) { + fs.stat(path, function (er, stat) { + cb(er, er ? false : checkStat(stat, path, options)) + }) } -function supportsColor(haveStream, streamIsTTY) { - if (forceColor === 0) { - return 0; - } +function sync (path, options) { + return checkStat(fs.statSync(path), path, options) +} - if (hasFlag('color=16m') || - hasFlag('color=full') || - hasFlag('color=truecolor')) { - return 3; - } - if (hasFlag('color=256')) { - return 2; - } +/***/ }), +/* 244 */ +/***/ (function(module, exports, __webpack_require__) { - if (haveStream && !streamIsTTY && forceColor === undefined) { - return 0; - } +module.exports = isexe +isexe.sync = sync - const min = forceColor || 0; +var fs = __webpack_require__(133) - if (env.TERM === 'dumb') { - return min; - } - - if (process.platform === 'win32') { - // Windows 10 build 10586 is the first Windows release that supports 256 colors. - // Windows 10 build 14931 is the first release that supports 16m/TrueColor. - const osRelease = os.release().split('.'); - if ( - Number(osRelease[0]) >= 10 && - Number(osRelease[2]) >= 10586 - ) { - return Number(osRelease[2]) >= 14931 ? 3 : 2; - } +function isexe (path, options, cb) { + fs.stat(path, function (er, stat) { + cb(er, er ? false : checkStat(stat, options)) + }) +} - return 1; - } +function sync (path, options) { + return checkStat(fs.statSync(path), options) +} - if ('CI' in env) { - if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI'].some(sign => sign in env) || env.CI_NAME === 'codeship') { - return 1; - } +function checkStat (stat, options) { + return stat.isFile() && checkMode(stat, options) +} - return min; - } +function checkMode (stat, options) { + var mod = stat.mode + var uid = stat.uid + var gid = stat.gid - if ('TEAMCITY_VERSION' in env) { - return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0; - } + var myUid = options.uid !== undefined ? + options.uid : process.getuid && process.getuid() + var myGid = options.gid !== undefined ? + options.gid : process.getgid && process.getgid() - if ('GITHUB_ACTIONS' in env) { - return 1; - } + var u = parseInt('100', 8) + var g = parseInt('010', 8) + var o = parseInt('001', 8) + var ug = u | g - if (env.COLORTERM === 'truecolor') { - return 3; - } + var ret = (mod & o) || + (mod & g) && gid === myGid || + (mod & u) && uid === myUid || + (mod & ug) && myUid === 0 - if ('TERM_PROGRAM' in env) { - const version = parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10); + return ret +} - switch (env.TERM_PROGRAM) { - case 'iTerm.app': - return version >= 3 ? 3 : 2; - case 'Apple_Terminal': - return 2; - // No default - } - } - if (/-256(color)?$/i.test(env.TERM)) { - return 2; - } +/***/ }), +/* 245 */ +/***/ (function(module, exports, __webpack_require__) { - if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) { - return 1; - } +"use strict"; - if ('COLORTERM' in env) { - return 1; - } - return min; -} +const pathKey = (options = {}) => { + const environment = options.env || process.env; + const platform = options.platform || process.platform; -function getSupportLevel(stream) { - const level = supportsColor(stream, stream && stream.isTTY); - return translateLevel(level); -} + if (platform !== 'win32') { + return 'PATH'; + } -module.exports = { - supportsColor: getSupportLevel, - stdout: translateLevel(supportsColor(true, tty.isatty(1))), - stderr: translateLevel(supportsColor(true, tty.isatty(2))) + return Object.keys(environment).find(key => key.toUpperCase() === 'PATH') || 'Path'; }; +module.exports = pathKey; +// TODO: Remove this for the next major release +module.exports.default = pathKey; + /***/ }), -/* 241 */ +/* 246 */ /***/ (function(module, exports, __webpack_require__) { "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); -}; +// See http://www.robvanderwoude.com/escapechars.php +const metaCharsRegExp = /([()\][%!^"`<>&|;, *?])/g; + +function escapeCommand(arg) { + // Escape meta chars + arg = arg.replace(metaCharsRegExp, '^$1'); + + return arg; +} + +function escapeArgument(arg, doubleEscapeMetaChars) { + // Convert to string + arg = `${arg}`; + + // Algorithm below is based on https://qntm.org/cmd + + // Sequence of backslashes followed by a double quote: + // double up all the backslashes and escape the double quote + arg = arg.replace(/(\\*)"/g, '$1$1\\"'); + + // Sequence of backslashes followed by the end of the string + // (which will become a double quote later): + // double up all the backslashes + arg = arg.replace(/(\\*)$/, '$1$1'); + + // All other backslashes occur literally + + // Quote the whole thing: + arg = `"${arg}"`; + + // Escape meta chars + arg = arg.replace(metaCharsRegExp, '^$1'); + + // Double escape meta chars if necessary + if (doubleEscapeMetaChars) { + arg = arg.replace(metaCharsRegExp, '^$1'); + } + + return arg; +} + +module.exports.command = escapeCommand; +module.exports.argument = escapeArgument; /***/ }), -/* 242 */ +/* 247 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const stringReplaceAll = (string, substring, replacer) => { - let index = string.indexOf(substring); - if (index === -1) { - return string; - } +const fs = __webpack_require__(133); +const shebangCommand = __webpack_require__(248); - const substringLength = substring.length; - let endIndex = 0; - let returnValue = ''; - do { - returnValue += string.substr(endIndex, index - endIndex) + substring + replacer; - endIndex = index + substringLength; - index = string.indexOf(substring, endIndex); - } while (index !== -1); +function readShebang(command) { + // Read the first 150 bytes from the file + const size = 150; + const buffer = Buffer.alloc(size); - returnValue += string.substr(endIndex); - return returnValue; -}; + let fd; -const stringEncaseCRLFWithFirstIndex = (string, prefix, postfix, index) => { - let endIndex = 0; - let returnValue = ''; - do { - const gotCR = string[index - 1] === '\r'; - returnValue += string.substr(endIndex, (gotCR ? index - 1 : index) - endIndex) + prefix + (gotCR ? '\r\n' : '\n') + postfix; - endIndex = index + 1; - index = string.indexOf('\n', endIndex); - } while (index !== -1); + try { + fd = fs.openSync(command, 'r'); + fs.readSync(fd, buffer, 0, size, 0); + fs.closeSync(fd); + } catch (e) { /* Empty */ } - returnValue += string.substr(endIndex); - return returnValue; -}; + // Attempt to extract shebang (null is returned if not a shebang) + return shebangCommand(buffer.toString()); +} -module.exports = { - stringReplaceAll, - stringEncaseCRLFWithFirstIndex -}; +module.exports = readShebang; /***/ }), -/* 243 */ +/* 248 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const TEMPLATE_REGEX = /(?:\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi; -const STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g; -const STRING_REGEX = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$/; -const ESCAPE_REGEX = /\\(u(?:[a-f\d]{4}|{[a-f\d]{1,6}})|x[a-f\d]{2}|.)|([^\\])/gi; - -const ESCAPES = new Map([ - ['n', '\n'], - ['r', '\r'], - ['t', '\t'], - ['b', '\b'], - ['f', '\f'], - ['v', '\v'], - ['0', '\0'], - ['\\', '\\'], - ['e', '\u001B'], - ['a', '\u0007'] -]); +const shebangRegex = __webpack_require__(249); -function unescape(c) { - const u = c[0] === 'u'; - const bracket = c[1] === '{'; +module.exports = (string = '') => { + const match = string.match(shebangRegex); - if ((u && !bracket && c.length === 5) || (c[0] === 'x' && c.length === 3)) { - return String.fromCharCode(parseInt(c.slice(1), 16)); + if (!match) { + return null; } - if (u && bracket) { - return String.fromCodePoint(parseInt(c.slice(2, -1), 16)); + const [path, argument] = match[0].replace(/#! ?/, '').split(' '); + const binary = path.split('/').pop(); + + if (binary === 'env') { + return argument; } - return ESCAPES.get(c) || c; -} + return argument ? `${binary} ${argument}` : binary; +}; -function parseArguments(name, arguments_) { - const results = []; - const chunks = arguments_.trim().split(/\s*,\s*/g); - let matches; - for (const chunk of chunks) { - const number = Number(chunk); - if (!Number.isNaN(number)) { - results.push(number); - } else if ((matches = chunk.match(STRING_REGEX))) { - results.push(matches[2].replace(ESCAPE_REGEX, (m, escape, character) => escape ? unescape(escape) : character)); - } else { - throw new Error(`Invalid Chalk template style argument: ${chunk} (in style '${name}')`); - } - } +/***/ }), +/* 249 */ +/***/ (function(module, exports, __webpack_require__) { - return results; -} +"use strict"; -function parseStyle(style) { - STYLE_REGEX.lastIndex = 0; +module.exports = /^#!(.*)/; - const results = []; - let matches; - while ((matches = STYLE_REGEX.exec(style)) !== null) { - const name = matches[1]; +/***/ }), +/* 250 */ +/***/ (function(module, exports, __webpack_require__) { - if (matches[2]) { - const args = parseArguments(name, matches[2]); - results.push([name].concat(args)); - } else { - results.push([name]); - } - } +"use strict"; - return results; + +const isWin = process.platform === 'win32'; + +function notFoundError(original, syscall) { + return Object.assign(new Error(`${syscall} ${original.command} ENOENT`), { + code: 'ENOENT', + errno: 'ENOENT', + syscall: `${syscall} ${original.command}`, + path: original.command, + spawnargs: original.args, + }); } -function buildStyle(chalk, styles) { - const enabled = {}; +function hookChildProcess(cp, parsed) { + if (!isWin) { + return; + } - for (const layer of styles) { - for (const style of layer.styles) { - enabled[style[0]] = layer.inverse ? null : style.slice(1); - } - } + const originalEmit = cp.emit; - let current = chalk; - for (const [styleName, styles] of Object.entries(enabled)) { - if (!Array.isArray(styles)) { - continue; - } + cp.emit = function (name, arg1) { + // If emitting "exit" event and exit code is 1, we need to check if + // the command exists and emit an "error" instead + // See https://github.com/IndigoUnited/node-cross-spawn/issues/16 + if (name === 'exit') { + const err = verifyENOENT(arg1, parsed, 'spawn'); - if (!(styleName in current)) { - throw new Error(`Unknown Chalk style: ${styleName}`); - } + if (err) { + return originalEmit.call(cp, 'error', err); + } + } - current = styles.length > 0 ? current[styleName](...styles) : current[styleName]; - } + return originalEmit.apply(cp, arguments); // eslint-disable-line prefer-rest-params + }; +} - return current; +function verifyENOENT(status, parsed) { + if (isWin && status === 1 && !parsed.file) { + return notFoundError(parsed.original, 'spawn'); + } + + return null; } -module.exports = (chalk, temporary) => { - const styles = []; - const chunks = []; - let chunk = []; +function verifyENOENTSync(status, parsed) { + if (isWin && status === 1 && !parsed.file) { + return notFoundError(parsed.original, 'spawnSync'); + } - // eslint-disable-next-line max-params - temporary.replace(TEMPLATE_REGEX, (m, escapeCharacter, inverse, style, close, character) => { - if (escapeCharacter) { - chunk.push(unescape(escapeCharacter)); - } else if (style) { - const string = chunk.join(''); - chunk = []; - chunks.push(styles.length === 0 ? string : buildStyle(chalk, styles)(string)); - styles.push({inverse, styles: parseStyle(style)}); - } else if (close) { - if (styles.length === 0) { - throw new Error('Found extraneous } in Chalk template literal'); - } + return null; +} - chunks.push(buildStyle(chalk, styles)(chunk.join(''))); - chunk = []; - styles.pop(); - } else { - chunk.push(character); - } - }); +module.exports = { + hookChildProcess, + verifyENOENT, + verifyENOENTSync, + notFoundError, +}; - chunks.push(chunk.join('')); - if (styles.length > 0) { - const errMessage = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? '' : 's'} (\`}\`)`; - throw new Error(errMessage); +/***/ }), +/* 251 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +module.exports = input => { + const LF = typeof input === 'string' ? '\n' : '\n'.charCodeAt(); + const CR = typeof input === 'string' ? '\r' : '\r'.charCodeAt(); + + if (input[input.length - 1] === LF) { + input = input.slice(0, input.length - 1); } - return chunks.join(''); + if (input[input.length - 1] === CR) { + input = input.slice(0, input.length - 1); + } + + return input; }; /***/ }), -/* 244 */ +/* 252 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const path = __webpack_require__(4); -const childProcess = __webpack_require__(245); -const crossSpawn = __webpack_require__(246); -const stripFinalNewline = __webpack_require__(259); -const npmRunPath = __webpack_require__(260); -const onetime = __webpack_require__(261); -const makeError = __webpack_require__(263); -const normalizeStdio = __webpack_require__(268); -const {spawnedKill, spawnedCancel, setupTimeout, setExitHandler} = __webpack_require__(269); -const {handleInput, getSpawnedResult, makeAllStream, validateInputSync} = __webpack_require__(270); -const {mergePromise, getSpawnedPromise} = __webpack_require__(277); -const {joinCommand, parseCommand} = __webpack_require__(278); +const pathKey = __webpack_require__(245); -const DEFAULT_MAX_BUFFER = 1000 * 1000 * 100; +const npmRunPath = options => { + options = { + cwd: process.cwd(), + path: process.env[pathKey()], + execPath: process.execPath, + ...options + }; -const getEnv = ({env: envOption, extendEnv, preferLocal, localDir, execPath}) => { - const env = extendEnv ? {...process.env, ...envOption} : envOption; + let previous; + let cwdPath = path.resolve(options.cwd); + const result = []; - if (preferLocal) { - return npmRunPath.env({env, cwd: localDir, execPath}); + while (previous !== cwdPath) { + result.push(path.join(cwdPath, 'node_modules/.bin')); + previous = cwdPath; + cwdPath = path.resolve(cwdPath, '..'); } - return env; + // Ensure the running `node` binary is used + const execPathDir = path.resolve(options.cwd, options.execPath, '..'); + result.push(execPathDir); + + return result.concat(options.path).join(path.delimiter); }; -const handleArgs = (file, args, options = {}) => { - const parsed = crossSpawn._parse(file, args, options); - file = parsed.command; - args = parsed.args; - options = parsed.options; +module.exports = npmRunPath; +// TODO: Remove this for the next major release +module.exports.default = npmRunPath; +module.exports.env = options => { options = { - maxBuffer: DEFAULT_MAX_BUFFER, - buffer: true, - stripFinalNewline: true, - extendEnv: true, - preferLocal: false, - localDir: options.cwd || process.cwd(), - execPath: process.execPath, - encoding: 'utf8', - reject: true, - cleanup: true, - all: false, - windowsHide: true, + env: process.env, ...options }; - options.env = getEnv(options); - - options.stdio = normalizeStdio(options); + const env = {...options.env}; + const path = pathKey({env}); - if (process.platform === 'win32' && path.basename(file, '.exe') === 'cmd') { - // #116 - args.unshift('/q'); - } + options.path = env[path]; + env[path] = module.exports(options); - return {file, args, options, parsed}; + return env; }; -const handleOutput = (options, value, error) => { - if (typeof value !== 'string' && !Buffer.isBuffer(value)) { - // When `execa.sync()` errors, we normalize it to '' to mimic `execa()` - return error === undefined ? undefined : ''; - } - if (options.stripFinalNewline) { - return stripFinalNewline(value); - } +/***/ }), +/* 253 */ +/***/ (function(module, exports, __webpack_require__) { - return value; -}; +"use strict"; -const execa = (file, args, options) => { - const parsed = handleArgs(file, args, options); - const command = joinCommand(file, args); +const mimicFn = __webpack_require__(254); - let spawned; - try { - spawned = childProcess.spawn(parsed.file, parsed.args, parsed.options); - } catch (error) { - // Ensure the returned error is always both a promise and a child process - const dummySpawned = new childProcess.ChildProcess(); - const errorPromise = Promise.reject(makeError({ - error, - stdout: '', - stderr: '', - all: '', - command, - parsed, - timedOut: false, - isCanceled: false, - killed: false - })); - return mergePromise(dummySpawned, errorPromise); +const calledFunctions = new WeakMap(); + +const oneTime = (fn, options = {}) => { + if (typeof fn !== 'function') { + throw new TypeError('Expected a function'); } - const spawnedPromise = getSpawnedPromise(spawned); - const timedPromise = setupTimeout(spawned, parsed.options, spawnedPromise); - const processDone = setExitHandler(spawned, parsed.options, timedPromise); + let ret; + let isCalled = false; + let callCount = 0; + const functionName = fn.displayName || fn.name || ''; - const context = {isCanceled: false}; + const onetime = function (...args) { + calledFunctions.set(onetime, ++callCount); - spawned.kill = spawnedKill.bind(null, spawned.kill.bind(spawned)); - spawned.cancel = spawnedCancel.bind(null, spawned, context); + if (isCalled) { + if (options.throw === true) { + throw new Error(`Function \`${functionName}\` can only be called once`); + } - const handlePromise = async () => { - const [{error, exitCode, signal, timedOut}, stdoutResult, stderrResult, allResult] = await getSpawnedResult(spawned, parsed.options, processDone); - const stdout = handleOutput(parsed.options, stdoutResult); - const stderr = handleOutput(parsed.options, stderrResult); - const all = handleOutput(parsed.options, allResult); - - if (error || exitCode !== 0 || signal !== null) { - const returnedError = makeError({ - error, - exitCode, - signal, - stdout, - stderr, - all, - command, - parsed, - timedOut, - isCanceled: context.isCanceled, - killed: spawned.killed - }); - - if (!parsed.options.reject) { - return returnedError; - } - - throw returnedError; + return ret; } - return { - command, - exitCode: 0, - stdout, - stderr, - all, - failed: false, - timedOut: false, - isCanceled: false, - killed: false - }; - }; - - const handlePromiseOnce = onetime(handlePromise); - - crossSpawn._enoent.hookChildProcess(spawned, parsed.parsed); + isCalled = true; + ret = fn.apply(this, args); + fn = null; - handleInput(spawned, parsed.options.input); + return ret; + }; - spawned.all = makeAllStream(spawned, parsed.options); + mimicFn(onetime, fn); + calledFunctions.set(onetime, callCount); - return mergePromise(spawned, handlePromiseOnce); + return onetime; }; -module.exports = execa; - -module.exports.sync = (file, args, options) => { - const parsed = handleArgs(file, args, options); - const command = joinCommand(file, args); - - validateInputSync(parsed.options); +module.exports = oneTime; +// TODO: Remove this for the next major release +module.exports.default = oneTime; - let result; - try { - result = childProcess.spawnSync(parsed.file, parsed.args, parsed.options); - } catch (error) { - throw makeError({ - error, - stdout: '', - stderr: '', - all: '', - command, - parsed, - timedOut: false, - isCanceled: false, - killed: false - }); +module.exports.callCount = fn => { + if (!calledFunctions.has(fn)) { + throw new Error(`The given function \`${fn.name}\` is not wrapped by the \`onetime\` package`); } - const stdout = handleOutput(parsed.options, result.stdout, result.error); - const stderr = handleOutput(parsed.options, result.stderr, result.error); + return calledFunctions.get(fn); +}; - if (result.error || result.status !== 0 || result.signal !== null) { - const error = makeError({ - stdout, - stderr, - error: result.error, - signal: result.signal, - exitCode: result.status, - command, - parsed, - timedOut: result.error && result.error.code === 'ETIMEDOUT', - isCanceled: false, - killed: result.signal !== null - }); - if (!parsed.options.reject) { - return error; - } +/***/ }), +/* 254 */ +/***/ (function(module, exports, __webpack_require__) { - throw error; - } +"use strict"; - return { - command, - exitCode: 0, - stdout, - stderr, - failed: false, - timedOut: false, - isCanceled: false, - killed: false - }; -}; -module.exports.command = (command, options) => { - const [file, ...args] = parseCommand(command); - return execa(file, args, options); -}; +const mimicFn = (to, from) => { + for (const prop of Reflect.ownKeys(from)) { + Object.defineProperty(to, prop, Object.getOwnPropertyDescriptor(from, prop)); + } -module.exports.commandSync = (command, options) => { - const [file, ...args] = parseCommand(command); - return execa.sync(file, args, options); + return to; }; -module.exports.node = (scriptPath, args, options = {}) => { - if (args && !Array.isArray(args) && typeof args === 'object') { - options = args; - args = []; - } +module.exports = mimicFn; +// TODO: Remove this for the next major release +module.exports.default = mimicFn; - const stdio = normalizeStdio.node(options); - const {nodePath = process.execPath, nodeOptions = process.execArgv} = options; +/***/ }), +/* 255 */ +/***/ (function(module, exports, __webpack_require__) { - return execa( - nodePath, - [ - ...nodeOptions, - scriptPath, - ...(Array.isArray(args) ? args : []) - ], - { - ...options, - stdin: undefined, - stdout: undefined, - stderr: undefined, - stdio, - shell: false - } - ); -}; +"use strict"; +const {signalsByName} = __webpack_require__(256); -/***/ }), -/* 245 */ -/***/ (function(module, exports) { +const getErrorPrefix = ({timedOut, timeout, errorCode, signal, signalDescription, exitCode, isCanceled}) => { + if (timedOut) { + return `timed out after ${timeout} milliseconds`; + } -module.exports = require("child_process"); + if (isCanceled) { + return 'was canceled'; + } -/***/ }), -/* 246 */ -/***/ (function(module, exports, __webpack_require__) { + if (errorCode !== undefined) { + return `failed with ${errorCode}`; + } -"use strict"; + if (signal !== undefined) { + return `was killed with ${signal} (${signalDescription})`; + } + if (exitCode !== undefined) { + return `failed with exit code ${exitCode}`; + } -const cp = __webpack_require__(245); -const parse = __webpack_require__(247); -const enoent = __webpack_require__(258); + return 'failed'; +}; -function spawn(command, args, options) { - // Parse the arguments - const parsed = parse(command, args, options); +const makeError = ({ + stdout, + stderr, + all, + error, + signal, + exitCode, + command, + timedOut, + isCanceled, + killed, + parsed: {options: {timeout}} +}) => { + // `signal` and `exitCode` emitted on `spawned.on('exit')` event can be `null`. + // We normalize them to `undefined` + exitCode = exitCode === null ? undefined : exitCode; + signal = signal === null ? undefined : signal; + const signalDescription = signal === undefined ? undefined : signalsByName[signal].description; - // Spawn the child process - const spawned = cp.spawn(parsed.command, parsed.args, parsed.options); + const errorCode = error && error.code; - // Hook into child process "exit" event to emit an error if the command - // does not exists, see: https://github.com/IndigoUnited/node-cross-spawn/issues/16 - enoent.hookChildProcess(spawned, parsed); + const prefix = getErrorPrefix({timedOut, timeout, errorCode, signal, signalDescription, exitCode, isCanceled}); + const execaMessage = `Command ${prefix}: ${command}`; + const isError = Object.prototype.toString.call(error) === '[object Error]'; + const shortMessage = isError ? `${execaMessage}\n${error.message}` : execaMessage; + const message = [shortMessage, stderr, stdout].filter(Boolean).join('\n'); - return spawned; -} + if (isError) { + error.originalMessage = error.message; + error.message = message; + } else { + error = new Error(message); + } -function spawnSync(command, args, options) { - // Parse the arguments - const parsed = parse(command, args, options); + error.shortMessage = shortMessage; + error.command = command; + error.exitCode = exitCode; + error.signal = signal; + error.signalDescription = signalDescription; + error.stdout = stdout; + error.stderr = stderr; - // Spawn the child process - const result = cp.spawnSync(parsed.command, parsed.args, parsed.options); + if (all !== undefined) { + error.all = all; + } - // Analyze if the command does not exist, see: https://github.com/IndigoUnited/node-cross-spawn/issues/16 - result.error = result.error || enoent.verifyENOENTSync(result.status, parsed); + if ('bufferedData' in error) { + delete error.bufferedData; + } - return result; -} + error.failed = true; + error.timedOut = Boolean(timedOut); + error.isCanceled = isCanceled; + error.killed = killed && !timedOut; -module.exports = spawn; -module.exports.spawn = spawn; -module.exports.sync = spawnSync; + return error; +}; -module.exports._parse = parse; -module.exports._enoent = enoent; +module.exports = makeError; /***/ }), -/* 247 */ +/* 256 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +Object.defineProperty(exports,"__esModule",{value:true});exports.signalsByNumber=exports.signalsByName=void 0;var _os=__webpack_require__(120); +var _signals=__webpack_require__(257); +var _realtime=__webpack_require__(259); -const path = __webpack_require__(4); -const resolveCommand = __webpack_require__(248); -const escape = __webpack_require__(254); -const readShebang = __webpack_require__(255); -const isWin = process.platform === 'win32'; -const isExecutableRegExp = /\.(?:com|exe)$/i; -const isCmdShimRegExp = /node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i; -function detectShebang(parsed) { - parsed.file = resolveCommand(parsed); +const getSignalsByName=function(){ +const signals=(0,_signals.getSignals)(); +return signals.reduce(getSignalByName,{}); +}; - const shebang = parsed.file && readShebang(parsed.file); +const getSignalByName=function( +signalByNameMemo, +{name,number,description,supported,action,forced,standard}) +{ +return{ +...signalByNameMemo, +[name]:{name,number,description,supported,action,forced,standard}}; - if (shebang) { - parsed.args.unshift(parsed.file); - parsed.command = shebang; +}; - return resolveCommand(parsed); - } +const signalsByName=getSignalsByName();exports.signalsByName=signalsByName; - return parsed.file; -} -function parseNonShell(parsed) { - if (!isWin) { - return parsed; - } - // Detect & add support for shebangs - const commandFile = detectShebang(parsed); - // We don't need a shell if the command filename is an executable - const needsShell = !isExecutableRegExp.test(commandFile); +const getSignalsByNumber=function(){ +const signals=(0,_signals.getSignals)(); +const length=_realtime.SIGRTMAX+1; +const signalsA=Array.from({length},(value,number)=> +getSignalByNumber(number,signals)); - // If a shell is required, use cmd.exe and take care of escaping everything correctly - // Note that `forceShell` is an hidden option used only in tests - if (parsed.options.forceShell || needsShell) { - // Need to double escape meta chars if the command is a cmd-shim located in `node_modules/.bin/` - // The cmd-shim simply calls execute the package bin file with NodeJS, proxying any argument - // Because the escape of metachars with ^ gets interpreted when the cmd.exe is first called, - // we need to double escape them - const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile); +return Object.assign({},...signalsA); +}; - // Normalize posix paths into OS compatible paths (e.g.: foo/bar -> foo\bar) - // This is necessary otherwise it will always fail with ENOENT in those cases - parsed.command = path.normalize(parsed.command); +const getSignalByNumber=function(number,signals){ +const signal=findSignalByNumber(number,signals); - // Escape command & arguments - parsed.command = escape.command(parsed.command); - parsed.args = parsed.args.map((arg) => escape.argument(arg, needsDoubleEscapeMetaChars)); +if(signal===undefined){ +return{}; +} - const shellCommand = [parsed.command].concat(parsed.args).join(' '); +const{name,description,supported,action,forced,standard}=signal; +return{ +[number]:{ +name, +number, +description, +supported, +action, +forced, +standard}}; - parsed.args = ['/d', '/s', '/c', `"${shellCommand}"`]; - parsed.command = process.env.comspec || 'cmd.exe'; - parsed.options.windowsVerbatimArguments = true; // Tell node's spawn that the arguments are already escaped - } - return parsed; -} +}; -function parse(command, args, options) { - // Normalize arguments, similar to nodejs - if (args && !Array.isArray(args)) { - options = args; - args = null; - } - args = args ? args.slice(0) : []; // Clone array to avoid changing the original - options = Object.assign({}, options); // Clone object to avoid changing the original - // Build our parsed object - const parsed = { - command, - args, - options, - file: undefined, - original: { - command, - args, - }, - }; +const findSignalByNumber=function(number,signals){ +const signal=signals.find(({name})=>_os.constants.signals[name]===number); - // Delegate further parsing to shell or non-shell - return options.shell ? parsed : parseNonShell(parsed); +if(signal!==undefined){ +return signal; } -module.exports = parse; +return signals.find(signalA=>signalA.number===number); +}; +const signalsByNumber=getSignalsByNumber();exports.signalsByNumber=signalsByNumber; +//# sourceMappingURL=main.js.map /***/ }), -/* 248 */ +/* 257 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +Object.defineProperty(exports,"__esModule",{value:true});exports.getSignals=void 0;var _os=__webpack_require__(120); +var _core=__webpack_require__(258); +var _realtime=__webpack_require__(259); -const path = __webpack_require__(4); -const which = __webpack_require__(249); -const pathKey = __webpack_require__(253)(); -function resolveCommandAttempt(parsed, withoutPathExt) { - const cwd = process.cwd(); - const hasCustomCwd = parsed.options.cwd != null; - // Worker threads do not have process.chdir() - const shouldSwitchCwd = hasCustomCwd && process.chdir !== undefined; - // If a custom `cwd` was specified, we need to change the process cwd - // because `which` will do stat calls but does not support a custom cwd - if (shouldSwitchCwd) { - try { - process.chdir(parsed.options.cwd); - } catch (err) { - /* Empty */ - } - } +const getSignals=function(){ +const realtimeSignals=(0,_realtime.getRealtimeSignals)(); +const signals=[..._core.SIGNALS,...realtimeSignals].map(normalizeSignal); +return signals; +};exports.getSignals=getSignals; - let resolved; - try { - resolved = which.sync(parsed.command, { - path: (parsed.options.env || process.env)[pathKey], - pathExt: withoutPathExt ? path.delimiter : undefined, - }); - } catch (e) { - /* Empty */ - } finally { - if (shouldSwitchCwd) { - process.chdir(cwd); - } - } - // If we successfully resolved, ensure that an absolute path is returned - // Note that when a custom `cwd` was used, we need to resolve to an absolute path based on it - if (resolved) { - resolved = path.resolve(hasCustomCwd ? parsed.options.cwd : '', resolved); - } - return resolved; -} -function resolveCommand(parsed) { - return resolveCommandAttempt(parsed) || resolveCommandAttempt(parsed, true); -} -module.exports = resolveCommand; +const normalizeSignal=function({ +name, +number:defaultNumber, +description, +action, +forced=false, +standard}) +{ +const{ +signals:{[name]:constantSignal}}= +_os.constants; +const supported=constantSignal!==undefined; +const number=supported?constantSignal:defaultNumber; +return{name,number,description,supported,action,forced,standard}; +}; +//# sourceMappingURL=signals.js.map /***/ }), -/* 249 */ +/* 258 */ /***/ (function(module, exports, __webpack_require__) { -const isWindows = process.platform === 'win32' || - process.env.OSTYPE === 'cygwin' || - process.env.OSTYPE === 'msys' +"use strict"; +Object.defineProperty(exports,"__esModule",{value:true});exports.SIGNALS=void 0; -const path = __webpack_require__(4) -const COLON = isWindows ? ';' : ':' -const isexe = __webpack_require__(250) +const SIGNALS=[ +{ +name:"SIGHUP", +number:1, +action:"terminate", +description:"Terminal closed", +standard:"posix"}, -const getNotFoundError = (cmd) => - Object.assign(new Error(`not found: ${cmd}`), { code: 'ENOENT' }) +{ +name:"SIGINT", +number:2, +action:"terminate", +description:"User interruption with CTRL-C", +standard:"ansi"}, -const getPathInfo = (cmd, opt) => { - const colon = opt.colon || COLON +{ +name:"SIGQUIT", +number:3, +action:"core", +description:"User interruption with CTRL-\\", +standard:"posix"}, - // If it has a slash, then we don't bother searching the pathenv. - // just check the file itself, and that's it. - const pathEnv = cmd.match(/\//) || isWindows && cmd.match(/\\/) ? [''] - : ( - [ - // windows always checks the cwd first - ...(isWindows ? [process.cwd()] : []), - ...(opt.path || process.env.PATH || - /* istanbul ignore next: very unusual */ '').split(colon), - ] - ) - const pathExtExe = isWindows - ? opt.pathExt || process.env.PATHEXT || '.EXE;.CMD;.BAT;.COM' - : '' - const pathExt = isWindows ? pathExtExe.split(colon) : [''] +{ +name:"SIGILL", +number:4, +action:"core", +description:"Invalid machine instruction", +standard:"ansi"}, - if (isWindows) { - if (cmd.indexOf('.') !== -1 && pathExt[0] !== '') - pathExt.unshift('') - } +{ +name:"SIGTRAP", +number:5, +action:"core", +description:"Debugger breakpoint", +standard:"posix"}, - return { - pathEnv, - pathExt, - pathExtExe, - } -} +{ +name:"SIGABRT", +number:6, +action:"core", +description:"Aborted", +standard:"ansi"}, -const which = (cmd, opt, cb) => { - if (typeof opt === 'function') { - cb = opt - opt = {} - } - if (!opt) - opt = {} +{ +name:"SIGIOT", +number:6, +action:"core", +description:"Aborted", +standard:"bsd"}, - const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt) - const found = [] +{ +name:"SIGBUS", +number:7, +action:"core", +description: +"Bus error due to misaligned, non-existing address or paging error", +standard:"bsd"}, - const step = i => new Promise((resolve, reject) => { - if (i === pathEnv.length) - return opt.all && found.length ? resolve(found) - : reject(getNotFoundError(cmd)) +{ +name:"SIGEMT", +number:7, +action:"terminate", +description:"Command should be emulated but is not implemented", +standard:"other"}, - const ppRaw = pathEnv[i] - const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw +{ +name:"SIGFPE", +number:8, +action:"core", +description:"Floating point arithmetic error", +standard:"ansi"}, - const pCmd = path.join(pathPart, cmd) - const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd - : pCmd +{ +name:"SIGKILL", +number:9, +action:"terminate", +description:"Forced termination", +standard:"posix", +forced:true}, - resolve(subStep(p, i, 0)) - }) +{ +name:"SIGUSR1", +number:10, +action:"terminate", +description:"Application-specific signal", +standard:"posix"}, - const subStep = (p, i, ii) => new Promise((resolve, reject) => { - if (ii === pathExt.length) - return resolve(step(i + 1)) - const ext = pathExt[ii] - isexe(p + ext, { pathExt: pathExtExe }, (er, is) => { - if (!er && is) { - if (opt.all) - found.push(p + ext) - else - return resolve(p + ext) - } - return resolve(subStep(p, i, ii + 1)) - }) - }) +{ +name:"SIGSEGV", +number:11, +action:"core", +description:"Segmentation fault", +standard:"ansi"}, - return cb ? step(0).then(res => cb(null, res), cb) : step(0) -} +{ +name:"SIGUSR2", +number:12, +action:"terminate", +description:"Application-specific signal", +standard:"posix"}, -const whichSync = (cmd, opt) => { - opt = opt || {} +{ +name:"SIGPIPE", +number:13, +action:"terminate", +description:"Broken pipe or socket", +standard:"posix"}, - const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt) - const found = [] +{ +name:"SIGALRM", +number:14, +action:"terminate", +description:"Timeout or timer", +standard:"posix"}, - for (let i = 0; i < pathEnv.length; i ++) { - const ppRaw = pathEnv[i] - const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw +{ +name:"SIGTERM", +number:15, +action:"terminate", +description:"Termination", +standard:"ansi"}, - const pCmd = path.join(pathPart, cmd) - const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd - : pCmd +{ +name:"SIGSTKFLT", +number:16, +action:"terminate", +description:"Stack is empty or overflowed", +standard:"other"}, - for (let j = 0; j < pathExt.length; j ++) { - const cur = p + pathExt[j] - try { - const is = isexe.sync(cur, { pathExt: pathExtExe }) - if (is) { - if (opt.all) - found.push(cur) - else - return cur - } - } catch (ex) {} - } - } +{ +name:"SIGCHLD", +number:17, +action:"ignore", +description:"Child process terminated, paused or unpaused", +standard:"posix"}, - if (opt.all && found.length) - return found +{ +name:"SIGCLD", +number:17, +action:"ignore", +description:"Child process terminated, paused or unpaused", +standard:"other"}, - if (opt.nothrow) - return null +{ +name:"SIGCONT", +number:18, +action:"unpause", +description:"Unpaused", +standard:"posix", +forced:true}, - throw getNotFoundError(cmd) -} +{ +name:"SIGSTOP", +number:19, +action:"pause", +description:"Paused", +standard:"posix", +forced:true}, -module.exports = which -which.sync = whichSync +{ +name:"SIGTSTP", +number:20, +action:"pause", +description:"Paused using CTRL-Z or \"suspend\"", +standard:"posix"}, +{ +name:"SIGTTIN", +number:21, +action:"pause", +description:"Background process cannot read terminal input", +standard:"posix"}, -/***/ }), -/* 250 */ -/***/ (function(module, exports, __webpack_require__) { +{ +name:"SIGBREAK", +number:21, +action:"terminate", +description:"User interruption with CTRL-BREAK", +standard:"other"}, -var fs = __webpack_require__(133) -var core -if (process.platform === 'win32' || global.TESTING_WINDOWS) { - core = __webpack_require__(251) -} else { - core = __webpack_require__(252) -} +{ +name:"SIGTTOU", +number:22, +action:"pause", +description:"Background process cannot write to terminal output", +standard:"posix"}, -module.exports = isexe -isexe.sync = sync +{ +name:"SIGURG", +number:23, +action:"ignore", +description:"Socket received out-of-band data", +standard:"bsd"}, -function isexe (path, options, cb) { - if (typeof options === 'function') { - cb = options - options = {} - } +{ +name:"SIGXCPU", +number:24, +action:"core", +description:"Process timed out", +standard:"bsd"}, - if (!cb) { - if (typeof Promise !== 'function') { - throw new TypeError('callback not provided') - } +{ +name:"SIGXFSZ", +number:25, +action:"core", +description:"File too big", +standard:"bsd"}, - return new Promise(function (resolve, reject) { - isexe(path, options || {}, function (er, is) { - if (er) { - reject(er) - } else { - resolve(is) - } - }) - }) - } +{ +name:"SIGVTALRM", +number:26, +action:"terminate", +description:"Timeout or timer", +standard:"bsd"}, - core(path, options || {}, function (er, is) { - // ignore EACCES because that just means we aren't allowed to run it - if (er) { - if (er.code === 'EACCES' || options && options.ignoreErrors) { - er = null - is = false - } - } - cb(er, is) - }) -} +{ +name:"SIGPROF", +number:27, +action:"terminate", +description:"Timeout or timer", +standard:"bsd"}, -function sync (path, options) { - // my kingdom for a filtered catch - try { - return core.sync(path, options || {}) - } catch (er) { - if (options && options.ignoreErrors || er.code === 'EACCES') { - return false - } else { - throw er - } - } -} +{ +name:"SIGWINCH", +number:28, +action:"ignore", +description:"Terminal window size changed", +standard:"bsd"}, +{ +name:"SIGIO", +number:29, +action:"terminate", +description:"I/O is available", +standard:"other"}, -/***/ }), -/* 251 */ -/***/ (function(module, exports, __webpack_require__) { +{ +name:"SIGPOLL", +number:29, +action:"terminate", +description:"Watched event", +standard:"other"}, -module.exports = isexe -isexe.sync = sync +{ +name:"SIGINFO", +number:29, +action:"ignore", +description:"Request for process information", +standard:"other"}, -var fs = __webpack_require__(133) +{ +name:"SIGPWR", +number:30, +action:"terminate", +description:"Device running out of power", +standard:"systemv"}, -function checkPathExt (path, options) { - var pathext = options.pathExt !== undefined ? - options.pathExt : process.env.PATHEXT +{ +name:"SIGSYS", +number:31, +action:"core", +description:"Invalid system call", +standard:"other"}, - if (!pathext) { - return true - } +{ +name:"SIGUNUSED", +number:31, +action:"terminate", +description:"Invalid system call", +standard:"other"}];exports.SIGNALS=SIGNALS; +//# sourceMappingURL=core.js.map - pathext = pathext.split(';') - if (pathext.indexOf('') !== -1) { - return true - } - for (var i = 0; i < pathext.length; i++) { - var p = pathext[i].toLowerCase() - if (p && path.substr(-p.length).toLowerCase() === p) { - return true - } - } - return false -} +/***/ }), +/* 259 */ +/***/ (function(module, exports, __webpack_require__) { -function checkStat (stat, path, options) { - if (!stat.isSymbolicLink() && !stat.isFile()) { - return false - } - return checkPathExt(path, options) -} +"use strict"; +Object.defineProperty(exports,"__esModule",{value:true});exports.SIGRTMAX=exports.getRealtimeSignals=void 0; +const getRealtimeSignals=function(){ +const length=SIGRTMAX-SIGRTMIN+1; +return Array.from({length},getRealtimeSignal); +};exports.getRealtimeSignals=getRealtimeSignals; -function isexe (path, options, cb) { - fs.stat(path, function (er, stat) { - cb(er, er ? false : checkStat(stat, path, options)) - }) -} +const getRealtimeSignal=function(value,index){ +return{ +name:`SIGRT${index+1}`, +number:SIGRTMIN+index, +action:"terminate", +description:"Application-specific signal (realtime)", +standard:"posix"}; -function sync (path, options) { - return checkStat(fs.statSync(path), path, options) -} +}; +const SIGRTMIN=34; +const SIGRTMAX=64;exports.SIGRTMAX=SIGRTMAX; +//# sourceMappingURL=realtime.js.map /***/ }), -/* 252 */ +/* 260 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = isexe -isexe.sync = sync - -var fs = __webpack_require__(133) +"use strict"; -function isexe (path, options, cb) { - fs.stat(path, function (er, stat) { - cb(er, er ? false : checkStat(stat, options)) - }) -} +const aliases = ['stdin', 'stdout', 'stderr']; -function sync (path, options) { - return checkStat(fs.statSync(path), options) -} +const hasAlias = opts => aliases.some(alias => opts[alias] !== undefined); -function checkStat (stat, options) { - return stat.isFile() && checkMode(stat, options) -} +const normalizeStdio = opts => { + if (!opts) { + return; + } -function checkMode (stat, options) { - var mod = stat.mode - var uid = stat.uid - var gid = stat.gid + const {stdio} = opts; - var myUid = options.uid !== undefined ? - options.uid : process.getuid && process.getuid() - var myGid = options.gid !== undefined ? - options.gid : process.getgid && process.getgid() + if (stdio === undefined) { + return aliases.map(alias => opts[alias]); + } - var u = parseInt('100', 8) - var g = parseInt('010', 8) - var o = parseInt('001', 8) - var ug = u | g + if (hasAlias(opts)) { + throw new Error(`It's not possible to provide \`stdio\` in combination with one of ${aliases.map(alias => `\`${alias}\``).join(', ')}`); + } - var ret = (mod & o) || - (mod & g) && gid === myGid || - (mod & u) && uid === myUid || - (mod & ug) && myUid === 0 + if (typeof stdio === 'string') { + return stdio; + } - return ret -} + if (!Array.isArray(stdio)) { + throw new TypeError(`Expected \`stdio\` to be of type \`string\` or \`Array\`, got \`${typeof stdio}\``); + } + const length = Math.max(stdio.length, aliases.length); + return Array.from({length}, (value, index) => stdio[index]); +}; -/***/ }), -/* 253 */ -/***/ (function(module, exports, __webpack_require__) { +module.exports = normalizeStdio; -"use strict"; +// `ipc` is pushed unless it is already present +module.exports.node = opts => { + const stdio = normalizeStdio(opts); + if (stdio === 'ipc') { + return 'ipc'; + } -const pathKey = (options = {}) => { - const environment = options.env || process.env; - const platform = options.platform || process.platform; + if (stdio === undefined || typeof stdio === 'string') { + return [stdio, stdio, stdio, 'ipc']; + } - if (platform !== 'win32') { - return 'PATH'; + if (stdio.includes('ipc')) { + return stdio; } - return Object.keys(environment).find(key => key.toUpperCase() === 'PATH') || 'Path'; + return [...stdio, 'ipc']; }; -module.exports = pathKey; -// TODO: Remove this for the next major release -module.exports.default = pathKey; - /***/ }), -/* 254 */ +/* 261 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +const os = __webpack_require__(120); +const onExit = __webpack_require__(217); -// See http://www.robvanderwoude.com/escapechars.php -const metaCharsRegExp = /([()\][%!^"`<>&|;, *?])/g; - -function escapeCommand(arg) { - // Escape meta chars - arg = arg.replace(metaCharsRegExp, '^$1'); +const DEFAULT_FORCE_KILL_TIMEOUT = 1000 * 5; - return arg; -} +// Monkey-patches `childProcess.kill()` to add `forceKillAfterTimeout` behavior +const spawnedKill = (kill, signal = 'SIGTERM', options = {}) => { + const killResult = kill(signal); + setKillTimeout(kill, signal, options, killResult); + return killResult; +}; -function escapeArgument(arg, doubleEscapeMetaChars) { - // Convert to string - arg = `${arg}`; +const setKillTimeout = (kill, signal, options, killResult) => { + if (!shouldForceKill(signal, options, killResult)) { + return; + } - // Algorithm below is based on https://qntm.org/cmd + const timeout = getForceKillAfterTimeout(options); + const t = setTimeout(() => { + kill('SIGKILL'); + }, timeout); - // Sequence of backslashes followed by a double quote: - // double up all the backslashes and escape the double quote - arg = arg.replace(/(\\*)"/g, '$1$1\\"'); + // Guarded because there's no `.unref()` when `execa` is used in the renderer + // process in Electron. This cannot be tested since we don't run tests in + // Electron. + // istanbul ignore else + if (t.unref) { + t.unref(); + } +}; - // Sequence of backslashes followed by the end of the string - // (which will become a double quote later): - // double up all the backslashes - arg = arg.replace(/(\\*)$/, '$1$1'); +const shouldForceKill = (signal, {forceKillAfterTimeout}, killResult) => { + return isSigterm(signal) && forceKillAfterTimeout !== false && killResult; +}; - // All other backslashes occur literally +const isSigterm = signal => { + return signal === os.constants.signals.SIGTERM || + (typeof signal === 'string' && signal.toUpperCase() === 'SIGTERM'); +}; - // Quote the whole thing: - arg = `"${arg}"`; +const getForceKillAfterTimeout = ({forceKillAfterTimeout = true}) => { + if (forceKillAfterTimeout === true) { + return DEFAULT_FORCE_KILL_TIMEOUT; + } - // Escape meta chars - arg = arg.replace(metaCharsRegExp, '^$1'); + if (!Number.isInteger(forceKillAfterTimeout) || forceKillAfterTimeout < 0) { + throw new TypeError(`Expected the \`forceKillAfterTimeout\` option to be a non-negative integer, got \`${forceKillAfterTimeout}\` (${typeof forceKillAfterTimeout})`); + } - // Double escape meta chars if necessary - if (doubleEscapeMetaChars) { - arg = arg.replace(metaCharsRegExp, '^$1'); - } + return forceKillAfterTimeout; +}; - return arg; -} +// `childProcess.cancel()` +const spawnedCancel = (spawned, context) => { + const killResult = spawned.kill(); -module.exports.command = escapeCommand; -module.exports.argument = escapeArgument; + if (killResult) { + context.isCanceled = true; + } +}; +const timeoutKill = (spawned, signal, reject) => { + spawned.kill(signal); + reject(Object.assign(new Error('Timed out'), {timedOut: true, signal})); +}; -/***/ }), -/* 255 */ -/***/ (function(module, exports, __webpack_require__) { +// `timeout` option handling +const setupTimeout = (spawned, {timeout, killSignal = 'SIGTERM'}, spawnedPromise) => { + if (timeout === 0 || timeout === undefined) { + return spawnedPromise; + } -"use strict"; + if (!Number.isInteger(timeout) || timeout < 0) { + throw new TypeError(`Expected the \`timeout\` option to be a non-negative integer, got \`${timeout}\` (${typeof timeout})`); + } + let timeoutId; + const timeoutPromise = new Promise((resolve, reject) => { + timeoutId = setTimeout(() => { + timeoutKill(spawned, killSignal, reject); + }, timeout); + }); -const fs = __webpack_require__(133); -const shebangCommand = __webpack_require__(256); + const safeSpawnedPromise = spawnedPromise.finally(() => { + clearTimeout(timeoutId); + }); -function readShebang(command) { - // Read the first 150 bytes from the file - const size = 150; - const buffer = Buffer.alloc(size); + return Promise.race([timeoutPromise, safeSpawnedPromise]); +}; - let fd; +// `cleanup` option handling +const setExitHandler = async (spawned, {cleanup, detached}, timedPromise) => { + if (!cleanup || detached) { + return timedPromise; + } - try { - fd = fs.openSync(command, 'r'); - fs.readSync(fd, buffer, 0, size, 0); - fs.closeSync(fd); - } catch (e) { /* Empty */ } + const removeExitHandler = onExit(() => { + spawned.kill(); + }); - // Attempt to extract shebang (null is returned if not a shebang) - return shebangCommand(buffer.toString()); -} + return timedPromise.finally(() => { + removeExitHandler(); + }); +}; -module.exports = readShebang; +module.exports = { + spawnedKill, + spawnedCancel, + setupTimeout, + setExitHandler +}; /***/ }), -/* 256 */ +/* 262 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const shebangRegex = __webpack_require__(257); - -module.exports = (string = '') => { - const match = string.match(shebangRegex); +const isStream = __webpack_require__(263); +const getStream = __webpack_require__(264); +const mergeStream = __webpack_require__(268); - if (!match) { - return null; +// `input` option +const handleInput = (spawned, input) => { + // Checking for stdin is workaround for https://github.com/nodejs/node/issues/26852 + // TODO: Remove `|| spawned.stdin === undefined` once we drop support for Node.js <=12.2.0 + if (input === undefined || spawned.stdin === undefined) { + return; } - const [path, argument] = match[0].replace(/#! ?/, '').split(' '); - const binary = path.split('/').pop(); - - if (binary === 'env') { - return argument; + if (isStream(input)) { + input.pipe(spawned.stdin); + } else { + spawned.stdin.end(input); } - - return argument ? `${binary} ${argument}` : binary; }; +// `all` interleaves `stdout` and `stderr` +const makeAllStream = (spawned, {all}) => { + if (!all || (!spawned.stdout && !spawned.stderr)) { + return; + } -/***/ }), -/* 257 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -module.exports = /^#!(.*)/; - - -/***/ }), -/* 258 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; + const mixed = mergeStream(); + if (spawned.stdout) { + mixed.add(spawned.stdout); + } -const isWin = process.platform === 'win32'; + if (spawned.stderr) { + mixed.add(spawned.stderr); + } -function notFoundError(original, syscall) { - return Object.assign(new Error(`${syscall} ${original.command} ENOENT`), { - code: 'ENOENT', - errno: 'ENOENT', - syscall: `${syscall} ${original.command}`, - path: original.command, - spawnargs: original.args, - }); -} + return mixed; +}; -function hookChildProcess(cp, parsed) { - if (!isWin) { - return; - } +// On failure, `result.stdout|stderr|all` should contain the currently buffered stream +const getBufferedData = async (stream, streamPromise) => { + if (!stream) { + return; + } - const originalEmit = cp.emit; + stream.destroy(); - cp.emit = function (name, arg1) { - // If emitting "exit" event and exit code is 1, we need to check if - // the command exists and emit an "error" instead - // See https://github.com/IndigoUnited/node-cross-spawn/issues/16 - if (name === 'exit') { - const err = verifyENOENT(arg1, parsed, 'spawn'); + try { + return await streamPromise; + } catch (error) { + return error.bufferedData; + } +}; - if (err) { - return originalEmit.call(cp, 'error', err); - } - } +const getStreamPromise = (stream, {encoding, buffer, maxBuffer}) => { + if (!stream || !buffer) { + return; + } - return originalEmit.apply(cp, arguments); // eslint-disable-line prefer-rest-params - }; -} + if (encoding) { + return getStream(stream, {encoding, maxBuffer}); + } -function verifyENOENT(status, parsed) { - if (isWin && status === 1 && !parsed.file) { - return notFoundError(parsed.original, 'spawn'); - } + return getStream.buffer(stream, {maxBuffer}); +}; - return null; -} +// Retrieve result of child process: exit code, signal, error, streams (stdout/stderr/all) +const getSpawnedResult = async ({stdout, stderr, all}, {encoding, buffer, maxBuffer}, processDone) => { + const stdoutPromise = getStreamPromise(stdout, {encoding, buffer, maxBuffer}); + const stderrPromise = getStreamPromise(stderr, {encoding, buffer, maxBuffer}); + const allPromise = getStreamPromise(all, {encoding, buffer, maxBuffer: maxBuffer * 2}); -function verifyENOENTSync(status, parsed) { - if (isWin && status === 1 && !parsed.file) { - return notFoundError(parsed.original, 'spawnSync'); - } + try { + return await Promise.all([processDone, stdoutPromise, stderrPromise, allPromise]); + } catch (error) { + return Promise.all([ + {error, signal: error.signal, timedOut: error.timedOut}, + getBufferedData(stdout, stdoutPromise), + getBufferedData(stderr, stderrPromise), + getBufferedData(all, allPromise) + ]); + } +}; - return null; -} +const validateInputSync = ({input}) => { + if (isStream(input)) { + throw new TypeError('The `input` option cannot be a stream in sync mode'); + } +}; module.exports = { - hookChildProcess, - verifyENOENT, - verifyENOENTSync, - notFoundError, + handleInput, + makeAllStream, + getSpawnedResult, + validateInputSync }; + /***/ }), -/* 259 */ +/* 263 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -module.exports = input => { - const LF = typeof input === 'string' ? '\n' : '\n'.charCodeAt(); - const CR = typeof input === 'string' ? '\r' : '\r'.charCodeAt(); +const isStream = stream => + stream !== null && + typeof stream === 'object' && + typeof stream.pipe === 'function'; - if (input[input.length - 1] === LF) { - input = input.slice(0, input.length - 1); - } +isStream.writable = stream => + isStream(stream) && + stream.writable !== false && + typeof stream._write === 'function' && + typeof stream._writableState === 'object'; - if (input[input.length - 1] === CR) { - input = input.slice(0, input.length - 1); - } +isStream.readable = stream => + isStream(stream) && + stream.readable !== false && + typeof stream._read === 'function' && + typeof stream._readableState === 'object'; - return input; -}; +isStream.duplex = stream => + isStream.writable(stream) && + isStream.readable(stream); + +isStream.transform = stream => + isStream.duplex(stream) && + typeof stream._transform === 'function' && + typeof stream._transformState === 'object'; + +module.exports = isStream; /***/ }), -/* 260 */ +/* 264 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const path = __webpack_require__(4); -const pathKey = __webpack_require__(253); +const pump = __webpack_require__(265); +const bufferStream = __webpack_require__(267); + +class MaxBufferError extends Error { + constructor() { + super('maxBuffer exceeded'); + this.name = 'MaxBufferError'; + } +} + +async function getStream(inputStream, options) { + if (!inputStream) { + return Promise.reject(new Error('Expected a stream')); + } -const npmRunPath = options => { options = { - cwd: process.cwd(), - path: process.env[pathKey()], - execPath: process.execPath, + maxBuffer: Infinity, ...options }; - let previous; - let cwdPath = path.resolve(options.cwd); - const result = []; - - while (previous !== cwdPath) { - result.push(path.join(cwdPath, 'node_modules/.bin')); - previous = cwdPath; - cwdPath = path.resolve(cwdPath, '..'); - } + const {maxBuffer} = options; - // Ensure the running `node` binary is used - const execPathDir = path.resolve(options.cwd, options.execPath, '..'); - result.push(execPathDir); + let stream; + await new Promise((resolve, reject) => { + const rejectPromise = error => { + if (error) { // A null check + error.bufferedData = stream.getBufferedValue(); + } - return result.concat(options.path).join(path.delimiter); -}; + reject(error); + }; -module.exports = npmRunPath; -// TODO: Remove this for the next major release -module.exports.default = npmRunPath; + stream = pump(inputStream, bufferStream(options), error => { + if (error) { + rejectPromise(error); + return; + } -module.exports.env = options => { - options = { - env: process.env, - ...options - }; + resolve(); + }); - const env = {...options.env}; - const path = pathKey({env}); + stream.on('data', () => { + if (stream.getBufferedLength() > maxBuffer) { + rejectPromise(new MaxBufferError()); + } + }); + }); - options.path = env[path]; - env[path] = module.exports(options); + return stream.getBufferedValue(); +} - return env; -}; +module.exports = getStream; +// TODO: Remove this for the next major release +module.exports.default = getStream; +module.exports.buffer = (stream, options) => getStream(stream, {...options, encoding: 'buffer'}); +module.exports.array = (stream, options) => getStream(stream, {...options, array: true}); +module.exports.MaxBufferError = MaxBufferError; /***/ }), -/* 261 */ +/* 265 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; +var once = __webpack_require__(161) +var eos = __webpack_require__(266) +var fs = __webpack_require__(133) // we only need fs to get the ReadStream and WriteStream prototypes -const mimicFn = __webpack_require__(262); +var noop = function () {} +var ancient = /^v?\.0/.test(process.version) -const calledFunctions = new WeakMap(); +var isFn = function (fn) { + return typeof fn === 'function' +} -const oneTime = (fn, options = {}) => { - if (typeof fn !== 'function') { - throw new TypeError('Expected a function'); - } +var isFS = function (stream) { + if (!ancient) return false // newer node version do not need to care about fs is a special way + if (!fs) return false // browser + return (stream instanceof (fs.ReadStream || noop) || stream instanceof (fs.WriteStream || noop)) && isFn(stream.close) +} - let ret; - let isCalled = false; - let callCount = 0; - const functionName = fn.displayName || fn.name || ''; +var isRequest = function (stream) { + return stream.setHeader && isFn(stream.abort) +} - const onetime = function (...args) { - calledFunctions.set(onetime, ++callCount); +var destroyer = function (stream, reading, writing, callback) { + callback = once(callback) - if (isCalled) { - if (options.throw === true) { - throw new Error(`Function \`${functionName}\` can only be called once`); - } + var closed = false + stream.on('close', function () { + closed = true + }) - return ret; - } + eos(stream, {readable: reading, writable: writing}, function (err) { + if (err) return callback(err) + closed = true + callback() + }) - isCalled = true; - ret = fn.apply(this, args); - fn = null; + var destroyed = false + return function (err) { + if (closed) return + if (destroyed) return + destroyed = true - return ret; - }; + if (isFS(stream)) return stream.close(noop) // use close for fs streams to avoid fd leaks + if (isRequest(stream)) return stream.abort() // request.destroy just do .end - .abort is what we want - mimicFn(onetime, fn); - calledFunctions.set(onetime, callCount); + if (isFn(stream.destroy)) return stream.destroy() - return onetime; -}; + callback(err || new Error('stream was destroyed')) + } +} -module.exports = oneTime; -// TODO: Remove this for the next major release -module.exports.default = oneTime; +var call = function (fn) { + fn() +} -module.exports.callCount = fn => { - if (!calledFunctions.has(fn)) { - throw new Error(`The given function \`${fn.name}\` is not wrapped by the \`onetime\` package`); - } +var pipe = function (from, to) { + return from.pipe(to) +} - return calledFunctions.get(fn); -}; +var pump = function () { + var streams = Array.prototype.slice.call(arguments) + var callback = isFn(streams[streams.length - 1] || noop) && streams.pop() || noop + + if (Array.isArray(streams[0])) streams = streams[0] + if (streams.length < 2) throw new Error('pump requires two streams per minimum') + + var error + var destroys = streams.map(function (stream, i) { + var reading = i < streams.length - 1 + var writing = i > 0 + return destroyer(stream, reading, writing, function (err) { + if (!error) error = err + if (err) destroys.forEach(call) + if (reading) return + destroys.forEach(call) + callback(error) + }) + }) + + return streams.reduce(pipe) +} + +module.exports = pump /***/ }), -/* 262 */ +/* 266 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; - +var once = __webpack_require__(161); -const mimicFn = (to, from) => { - for (const prop of Reflect.ownKeys(from)) { - Object.defineProperty(to, prop, Object.getOwnPropertyDescriptor(from, prop)); - } +var noop = function() {}; - return to; +var isRequest = function(stream) { + return stream.setHeader && typeof stream.abort === 'function'; }; -module.exports = mimicFn; -// TODO: Remove this for the next major release -module.exports.default = mimicFn; +var isChildProcess = function(stream) { + return stream.stdio && Array.isArray(stream.stdio) && stream.stdio.length === 3 +}; +var eos = function(stream, opts, callback) { + if (typeof opts === 'function') return eos(stream, null, opts); + if (!opts) opts = {}; -/***/ }), -/* 263 */ -/***/ (function(module, exports, __webpack_require__) { + callback = once(callback || noop); -"use strict"; + var ws = stream._writableState; + var rs = stream._readableState; + var readable = opts.readable || (opts.readable !== false && stream.readable); + var writable = opts.writable || (opts.writable !== false && stream.writable); -const {signalsByName} = __webpack_require__(264); + var onlegacyfinish = function() { + if (!stream.writable) onfinish(); + }; -const getErrorPrefix = ({timedOut, timeout, errorCode, signal, signalDescription, exitCode, isCanceled}) => { - if (timedOut) { - return `timed out after ${timeout} milliseconds`; - } + var onfinish = function() { + writable = false; + if (!readable) callback.call(stream); + }; - if (isCanceled) { - return 'was canceled'; - } + var onend = function() { + readable = false; + if (!writable) callback.call(stream); + }; - if (errorCode !== undefined) { - return `failed with ${errorCode}`; - } + var onexit = function(exitCode) { + callback.call(stream, exitCode ? new Error('exited with error code: ' + exitCode) : null); + }; - if (signal !== undefined) { - return `was killed with ${signal} (${signalDescription})`; - } + var onerror = function(err) { + callback.call(stream, err); + }; - if (exitCode !== undefined) { - return `failed with exit code ${exitCode}`; + var onclose = function() { + if (readable && !(rs && rs.ended)) return callback.call(stream, new Error('premature close')); + if (writable && !(ws && ws.ended)) return callback.call(stream, new Error('premature close')); + }; + + var onrequest = function() { + stream.req.on('finish', onfinish); + }; + + if (isRequest(stream)) { + stream.on('complete', onfinish); + stream.on('abort', onclose); + if (stream.req) onrequest(); + else stream.on('request', onrequest); + } else if (writable && !ws) { // legacy streams + stream.on('end', onlegacyfinish); + stream.on('close', onlegacyfinish); } - return 'failed'; -}; + if (isChildProcess(stream)) stream.on('exit', onexit); -const makeError = ({ - stdout, - stderr, - all, - error, - signal, - exitCode, - command, - timedOut, - isCanceled, - killed, - parsed: {options: {timeout}} -}) => { - // `signal` and `exitCode` emitted on `spawned.on('exit')` event can be `null`. - // We normalize them to `undefined` - exitCode = exitCode === null ? undefined : exitCode; - signal = signal === null ? undefined : signal; - const signalDescription = signal === undefined ? undefined : signalsByName[signal].description; + stream.on('end', onend); + stream.on('finish', onfinish); + if (opts.error !== false) stream.on('error', onerror); + stream.on('close', onclose); - const errorCode = error && error.code; + return function() { + stream.removeListener('complete', onfinish); + stream.removeListener('abort', onclose); + stream.removeListener('request', onrequest); + if (stream.req) stream.req.removeListener('finish', onfinish); + stream.removeListener('end', onlegacyfinish); + stream.removeListener('close', onlegacyfinish); + stream.removeListener('finish', onfinish); + stream.removeListener('exit', onexit); + stream.removeListener('end', onend); + stream.removeListener('error', onerror); + stream.removeListener('close', onclose); + }; +}; - const prefix = getErrorPrefix({timedOut, timeout, errorCode, signal, signalDescription, exitCode, isCanceled}); - const execaMessage = `Command ${prefix}: ${command}`; - const isError = Object.prototype.toString.call(error) === '[object Error]'; - const shortMessage = isError ? `${execaMessage}\n${error.message}` : execaMessage; - const message = [shortMessage, stderr, stdout].filter(Boolean).join('\n'); +module.exports = eos; - if (isError) { - error.originalMessage = error.message; - error.message = message; - } else { - error = new Error(message); - } - error.shortMessage = shortMessage; - error.command = command; - error.exitCode = exitCode; - error.signal = signal; - error.signalDescription = signalDescription; - error.stdout = stdout; - error.stderr = stderr; +/***/ }), +/* 267 */ +/***/ (function(module, exports, __webpack_require__) { - if (all !== undefined) { - error.all = all; - } +"use strict"; - if ('bufferedData' in error) { - delete error.bufferedData; - } +const {PassThrough: PassThroughStream} = __webpack_require__(137); - error.failed = true; - error.timedOut = Boolean(timedOut); - error.isCanceled = isCanceled; - error.killed = killed && !timedOut; +module.exports = options => { + options = {...options}; - return error; -}; + const {array} = options; + let {encoding} = options; + const isBuffer = encoding === 'buffer'; + let objectMode = false; -module.exports = makeError; + if (array) { + objectMode = !(encoding || isBuffer); + } else { + encoding = encoding || 'utf8'; + } + if (isBuffer) { + encoding = null; + } -/***/ }), -/* 264 */ -/***/ (function(module, exports, __webpack_require__) { + const stream = new PassThroughStream({objectMode}); -"use strict"; -Object.defineProperty(exports,"__esModule",{value:true});exports.signalsByNumber=exports.signalsByName=void 0;var _os=__webpack_require__(120); + if (encoding) { + stream.setEncoding(encoding); + } + + let length = 0; + const chunks = []; -var _signals=__webpack_require__(265); -var _realtime=__webpack_require__(267); + stream.on('data', chunk => { + chunks.push(chunk); + if (objectMode) { + length = chunks.length; + } else { + length += chunk.length; + } + }); + stream.getBufferedValue = () => { + if (array) { + return chunks; + } -const getSignalsByName=function(){ -const signals=(0,_signals.getSignals)(); -return signals.reduce(getSignalByName,{}); -}; + return isBuffer ? Buffer.concat(chunks, length) : chunks.join(''); + }; -const getSignalByName=function( -signalByNameMemo, -{name,number,description,supported,action,forced,standard}) -{ -return{ -...signalByNameMemo, -[name]:{name,number,description,supported,action,forced,standard}}; + stream.getBufferedLength = () => length; + return stream; }; -const signalsByName=getSignalsByName();exports.signalsByName=signalsByName; +/***/ }), +/* 268 */ +/***/ (function(module, exports, __webpack_require__) { +"use strict"; -const getSignalsByNumber=function(){ -const signals=(0,_signals.getSignals)(); -const length=_realtime.SIGRTMAX+1; -const signalsA=Array.from({length},(value,number)=> -getSignalByNumber(number,signals)); +const { PassThrough } = __webpack_require__(137); -return Object.assign({},...signalsA); -}; +module.exports = function (/*streams...*/) { + var sources = [] + var output = new PassThrough({objectMode: true}) -const getSignalByNumber=function(number,signals){ -const signal=findSignalByNumber(number,signals); + output.setMaxListeners(0) -if(signal===undefined){ -return{}; -} + output.add = add + output.isEmpty = isEmpty -const{name,description,supported,action,forced,standard}=signal; -return{ -[number]:{ -name, -number, -description, -supported, -action, -forced, -standard}}; + output.on('unpipe', remove) + Array.prototype.slice.call(arguments).forEach(add) -}; + return output + function add (source) { + if (Array.isArray(source)) { + source.forEach(add) + return this + } + sources.push(source); + source.once('end', remove.bind(null, source)) + source.once('error', output.emit.bind(output, 'error')) + source.pipe(output, {end: false}) + return this + } -const findSignalByNumber=function(number,signals){ -const signal=signals.find(({name})=>_os.constants.signals[name]===number); + function isEmpty () { + return sources.length == 0; + } -if(signal!==undefined){ -return signal; + function remove (source) { + sources = sources.filter(function (it) { return it !== source }) + if (!sources.length && output.readable) { output.end() } + } } -return signals.find(signalA=>signalA.number===number); -}; - -const signalsByNumber=getSignalsByNumber();exports.signalsByNumber=signalsByNumber; -//# sourceMappingURL=main.js.map /***/ }), -/* 265 */ +/* 269 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -Object.defineProperty(exports,"__esModule",{value:true});exports.getSignals=void 0;var _os=__webpack_require__(120); -var _core=__webpack_require__(266); -var _realtime=__webpack_require__(267); +const nativePromisePrototype = (async () => {})().constructor.prototype; +const descriptors = ['then', 'catch', 'finally'].map(property => [ + property, + Reflect.getOwnPropertyDescriptor(nativePromisePrototype, property) +]); +// The return value is a mixin of `childProcess` and `Promise` +const mergePromise = (spawned, promise) => { + for (const [property, descriptor] of descriptors) { + // Starting the main `promise` is deferred to avoid consuming streams + const value = typeof promise === 'function' ? + (...args) => Reflect.apply(descriptor.value, promise(), args) : + descriptor.value.bind(promise); -const getSignals=function(){ -const realtimeSignals=(0,_realtime.getRealtimeSignals)(); -const signals=[..._core.SIGNALS,...realtimeSignals].map(normalizeSignal); -return signals; -};exports.getSignals=getSignals; + Reflect.defineProperty(spawned, property, {...descriptor, value}); + } + return spawned; +}; +// Use promises instead of `child_process` events +const getSpawnedPromise = spawned => { + return new Promise((resolve, reject) => { + spawned.on('exit', (exitCode, signal) => { + resolve({exitCode, signal}); + }); + spawned.on('error', error => { + reject(error); + }); + if (spawned.stdin) { + spawned.stdin.on('error', error => { + reject(error); + }); + } + }); +}; +module.exports = { + mergePromise, + getSpawnedPromise +}; -const normalizeSignal=function({ -name, -number:defaultNumber, -description, -action, -forced=false, -standard}) -{ -const{ -signals:{[name]:constantSignal}}= -_os.constants; -const supported=constantSignal!==undefined; -const number=supported?constantSignal:defaultNumber; -return{name,number,description,supported,action,forced,standard}; -}; -//# sourceMappingURL=signals.js.map /***/ }), -/* 266 */ +/* 270 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -Object.defineProperty(exports,"__esModule",{value:true});exports.SIGNALS=void 0; -const SIGNALS=[ -{ -name:"SIGHUP", -number:1, -action:"terminate", -description:"Terminal closed", -standard:"posix"}, +const SPACES_REGEXP = / +/g; -{ -name:"SIGINT", -number:2, -action:"terminate", -description:"User interruption with CTRL-C", -standard:"ansi"}, +const joinCommand = (file, args = []) => { + if (!Array.isArray(args)) { + return file; + } -{ -name:"SIGQUIT", -number:3, -action:"core", -description:"User interruption with CTRL-\\", -standard:"posix"}, + return [file, ...args].join(' '); +}; -{ -name:"SIGILL", -number:4, -action:"core", -description:"Invalid machine instruction", -standard:"ansi"}, +// Allow spaces to be escaped by a backslash if not meant as a delimiter +const handleEscaping = (tokens, token, index) => { + if (index === 0) { + return [token]; + } -{ -name:"SIGTRAP", -number:5, -action:"core", -description:"Debugger breakpoint", -standard:"posix"}, + const previousToken = tokens[tokens.length - 1]; -{ -name:"SIGABRT", -number:6, -action:"core", -description:"Aborted", -standard:"ansi"}, + if (previousToken.endsWith('\\')) { + return [...tokens.slice(0, -1), `${previousToken.slice(0, -1)} ${token}`]; + } -{ -name:"SIGIOT", -number:6, -action:"core", -description:"Aborted", -standard:"bsd"}, + return [...tokens, token]; +}; -{ -name:"SIGBUS", -number:7, -action:"core", -description: -"Bus error due to misaligned, non-existing address or paging error", -standard:"bsd"}, +// Handle `execa.command()` +const parseCommand = command => { + return command + .trim() + .split(SPACES_REGEXP) + .reduce(handleEscaping, []); +}; -{ -name:"SIGEMT", -number:7, -action:"terminate", -description:"Command should be emulated but is not implemented", -standard:"other"}, +module.exports = { + joinCommand, + parseCommand +}; -{ -name:"SIGFPE", -number:8, -action:"core", -description:"Floating point arithmetic error", -standard:"ansi"}, -{ -name:"SIGKILL", -number:9, -action:"terminate", -description:"Forced termination", -standard:"posix", -forced:true}, +/***/ }), +/* 271 */ +/***/ (function(module, exports, __webpack_require__) { -{ -name:"SIGUSR1", -number:10, -action:"terminate", -description:"Application-specific signal", -standard:"posix"}, +// Copyright IBM Corp. 2014,2018. All Rights Reserved. +// Node module: strong-log-transformer +// This file is licensed under the Apache License 2.0. +// License text available at https://opensource.org/licenses/Apache-2.0 -{ -name:"SIGSEGV", -number:11, -action:"core", -description:"Segmentation fault", -standard:"ansi"}, +module.exports = __webpack_require__(272); +module.exports.cli = __webpack_require__(276); -{ -name:"SIGUSR2", -number:12, -action:"terminate", -description:"Application-specific signal", -standard:"posix"}, -{ -name:"SIGPIPE", -number:13, -action:"terminate", -description:"Broken pipe or socket", -standard:"posix"}, +/***/ }), +/* 272 */ +/***/ (function(module, exports, __webpack_require__) { -{ -name:"SIGALRM", -number:14, -action:"terminate", -description:"Timeout or timer", -standard:"posix"}, +"use strict"; +// Copyright IBM Corp. 2014,2018. All Rights Reserved. +// Node module: strong-log-transformer +// This file is licensed under the Apache License 2.0. +// License text available at https://opensource.org/licenses/Apache-2.0 -{ -name:"SIGTERM", -number:15, -action:"terminate", -description:"Termination", -standard:"ansi"}, -{ -name:"SIGSTKFLT", -number:16, -action:"terminate", -description:"Stack is empty or overflowed", -standard:"other"}, -{ -name:"SIGCHLD", -number:17, -action:"ignore", -description:"Child process terminated, paused or unpaused", -standard:"posix"}, +var stream = __webpack_require__(137); +var util = __webpack_require__(111); +var fs = __webpack_require__(133); -{ -name:"SIGCLD", -number:17, -action:"ignore", -description:"Child process terminated, paused or unpaused", -standard:"other"}, +var through = __webpack_require__(273); +var duplexer = __webpack_require__(274); +var StringDecoder = __webpack_require__(275).StringDecoder; -{ -name:"SIGCONT", -number:18, -action:"unpause", -description:"Unpaused", -standard:"posix", -forced:true}, +module.exports = Logger; -{ -name:"SIGSTOP", -number:19, -action:"pause", -description:"Paused", -standard:"posix", -forced:true}, +Logger.DEFAULTS = { + format: 'text', + tag: '', + mergeMultiline: false, + timeStamp: false, +}; -{ -name:"SIGTSTP", -number:20, -action:"pause", -description:"Paused using CTRL-Z or \"suspend\"", -standard:"posix"}, +var formatters = { + text: textFormatter, + json: jsonFormatter, +} -{ -name:"SIGTTIN", -number:21, -action:"pause", -description:"Background process cannot read terminal input", -standard:"posix"}, +function Logger(options) { + var defaults = JSON.parse(JSON.stringify(Logger.DEFAULTS)); + options = util._extend(defaults, options || {}); + var catcher = deLiner(); + var emitter = catcher; + var transforms = [ + objectifier(), + ]; -{ -name:"SIGBREAK", -number:21, -action:"terminate", -description:"User interruption with CTRL-BREAK", -standard:"other"}, + if (options.tag) { + transforms.push(staticTagger(options.tag)); + } -{ -name:"SIGTTOU", -number:22, -action:"pause", -description:"Background process cannot write to terminal output", -standard:"posix"}, + if (options.mergeMultiline) { + transforms.push(lineMerger()); + } -{ -name:"SIGURG", -number:23, -action:"ignore", -description:"Socket received out-of-band data", -standard:"bsd"}, - -{ -name:"SIGXCPU", -number:24, -action:"core", -description:"Process timed out", -standard:"bsd"}, + // TODO + // if (options.pidStamp) { + // transforms.push(pidStamper(options.pid)); + // } -{ -name:"SIGXFSZ", -number:25, -action:"core", -description:"File too big", -standard:"bsd"}, + // TODO + // if (options.workerStamp) { + // transforms.push(workerStamper(options.worker)); + // } -{ -name:"SIGVTALRM", -number:26, -action:"terminate", -description:"Timeout or timer", -standard:"bsd"}, + transforms.push(formatters[options.format](options)); -{ -name:"SIGPROF", -number:27, -action:"terminate", -description:"Timeout or timer", -standard:"bsd"}, + // restore line endings that were removed by line splitting + transforms.push(reLiner()); -{ -name:"SIGWINCH", -number:28, -action:"ignore", -description:"Terminal window size changed", -standard:"bsd"}, + for (var t in transforms) { + emitter = emitter.pipe(transforms[t]); + } -{ -name:"SIGIO", -number:29, -action:"terminate", -description:"I/O is available", -standard:"other"}, + return duplexer(catcher, emitter); +} -{ -name:"SIGPOLL", -number:29, -action:"terminate", -description:"Watched event", -standard:"other"}, +function deLiner() { + var decoder = new StringDecoder('utf8'); + var last = ''; -{ -name:"SIGINFO", -number:29, -action:"ignore", -description:"Request for process information", -standard:"other"}, + return new stream.Transform({ + transform(chunk, _enc, callback) { + last += decoder.write(chunk); + var list = last.split(/\r\n|[\n\v\f\r\x85\u2028\u2029]/g); + last = list.pop(); + for (var i = 0; i < list.length; i++) { + // swallow empty lines + if (list[i]) { + this.push(list[i]); + } + } + callback(); + }, + flush(callback) { + // incomplete UTF8 sequences become UTF8 replacement characters + last += decoder.end(); + if (last) { + this.push(last); + } + callback(); + }, + }); +} -{ -name:"SIGPWR", -number:30, -action:"terminate", -description:"Device running out of power", -standard:"systemv"}, +function reLiner() { + return through(appendNewline); -{ -name:"SIGSYS", -number:31, -action:"core", -description:"Invalid system call", -standard:"other"}, + function appendNewline(line) { + this.emit('data', line + '\n'); + } +} -{ -name:"SIGUNUSED", -number:31, -action:"terminate", -description:"Invalid system call", -standard:"other"}];exports.SIGNALS=SIGNALS; -//# sourceMappingURL=core.js.map +function objectifier() { + return through(objectify, null, {autoDestroy: false}); -/***/ }), -/* 267 */ -/***/ (function(module, exports, __webpack_require__) { + function objectify(line) { + this.emit('data', { + msg: line, + time: Date.now(), + }); + } +} -"use strict"; -Object.defineProperty(exports,"__esModule",{value:true});exports.SIGRTMAX=exports.getRealtimeSignals=void 0; -const getRealtimeSignals=function(){ -const length=SIGRTMAX-SIGRTMIN+1; -return Array.from({length},getRealtimeSignal); -};exports.getRealtimeSignals=getRealtimeSignals; +function staticTagger(tag) { + return through(tagger); -const getRealtimeSignal=function(value,index){ -return{ -name:`SIGRT${index+1}`, -number:SIGRTMIN+index, -action:"terminate", -description:"Application-specific signal (realtime)", -standard:"posix"}; + function tagger(logEvent) { + logEvent.tag = tag; + this.emit('data', logEvent); + } +} -}; +function textFormatter(options) { + return through(textify); -const SIGRTMIN=34; -const SIGRTMAX=64;exports.SIGRTMAX=SIGRTMAX; -//# sourceMappingURL=realtime.js.map + function textify(logEvent) { + var line = util.format('%s%s', textifyTags(logEvent.tag), + logEvent.msg.toString()); + if (options.timeStamp) { + line = util.format('%s %s', new Date(logEvent.time).toISOString(), line); + } + this.emit('data', line.replace(/\n/g, '\\n')); + } -/***/ }), -/* 268 */ -/***/ (function(module, exports, __webpack_require__) { + function textifyTags(tags) { + var str = ''; + if (typeof tags === 'string') { + str = tags + ' '; + } else if (typeof tags === 'object') { + for (var t in tags) { + str += t + ':' + tags[t] + ' '; + } + } + return str; + } +} -"use strict"; +function jsonFormatter(options) { + return through(jsonify); -const aliases = ['stdin', 'stdout', 'stderr']; + function jsonify(logEvent) { + if (options.timeStamp) { + logEvent.time = new Date(logEvent.time).toISOString(); + } else { + delete logEvent.time; + } + logEvent.msg = logEvent.msg.toString(); + this.emit('data', JSON.stringify(logEvent)); + } +} -const hasAlias = opts => aliases.some(alias => opts[alias] !== undefined); +function lineMerger(host) { + var previousLine = null; + var flushTimer = null; + var stream = through(lineMergerWrite, lineMergerEnd); + var flush = _flush.bind(stream); -const normalizeStdio = opts => { - if (!opts) { - return; - } + return stream; - const {stdio} = opts; + function lineMergerWrite(line) { + if (/^\s+/.test(line.msg)) { + if (previousLine) { + previousLine.msg += '\n' + line.msg; + } else { + previousLine = line; + } + } else { + flush(); + previousLine = line; + } + // rolling timeout + clearTimeout(flushTimer); + flushTimer = setTimeout(flush.bind(this), 10); + } - if (stdio === undefined) { - return aliases.map(alias => opts[alias]); - } + function _flush() { + if (previousLine) { + this.emit('data', previousLine); + previousLine = null; + } + } - if (hasAlias(opts)) { - throw new Error(`It's not possible to provide \`stdio\` in combination with one of ${aliases.map(alias => `\`${alias}\``).join(', ')}`); - } + function lineMergerEnd() { + flush.call(this); + this.emit('end'); + } +} - if (typeof stdio === 'string') { - return stdio; - } - if (!Array.isArray(stdio)) { - throw new TypeError(`Expected \`stdio\` to be of type \`string\` or \`Array\`, got \`${typeof stdio}\``); - } +/***/ }), +/* 273 */ +/***/ (function(module, exports, __webpack_require__) { - const length = Math.max(stdio.length, aliases.length); - return Array.from({length}, (value, index) => stdio[index]); -}; +var Stream = __webpack_require__(137) -module.exports = normalizeStdio; +// through +// +// a stream that does nothing but re-emit the input. +// useful for aggregating a series of changing but not ending streams into one stream) -// `ipc` is pushed unless it is already present -module.exports.node = opts => { - const stdio = normalizeStdio(opts); +exports = module.exports = through +through.through = through - if (stdio === 'ipc') { - return 'ipc'; - } +//create a readable writable stream. - if (stdio === undefined || typeof stdio === 'string') { - return [stdio, stdio, stdio, 'ipc']; - } +function through (write, end, opts) { + write = write || function (data) { this.queue(data) } + end = end || function () { this.queue(null) } - if (stdio.includes('ipc')) { - return stdio; - } + var ended = false, destroyed = false, buffer = [], _ended = false + var stream = new Stream() + stream.readable = stream.writable = true + stream.paused = false - return [...stdio, 'ipc']; -}; +// stream.autoPause = !(opts && opts.autoPause === false) + stream.autoDestroy = !(opts && opts.autoDestroy === false) + stream.write = function (data) { + write.call(this, data) + return !stream.paused + } -/***/ }), -/* 269 */ -/***/ (function(module, exports, __webpack_require__) { + function drain() { + while(buffer.length && !stream.paused) { + var data = buffer.shift() + if(null === data) + return stream.emit('end') + else + stream.emit('data', data) + } + } -"use strict"; + stream.queue = stream.push = function (data) { +// console.error(ended) + if(_ended) return stream + if(data === null) _ended = true + buffer.push(data) + drain() + return stream + } -const os = __webpack_require__(120); -const onExit = __webpack_require__(225); + //this will be registered as the first 'end' listener + //must call destroy next tick, to make sure we're after any + //stream piped from here. + //this is only a problem if end is not emitted synchronously. + //a nicer way to do this is to make sure this is the last listener for 'end' -const DEFAULT_FORCE_KILL_TIMEOUT = 1000 * 5; + stream.on('end', function () { + stream.readable = false + if(!stream.writable && stream.autoDestroy) + process.nextTick(function () { + stream.destroy() + }) + }) -// Monkey-patches `childProcess.kill()` to add `forceKillAfterTimeout` behavior -const spawnedKill = (kill, signal = 'SIGTERM', options = {}) => { - const killResult = kill(signal); - setKillTimeout(kill, signal, options, killResult); - return killResult; -}; + function _end () { + stream.writable = false + end.call(stream) + if(!stream.readable && stream.autoDestroy) + stream.destroy() + } -const setKillTimeout = (kill, signal, options, killResult) => { - if (!shouldForceKill(signal, options, killResult)) { - return; - } + stream.end = function (data) { + if(ended) return + ended = true + if(arguments.length) stream.write(data) + _end() // will emit or queue + return stream + } - const timeout = getForceKillAfterTimeout(options); - const t = setTimeout(() => { - kill('SIGKILL'); - }, timeout); + stream.destroy = function () { + if(destroyed) return + destroyed = true + ended = true + buffer.length = 0 + stream.writable = stream.readable = false + stream.emit('close') + return stream + } - // Guarded because there's no `.unref()` when `execa` is used in the renderer - // process in Electron. This cannot be tested since we don't run tests in - // Electron. - // istanbul ignore else - if (t.unref) { - t.unref(); - } -}; + stream.pause = function () { + if(stream.paused) return + stream.paused = true + return stream + } -const shouldForceKill = (signal, {forceKillAfterTimeout}, killResult) => { - return isSigterm(signal) && forceKillAfterTimeout !== false && killResult; -}; + stream.resume = function () { + if(stream.paused) { + stream.paused = false + stream.emit('resume') + } + drain() + //may have become paused again, + //as drain emits 'data'. + if(!stream.paused) + stream.emit('drain') + return stream + } + return stream +} -const isSigterm = signal => { - return signal === os.constants.signals.SIGTERM || - (typeof signal === 'string' && signal.toUpperCase() === 'SIGTERM'); -}; -const getForceKillAfterTimeout = ({forceKillAfterTimeout = true}) => { - if (forceKillAfterTimeout === true) { - return DEFAULT_FORCE_KILL_TIMEOUT; - } - if (!Number.isInteger(forceKillAfterTimeout) || forceKillAfterTimeout < 0) { - throw new TypeError(`Expected the \`forceKillAfterTimeout\` option to be a non-negative integer, got \`${forceKillAfterTimeout}\` (${typeof forceKillAfterTimeout})`); - } +/***/ }), +/* 274 */ +/***/ (function(module, exports, __webpack_require__) { - return forceKillAfterTimeout; -}; +var Stream = __webpack_require__(137) +var writeMethods = ["write", "end", "destroy"] +var readMethods = ["resume", "pause"] +var readEvents = ["data", "close"] +var slice = Array.prototype.slice -// `childProcess.cancel()` -const spawnedCancel = (spawned, context) => { - const killResult = spawned.kill(); +module.exports = duplex - if (killResult) { - context.isCanceled = true; - } -}; +function forEach (arr, fn) { + if (arr.forEach) { + return arr.forEach(fn) + } -const timeoutKill = (spawned, signal, reject) => { - spawned.kill(signal); - reject(Object.assign(new Error('Timed out'), {timedOut: true, signal})); -}; + for (var i = 0; i < arr.length; i++) { + fn(arr[i], i) + } +} -// `timeout` option handling -const setupTimeout = (spawned, {timeout, killSignal = 'SIGTERM'}, spawnedPromise) => { - if (timeout === 0 || timeout === undefined) { - return spawnedPromise; - } +function duplex(writer, reader) { + var stream = new Stream() + var ended = false - if (!Number.isInteger(timeout) || timeout < 0) { - throw new TypeError(`Expected the \`timeout\` option to be a non-negative integer, got \`${timeout}\` (${typeof timeout})`); - } + forEach(writeMethods, proxyWriter) - let timeoutId; - const timeoutPromise = new Promise((resolve, reject) => { - timeoutId = setTimeout(() => { - timeoutKill(spawned, killSignal, reject); - }, timeout); - }); + forEach(readMethods, proxyReader) - const safeSpawnedPromise = spawnedPromise.finally(() => { - clearTimeout(timeoutId); - }); + forEach(readEvents, proxyStream) - return Promise.race([timeoutPromise, safeSpawnedPromise]); -}; + reader.on("end", handleEnd) -// `cleanup` option handling -const setExitHandler = async (spawned, {cleanup, detached}, timedPromise) => { - if (!cleanup || detached) { - return timedPromise; - } + writer.on("drain", function() { + stream.emit("drain") + }) - const removeExitHandler = onExit(() => { - spawned.kill(); - }); + writer.on("error", reemit) + reader.on("error", reemit) - return timedPromise.finally(() => { - removeExitHandler(); - }); -}; + stream.writable = writer.writable + stream.readable = reader.readable -module.exports = { - spawnedKill, - spawnedCancel, - setupTimeout, - setExitHandler -}; + return stream + function proxyWriter(methodName) { + stream[methodName] = method -/***/ }), -/* 270 */ -/***/ (function(module, exports, __webpack_require__) { + function method() { + return writer[methodName].apply(writer, arguments) + } + } -"use strict"; + function proxyReader(methodName) { + stream[methodName] = method -const isStream = __webpack_require__(271); -const getStream = __webpack_require__(272); -const mergeStream = __webpack_require__(276); + function method() { + stream.emit(methodName) + var func = reader[methodName] + if (func) { + return func.apply(reader, arguments) + } + reader.emit(methodName) + } + } -// `input` option -const handleInput = (spawned, input) => { - // Checking for stdin is workaround for https://github.com/nodejs/node/issues/26852 - // TODO: Remove `|| spawned.stdin === undefined` once we drop support for Node.js <=12.2.0 - if (input === undefined || spawned.stdin === undefined) { - return; - } + function proxyStream(methodName) { + reader.on(methodName, reemit) - if (isStream(input)) { - input.pipe(spawned.stdin); - } else { - spawned.stdin.end(input); - } -}; + function reemit() { + var args = slice.call(arguments) + args.unshift(methodName) + stream.emit.apply(stream, args) + } + } -// `all` interleaves `stdout` and `stderr` -const makeAllStream = (spawned, {all}) => { - if (!all || (!spawned.stdout && !spawned.stderr)) { - return; - } + function handleEnd() { + if (ended) { + return + } + ended = true + var args = slice.call(arguments) + args.unshift("end") + stream.emit.apply(stream, args) + } - const mixed = mergeStream(); + function reemit(err) { + stream.emit("error", err) + } +} - if (spawned.stdout) { - mixed.add(spawned.stdout); - } - if (spawned.stderr) { - mixed.add(spawned.stderr); - } +/***/ }), +/* 275 */ +/***/ (function(module, exports) { - return mixed; -}; +module.exports = require("string_decoder"); -// On failure, `result.stdout|stderr|all` should contain the currently buffered stream -const getBufferedData = async (stream, streamPromise) => { - if (!stream) { - return; - } +/***/ }), +/* 276 */ +/***/ (function(module, exports, __webpack_require__) { - stream.destroy(); +"use strict"; +// Copyright IBM Corp. 2014,2018. All Rights Reserved. +// Node module: strong-log-transformer +// This file is licensed under the Apache License 2.0. +// License text available at https://opensource.org/licenses/Apache-2.0 - try { - return await streamPromise; - } catch (error) { - return error.bufferedData; - } -}; -const getStreamPromise = (stream, {encoding, buffer, maxBuffer}) => { - if (!stream || !buffer) { - return; - } - if (encoding) { - return getStream(stream, {encoding, maxBuffer}); - } +var minimist = __webpack_require__(277); +var path = __webpack_require__(4); - return getStream.buffer(stream, {maxBuffer}); -}; +var Logger = __webpack_require__(272); +var pkg = __webpack_require__(278); -// Retrieve result of child process: exit code, signal, error, streams (stdout/stderr/all) -const getSpawnedResult = async ({stdout, stderr, all}, {encoding, buffer, maxBuffer}, processDone) => { - const stdoutPromise = getStreamPromise(stdout, {encoding, buffer, maxBuffer}); - const stderrPromise = getStreamPromise(stderr, {encoding, buffer, maxBuffer}); - const allPromise = getStreamPromise(all, {encoding, buffer, maxBuffer: maxBuffer * 2}); +module.exports = cli; - try { - return await Promise.all([processDone, stdoutPromise, stderrPromise, allPromise]); - } catch (error) { - return Promise.all([ - {error, signal: error.signal, timedOut: error.timedOut}, - getBufferedData(stdout, stdoutPromise), - getBufferedData(stderr, stderrPromise), - getBufferedData(all, allPromise) - ]); - } -}; +function cli(args) { + var opts = minimist(args.slice(2)); + var $0 = path.basename(args[1]); + var p = console.log.bind(console); + if (opts.v || opts.version) { + version($0, p); + } else if (opts.h || opts.help) { + usage($0, p); + } else if (args.length < 3) { + process.stdin.pipe(Logger()).pipe(process.stdout); + } else { + process.stdin.pipe(Logger(opts)).pipe(process.stdout); + } +} -const validateInputSync = ({input}) => { - if (isStream(input)) { - throw new TypeError('The `input` option cannot be a stream in sync mode'); - } -}; +function version($0, p) { + p('%s v%s', pkg.name, pkg.version); +} -module.exports = { - handleInput, - makeAllStream, - getSpawnedResult, - validateInputSync -}; +function usage($0, p) { + var PADDING = ' '; + var opt, def; + p('Usage: %s [options]', $0); + p(''); + p('%s', pkg.description); + p(''); + p('OPTIONS:'); + for (opt in Logger.DEFAULTS) { + def = Logger.DEFAULTS[opt]; + if (typeof def === 'boolean') + boolOpt(opt, Logger.DEFAULTS[opt]); + else + stdOpt(opt, Logger.DEFAULTS[opt]); + } + p(''); + function boolOpt(name, def) { + name = name + PADDING.slice(0, 20-name.length); + p(' --%s default: %s', name, def); + } + function stdOpt(name, def) { + var value = name.toUpperCase() + + PADDING.slice(0, 19 - name.length*2); + p(' --%s %s default: %j', name, value, def); + } +} -/***/ }), -/* 271 */ -/***/ (function(module, exports, __webpack_require__) { -"use strict"; +/***/ }), +/* 277 */ +/***/ (function(module, exports) { +module.exports = function (args, opts) { + if (!opts) opts = {}; + + var flags = { bools : {}, strings : {}, unknownFn: null }; -const isStream = stream => - stream !== null && - typeof stream === 'object' && - typeof stream.pipe === 'function'; + if (typeof opts['unknown'] === 'function') { + flags.unknownFn = opts['unknown']; + } -isStream.writable = stream => - isStream(stream) && - stream.writable !== false && - typeof stream._write === 'function' && - typeof stream._writableState === 'object'; + if (typeof opts['boolean'] === 'boolean' && opts['boolean']) { + flags.allBools = true; + } else { + [].concat(opts['boolean']).filter(Boolean).forEach(function (key) { + flags.bools[key] = true; + }); + } + + var aliases = {}; + Object.keys(opts.alias || {}).forEach(function (key) { + aliases[key] = [].concat(opts.alias[key]); + aliases[key].forEach(function (x) { + aliases[x] = [key].concat(aliases[key].filter(function (y) { + return x !== y; + })); + }); + }); -isStream.readable = stream => - isStream(stream) && - stream.readable !== false && - typeof stream._read === 'function' && - typeof stream._readableState === 'object'; + [].concat(opts.string).filter(Boolean).forEach(function (key) { + flags.strings[key] = true; + if (aliases[key]) { + flags.strings[aliases[key]] = true; + } + }); -isStream.duplex = stream => - isStream.writable(stream) && - isStream.readable(stream); + var defaults = opts['default'] || {}; + + var argv = { _ : [] }; + Object.keys(flags.bools).forEach(function (key) { + setArg(key, defaults[key] === undefined ? false : defaults[key]); + }); + + var notFlags = []; -isStream.transform = stream => - isStream.duplex(stream) && - typeof stream._transform === 'function' && - typeof stream._transformState === 'object'; + if (args.indexOf('--') !== -1) { + notFlags = args.slice(args.indexOf('--')+1); + args = args.slice(0, args.indexOf('--')); + } -module.exports = isStream; + function argDefined(key, arg) { + return (flags.allBools && /^--[^=]+$/.test(arg)) || + flags.strings[key] || flags.bools[key] || aliases[key]; + } + function setArg (key, val, arg) { + if (arg && flags.unknownFn && !argDefined(key, arg)) { + if (flags.unknownFn(arg) === false) return; + } -/***/ }), -/* 272 */ -/***/ (function(module, exports, __webpack_require__) { + var value = !flags.strings[key] && isNumber(val) + ? Number(val) : val + ; + setKey(argv, key.split('.'), value); + + (aliases[key] || []).forEach(function (x) { + setKey(argv, x.split('.'), value); + }); + } -"use strict"; + function setKey (obj, keys, value) { + var o = obj; + for (var i = 0; i < keys.length-1; i++) { + var key = keys[i]; + if (key === '__proto__') return; + if (o[key] === undefined) o[key] = {}; + if (o[key] === Object.prototype || o[key] === Number.prototype + || o[key] === String.prototype) o[key] = {}; + if (o[key] === Array.prototype) o[key] = []; + o = o[key]; + } -const pump = __webpack_require__(273); -const bufferStream = __webpack_require__(275); + var key = keys[keys.length - 1]; + if (key === '__proto__') return; + if (o === Object.prototype || o === Number.prototype + || o === String.prototype) o = {}; + if (o === Array.prototype) o = []; + if (o[key] === undefined || flags.bools[key] || typeof o[key] === 'boolean') { + o[key] = value; + } + else if (Array.isArray(o[key])) { + o[key].push(value); + } + else { + o[key] = [ o[key], value ]; + } + } + + function aliasIsBoolean(key) { + return aliases[key].some(function (x) { + return flags.bools[x]; + }); + } -class MaxBufferError extends Error { - constructor() { - super('maxBuffer exceeded'); - this.name = 'MaxBufferError'; - } -} + for (var i = 0; i < args.length; i++) { + var arg = args[i]; + + if (/^--.+=/.test(arg)) { + // Using [\s\S] instead of . because js doesn't support the + // 'dotall' regex modifier. See: + // http://stackoverflow.com/a/1068308/13216 + var m = arg.match(/^--([^=]+)=([\s\S]*)$/); + var key = m[1]; + var value = m[2]; + if (flags.bools[key]) { + value = value !== 'false'; + } + setArg(key, value, arg); + } + else if (/^--no-.+/.test(arg)) { + var key = arg.match(/^--no-(.+)/)[1]; + setArg(key, false, arg); + } + else if (/^--.+/.test(arg)) { + var key = arg.match(/^--(.+)/)[1]; + var next = args[i + 1]; + if (next !== undefined && !/^-/.test(next) + && !flags.bools[key] + && !flags.allBools + && (aliases[key] ? !aliasIsBoolean(key) : true)) { + setArg(key, next, arg); + i++; + } + else if (/^(true|false)$/.test(next)) { + setArg(key, next === 'true', arg); + i++; + } + else { + setArg(key, flags.strings[key] ? '' : true, arg); + } + } + else if (/^-[^-]+/.test(arg)) { + var letters = arg.slice(1,-1).split(''); + + var broken = false; + for (var j = 0; j < letters.length; j++) { + var next = arg.slice(j+2); + + if (next === '-') { + setArg(letters[j], next, arg) + continue; + } + + if (/[A-Za-z]/.test(letters[j]) && /=/.test(next)) { + setArg(letters[j], next.split('=')[1], arg); + broken = true; + break; + } + + if (/[A-Za-z]/.test(letters[j]) + && /-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) { + setArg(letters[j], next, arg); + broken = true; + break; + } + + if (letters[j+1] && letters[j+1].match(/\W/)) { + setArg(letters[j], arg.slice(j+2), arg); + broken = true; + break; + } + else { + setArg(letters[j], flags.strings[letters[j]] ? '' : true, arg); + } + } + + var key = arg.slice(-1)[0]; + if (!broken && key !== '-') { + if (args[i+1] && !/^(-|--)[^-]/.test(args[i+1]) + && !flags.bools[key] + && (aliases[key] ? !aliasIsBoolean(key) : true)) { + setArg(key, args[i+1], arg); + i++; + } + else if (args[i+1] && /^(true|false)$/.test(args[i+1])) { + setArg(key, args[i+1] === 'true', arg); + i++; + } + else { + setArg(key, flags.strings[key] ? '' : true, arg); + } + } + } + else { + if (!flags.unknownFn || flags.unknownFn(arg) !== false) { + argv._.push( + flags.strings['_'] || !isNumber(arg) ? arg : Number(arg) + ); + } + if (opts.stopEarly) { + argv._.push.apply(argv._, args.slice(i + 1)); + break; + } + } + } + + Object.keys(defaults).forEach(function (key) { + if (!hasKey(argv, key.split('.'))) { + setKey(argv, key.split('.'), defaults[key]); + + (aliases[key] || []).forEach(function (x) { + setKey(argv, x.split('.'), defaults[key]); + }); + } + }); + + if (opts['--']) { + argv['--'] = new Array(); + notFlags.forEach(function(key) { + argv['--'].push(key); + }); + } + else { + notFlags.forEach(function(key) { + argv._.push(key); + }); + } -async function getStream(inputStream, options) { - if (!inputStream) { - return Promise.reject(new Error('Expected a stream')); - } + return argv; +}; - options = { - maxBuffer: Infinity, - ...options - }; +function hasKey (obj, keys) { + var o = obj; + keys.slice(0,-1).forEach(function (key) { + o = (o[key] || {}); + }); - const {maxBuffer} = options; + var key = keys[keys.length - 1]; + return key in o; +} - let stream; - await new Promise((resolve, reject) => { - const rejectPromise = error => { - if (error) { // A null check - error.bufferedData = stream.getBufferedValue(); - } +function isNumber (x) { + if (typeof x === 'number') return true; + if (/^0x[0-9a-f]+$/i.test(x)) return true; + return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x); +} - reject(error); - }; - stream = pump(inputStream, bufferStream(options), error => { - if (error) { - rejectPromise(error); - return; - } - resolve(); - }); +/***/ }), +/* 278 */ +/***/ (function(module) { - stream.on('data', () => { - if (stream.getBufferedLength() > maxBuffer) { - rejectPromise(new MaxBufferError()); - } - }); - }); +module.exports = JSON.parse("{\"name\":\"strong-log-transformer\",\"version\":\"2.1.0\",\"description\":\"Stream transformer that prefixes lines with timestamps and other things.\",\"author\":\"Ryan Graham \",\"license\":\"Apache-2.0\",\"repository\":{\"type\":\"git\",\"url\":\"git://github.com/strongloop/strong-log-transformer\"},\"keywords\":[\"logging\",\"streams\"],\"bugs\":{\"url\":\"https://github.com/strongloop/strong-log-transformer/issues\"},\"homepage\":\"https://github.com/strongloop/strong-log-transformer\",\"directories\":{\"test\":\"test\"},\"bin\":{\"sl-log-transformer\":\"bin/sl-log-transformer.js\"},\"main\":\"index.js\",\"scripts\":{\"test\":\"tap --100 test/test-*\"},\"dependencies\":{\"duplexer\":\"^0.1.1\",\"minimist\":\"^1.2.0\",\"through\":\"^2.3.4\"},\"devDependencies\":{\"tap\":\"^12.0.1\"},\"engines\":{\"node\":\">=4\"}}"); - return stream.getBufferedValue(); -} +/***/ }), +/* 279 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -module.exports = getStream; -// TODO: Remove this for the next major release -module.exports.default = getStream; -module.exports.buffer = (stream, options) => getStream(stream, {...options, encoding: 'buffer'}); -module.exports.array = (stream, options) => getStream(stream, {...options, array: true}); -module.exports.MaxBufferError = MaxBufferError; +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "workspacePackagePaths", function() { return workspacePackagePaths; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "copyWorkspacePackages", function() { return copyWorkspacePackages; }); +/* harmony import */ var glob__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(146); +/* harmony import */ var glob__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(glob__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(111); +/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(util__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(280); +/* harmony import */ var _fs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(130); +/* harmony import */ var _package_json__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(164); +/* harmony import */ var _projects__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(145); +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ -/***/ }), -/* 273 */ -/***/ (function(module, exports, __webpack_require__) { -var once = __webpack_require__(161) -var eos = __webpack_require__(274) -var fs = __webpack_require__(133) // we only need fs to get the ReadStream and WriteStream prototypes -var noop = function () {} -var ancient = /^v?\.0/.test(process.version) -var isFn = function (fn) { - return typeof fn === 'function' -} -var isFS = function (stream) { - if (!ancient) return false // newer node version do not need to care about fs is a special way - if (!fs) return false // browser - return (stream instanceof (fs.ReadStream || noop) || stream instanceof (fs.WriteStream || noop)) && isFn(stream.close) -} -var isRequest = function (stream) { - return stream.setHeader && isFn(stream.abort) -} +const glob = Object(util__WEBPACK_IMPORTED_MODULE_2__["promisify"])(glob__WEBPACK_IMPORTED_MODULE_0___default.a); +async function workspacePackagePaths(rootPath) { + const rootPkgJson = await Object(_package_json__WEBPACK_IMPORTED_MODULE_5__["readPackageJson"])(rootPath); -var destroyer = function (stream, reading, writing, callback) { - callback = once(callback) + if (!rootPkgJson.workspaces) { + return []; + } - var closed = false - stream.on('close', function () { - closed = true - }) - - eos(stream, {readable: reading, writable: writing}, function (err) { - if (err) return callback(err) - closed = true - callback() - }) - - var destroyed = false - return function (err) { - if (closed) return - if (destroyed) return - destroyed = true + const workspacesPathsPatterns = rootPkgJson.workspaces.packages; + let workspaceProjectsPaths = []; - if (isFS(stream)) return stream.close(noop) // use close for fs streams to avoid fd leaks - if (isRequest(stream)) return stream.abort() // request.destroy just do .end - .abort is what we want + for (const pattern of workspacesPathsPatterns) { + workspaceProjectsPaths = workspaceProjectsPaths.concat(await packagesFromGlobPattern({ + pattern, + rootPath + })); + } // Filter out exclude glob patterns - if (isFn(stream.destroy)) return stream.destroy() - callback(err || new Error('stream was destroyed')) + for (const pattern of workspacesPathsPatterns) { + if (pattern.startsWith('!')) { + const pathToRemove = path__WEBPACK_IMPORTED_MODULE_1___default.a.join(rootPath, pattern.slice(1), 'package.json'); + workspaceProjectsPaths = workspaceProjectsPaths.filter(p => p !== pathToRemove); + } } -} -var call = function (fn) { - fn() + return workspaceProjectsPaths; } +async function copyWorkspacePackages(rootPath) { + const projectPaths = Object(_config__WEBPACK_IMPORTED_MODULE_3__["getProjectPaths"])({ + rootPath + }); + const projects = await Object(_projects__WEBPACK_IMPORTED_MODULE_6__["getProjects"])(rootPath, projectPaths); -var pipe = function (from, to) { - return from.pipe(to) -} + for (const project of projects.values()) { + const dest = path__WEBPACK_IMPORTED_MODULE_1___default.a.resolve(rootPath, 'node_modules', project.name); -var pump = function () { - var streams = Array.prototype.slice.call(arguments) - var callback = isFn(streams[streams.length - 1] || noop) && streams.pop() || noop + if ((await Object(_fs__WEBPACK_IMPORTED_MODULE_4__["isSymlink"])(dest)) === false) { + continue; + } // Remove the symlink - if (Array.isArray(streams[0])) streams = streams[0] - if (streams.length < 2) throw new Error('pump requires two streams per minimum') - var error - var destroys = streams.map(function (stream, i) { - var reading = i < streams.length - 1 - var writing = i > 0 - return destroyer(stream, reading, writing, function (err) { - if (!error) error = err - if (err) destroys.forEach(call) - if (reading) return - destroys.forEach(call) - callback(error) - }) - }) + await Object(_fs__WEBPACK_IMPORTED_MODULE_4__["unlink"])(dest); // Copy in the package - return streams.reduce(pipe) + await Object(_fs__WEBPACK_IMPORTED_MODULE_4__["copyDirectory"])(project.path, dest); + } } -module.exports = pump - +function packagesFromGlobPattern({ + pattern, + rootPath +}) { + const globOptions = { + cwd: rootPath, + // Should throw in case of unusual errors when reading the file system + strict: true, + // Always returns absolute paths for matched files + absolute: true, + // Do not match ** against multiple filenames + // (This is only specified because we currently don't have a need for it.) + noglobstar: true + }; + return glob(path__WEBPACK_IMPORTED_MODULE_1___default.a.join(pattern, 'package.json'), globOptions); +} /***/ }), -/* 274 */ -/***/ (function(module, exports, __webpack_require__) { - -var once = __webpack_require__(161); +/* 280 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -var noop = function() {}; +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getProjectPaths", function() { return getProjectPaths; }); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_0__); +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ -var isRequest = function(stream) { - return stream.setHeader && typeof stream.abort === 'function'; -}; -var isChildProcess = function(stream) { - return stream.stdio && Array.isArray(stream.stdio) && stream.stdio.length === 3 -}; +/** + * Returns all the paths where plugins are located + */ +function getProjectPaths({ + rootPath, + ossOnly, + skipKibanaPlugins +}) { + const projectPaths = [rootPath, Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, 'packages/*')]; // This is needed in order to install the dependencies for the declared + // plugin functional used in the selenium functional tests. + // As we are now using the webpack dll for the client vendors dependencies + // when we run the plugin functional tests against the distributable + // dependencies used by such plugins like @eui, react and react-dom can't + // be loaded from the dll as the context is different from the one declared + // into the webpack dll reference plugin. + // In anyway, have a plugin declaring their own dependencies is the + // correct and the expect behavior. -var eos = function(stream, opts, callback) { - if (typeof opts === 'function') return eos(stream, null, opts); - if (!opts) opts = {}; + projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, 'test/plugin_functional/plugins/*')); + projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, 'test/interpreter_functional/plugins/*')); + projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, 'examples/*')); - callback = once(callback || noop); + if (!ossOnly) { + projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, 'x-pack')); + projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, 'x-pack/plugins/*')); + projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, 'x-pack/legacy/plugins/*')); + projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, 'x-pack/test/functional_with_es_ssl/fixtures/plugins/*')); + } - var ws = stream._writableState; - var rs = stream._readableState; - var readable = opts.readable || (opts.readable !== false && stream.readable); - var writable = opts.writable || (opts.writable !== false && stream.writable); + if (!skipKibanaPlugins) { + projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, '../kibana-extra/*')); + projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, '../kibana-extra/*/packages/*')); + projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, '../kibana-extra/*/plugins/*')); + projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, 'plugins/*')); + projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, 'plugins/*/packages/*')); + projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, 'plugins/*/plugins/*')); + } - var onlegacyfinish = function() { - if (!stream.writable) onfinish(); - }; + return projectPaths; +} - var onfinish = function() { - writable = false; - if (!readable) callback.call(stream); - }; +/***/ }), +/* 281 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { - var onend = function() { - readable = false; - if (!writable) callback.call(stream); - }; +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getAllChecksums", function() { return getAllChecksums; }); +/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(133); +/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(fs__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var crypto__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(282); +/* harmony import */ var crypto__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(crypto__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(111); +/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(util__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(236); +/* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(execa__WEBPACK_IMPORTED_MODULE_3__); +/* harmony import */ var _yarn_lock__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(283); +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ - var onexit = function(exitCode) { - callback.call(stream, exitCode ? new Error('exited with error code: ' + exitCode) : null); - }; - var onerror = function(err) { - callback.call(stream, err); - }; - var onclose = function() { - if (readable && !(rs && rs.ended)) return callback.call(stream, new Error('premature close')); - if (writable && !(ws && ws.ended)) return callback.call(stream, new Error('premature close')); - }; - var onrequest = function() { - stream.req.on('finish', onfinish); - }; - if (isRequest(stream)) { - stream.on('complete', onfinish); - stream.on('abort', onclose); - if (stream.req) onrequest(); - else stream.on('request', onrequest); - } else if (writable && !ws) { // legacy streams - stream.on('end', onlegacyfinish); - stream.on('close', onlegacyfinish); - } +const statAsync = Object(util__WEBPACK_IMPORTED_MODULE_2__["promisify"])(fs__WEBPACK_IMPORTED_MODULE_0___default.a.stat); - if (isChildProcess(stream)) stream.on('exit', onexit); +const projectBySpecificitySorter = (a, b) => b.path.length - a.path.length; +/** Get the changed files for a set of projects */ - stream.on('end', onend); - stream.on('finish', onfinish); - if (opts.error !== false) stream.on('error', onerror); - stream.on('close', onclose); - return function() { - stream.removeListener('complete', onfinish); - stream.removeListener('abort', onclose); - stream.removeListener('request', onrequest); - if (stream.req) stream.req.removeListener('finish', onfinish); - stream.removeListener('end', onlegacyfinish); - stream.removeListener('close', onlegacyfinish); - stream.removeListener('finish', onfinish); - stream.removeListener('exit', onexit); - stream.removeListener('end', onend); - stream.removeListener('error', onerror); - stream.removeListener('close', onclose); - }; -}; +async function getChangesForProjects(projects, kbn, log) { + log.verbose('getting changed files'); + const { + stdout + } = await execa__WEBPACK_IMPORTED_MODULE_3___default()('git', ['ls-files', '-dmto', '--exclude-standard', '--', ...Array.from(projects.values()).filter(p => kbn.isPartOfRepo(p)).map(p => p.path)], { + cwd: kbn.getAbsolute() + }); + const output = stdout.trim(); + const unassignedChanges = new Map(); -module.exports = eos; + if (output) { + for (const line of output.split('\n')) { + const [tag, ...pathParts] = line.trim().split(' '); + const path = pathParts.join(' '); + switch (tag) { + case 'M': + case 'C': + // for some reason ls-files returns deleted files as both deleted + // and modified, so make sure not to overwrite changes already + // tracked as "deleted" + if (unassignedChanges.get(path) !== 'deleted') { + unassignedChanges.set(path, 'modified'); + } -/***/ }), -/* 275 */ -/***/ (function(module, exports, __webpack_require__) { + break; -"use strict"; + case 'R': + unassignedChanges.set(path, 'deleted'); + break; -const {PassThrough: PassThroughStream} = __webpack_require__(137); + case '?': + unassignedChanges.set(path, 'untracked'); + break; -module.exports = options => { - options = {...options}; + case 'H': + case 'S': + case 'K': + default: + log.warning(`unexpected modification status "${tag}" for ${path}, please report this!`); + unassignedChanges.set(path, 'invalid'); + break; + } + } + } - const {array} = options; - let {encoding} = options; - const isBuffer = encoding === 'buffer'; - let objectMode = false; + const sortedRelevantProjects = Array.from(projects.values()).sort(projectBySpecificitySorter); + const changesByProject = new Map(); - if (array) { - objectMode = !(encoding || isBuffer); - } else { - encoding = encoding || 'utf8'; - } + for (const project of sortedRelevantProjects) { + if (kbn.isOutsideRepo(project)) { + changesByProject.set(project, undefined); + continue; + } - if (isBuffer) { - encoding = null; - } + const ownChanges = new Map(); + const prefix = kbn.getRelative(project.path); - const stream = new PassThroughStream({objectMode}); + for (const [path, type] of unassignedChanges) { + if (path.startsWith(prefix)) { + ownChanges.set(path, type); + unassignedChanges.delete(path); + } + } - if (encoding) { - stream.setEncoding(encoding); - } + log.verbose(`[${project.name}] found ${ownChanges.size} changes`); + changesByProject.set(project, ownChanges); + } - let length = 0; - const chunks = []; + if (unassignedChanges.size) { + throw new Error(`unable to assign all change paths to a project: ${JSON.stringify(Array.from(unassignedChanges.entries()))}`); + } - stream.on('data', chunk => { - chunks.push(chunk); + return changesByProject; +} +/** Get the latest commit sha for a project */ - if (objectMode) { - length = chunks.length; - } else { - length += chunk.length; - } - }); - stream.getBufferedValue = () => { - if (array) { - return chunks; - } +async function getLatestSha(project, kbn) { + if (kbn.isOutsideRepo(project)) { + return; + } - return isBuffer ? Buffer.concat(chunks, length) : chunks.join(''); - }; + const { + stdout + } = await execa__WEBPACK_IMPORTED_MODULE_3___default()('git', ['log', '-n', '1', '--pretty=format:%H', '--', project.path], { + cwd: kbn.getAbsolute() + }); + return stdout.trim() || undefined; +} +/** + * Get a list of the absolute dependencies of this project, as resolved + * in the yarn.lock file, does not include other projects in the workspace + * or their dependencies + */ - stream.getBufferedLength = () => length; - return stream; -}; +function resolveDepsForProject(project, yarnLock, kbn, log) { + /** map of [name@range, name@resolved] */ + const resolved = new Map(); + const queue = Object.entries(project.allDependencies); + while (queue.length) { + const [name, versionRange] = queue.shift(); + const req = `${name}@${versionRange}`; -/***/ }), -/* 276 */ -/***/ (function(module, exports, __webpack_require__) { + if (resolved.has(req)) { + continue; + } -"use strict"; + if (!kbn.hasProject(name)) { + const pkg = yarnLock[req]; + if (!pkg) { + log.warning('yarn.lock file is out of date, please run `yarn kbn bootstrap` to re-enable caching'); + return; + } -const { PassThrough } = __webpack_require__(137); + const res = `${name}@${pkg.version}`; + resolved.set(req, res); + const allDepsEntries = [...Object.entries(pkg.dependencies || {}), ...Object.entries(pkg.optionalDependencies || {})]; -module.exports = function (/*streams...*/) { - var sources = [] - var output = new PassThrough({objectMode: true}) + for (const [childName, childVersionRange] of allDepsEntries) { + queue.push([childName, childVersionRange]); + } + } + } - output.setMaxListeners(0) + return Array.from(resolved.values()).sort((a, b) => a.localeCompare(b)); +} +/** + * Get the checksum for a specific project in the workspace + */ - output.add = add - output.isEmpty = isEmpty - output.on('unpipe', remove) +async function getChecksum(project, changes, yarnLock, kbn, log) { + const sha = await getLatestSha(project, kbn); - Array.prototype.slice.call(arguments).forEach(add) + if (sha) { + log.verbose(`[${project.name}] local sha:`, sha); + } - return output + if (!changes || Array.from(changes.values()).includes('invalid')) { + log.warning(`[${project.name}] unable to determine local changes, caching disabled`); + return; + } - function add (source) { - if (Array.isArray(source)) { - source.forEach(add) - return this + const changesSummary = await Promise.all(Array.from(changes).sort((a, b) => a[0].localeCompare(b[0])).map(async ([path, type]) => { + if (type === 'deleted') { + return `${path}:deleted`; } - sources.push(source); - source.once('end', remove.bind(null, source)) - source.once('error', output.emit.bind(output, 'error')) - source.pipe(output, {end: false}) - return this - } + const stats = await statAsync(kbn.getAbsolute(path)); + log.verbose(`[${project.name}] modified time ${stats.mtimeMs} for ${path}`); + return `${path}:${stats.mtimeMs}`; + })); + const deps = await resolveDepsForProject(project, yarnLock, kbn, log); - function isEmpty () { - return sources.length == 0; + if (!deps) { + return; } - function remove (source) { - sources = sources.filter(function (it) { return it !== source }) - if (!sources.length && output.readable) { output.end() } - } -} + log.verbose(`[${project.name}] resolved %d deps`, deps.length); + const checksum = JSON.stringify({ + sha, + changes: changesSummary, + deps + }, null, 2); + if (process.env.BOOTSTRAP_CACHE_DEBUG_CHECKSUM) { + return checksum; + } -/***/ }), -/* 277 */ -/***/ (function(module, exports, __webpack_require__) { + const hash = crypto__WEBPACK_IMPORTED_MODULE_1___default.a.createHash('sha1'); + hash.update(checksum); + return hash.digest('hex'); +} +/** + * Calculate checksums for all projects in the workspace based on + * - last git commit to project directory + * - un-committed changes + * - resolved dependencies from yarn.lock referenced by project package.json + */ -"use strict"; +async function getAllChecksums(kbn, log) { + const projects = kbn.getAllProjects(); + const changesByProject = await getChangesForProjects(projects, kbn, log); + const yarnLock = await Object(_yarn_lock__WEBPACK_IMPORTED_MODULE_4__["readYarnLock"])(kbn); + /** map of [project.name, cacheKey] */ -const nativePromisePrototype = (async () => {})().constructor.prototype; -const descriptors = ['then', 'catch', 'finally'].map(property => [ - property, - Reflect.getOwnPropertyDescriptor(nativePromisePrototype, property) -]); + const cacheKeys = new Map(); + await Promise.all(Array.from(projects.values()).map(async project => { + cacheKeys.set(project.name, await getChecksum(project, changesByProject.get(project), yarnLock, kbn, log)); + })); + return cacheKeys; +} -// The return value is a mixin of `childProcess` and `Promise` -const mergePromise = (spawned, promise) => { - for (const [property, descriptor] of descriptors) { - // Starting the main `promise` is deferred to avoid consuming streams - const value = typeof promise === 'function' ? - (...args) => Reflect.apply(descriptor.value, promise(), args) : - descriptor.value.bind(promise); +/***/ }), +/* 282 */ +/***/ (function(module, exports) { - Reflect.defineProperty(spawned, property, {...descriptor, value}); - } +module.exports = require("crypto"); - return spawned; -}; +/***/ }), +/* 283 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -// Use promises instead of `child_process` events -const getSpawnedPromise = spawned => { - return new Promise((resolve, reject) => { - spawned.on('exit', (exitCode, signal) => { - resolve({exitCode, signal}); - }); +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "readYarnLock", function() { return readYarnLock; }); +/* harmony import */ var _yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(284); +/* harmony import */ var _yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _utils_fs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(130); +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +// @ts-ignore published types are worthless - spawned.on('error', error => { - reject(error); - }); - if (spawned.stdin) { - spawned.stdin.on('error', error => { - reject(error); - }); - } - }); -}; +async function readYarnLock(kbn) { + try { + const contents = await Object(_utils_fs__WEBPACK_IMPORTED_MODULE_1__["readFile"])(kbn.getAbsolute('yarn.lock'), 'utf8'); + const yarnLock = Object(_yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0__["parse"])(contents); -module.exports = { - mergePromise, - getSpawnedPromise -}; + if (yarnLock.type === 'success') { + return yarnLock.object; + } + throw new Error('unable to read yarn.lock file, please run `yarn kbn bootstrap`'); + } catch (error) { + if (error.code !== 'ENOENT') { + throw error; + } + } + return {}; +} /***/ }), -/* 278 */ +/* 284 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; +module.exports = +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // identity function for calling harmony imports with the correct context +/******/ __webpack_require__.i = function(value) { return value; }; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { +/******/ configurable: false, +/******/ enumerable: true, +/******/ get: getter +/******/ }); +/******/ } +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 14); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, exports) { -const SPACES_REGEXP = / +/g; +module.exports = __webpack_require__(4); -const joinCommand = (file, args = []) => { - if (!Array.isArray(args)) { - return file; - } +/***/ }), +/* 1 */ +/***/ (function(module, exports, __webpack_require__) { - return [file, ...args].join(' '); -}; +"use strict"; -// Allow spaces to be escaped by a backslash if not meant as a delimiter -const handleEscaping = (tokens, token, index) => { - if (index === 0) { - return [token]; - } - const previousToken = tokens[tokens.length - 1]; +exports.__esModule = true; - if (previousToken.endsWith('\\')) { - return [...tokens.slice(0, -1), `${previousToken.slice(0, -1)} ${token}`]; - } +var _promise = __webpack_require__(173); - return [...tokens, token]; -}; +var _promise2 = _interopRequireDefault(_promise); -// Handle `execa.command()` -const parseCommand = command => { - return command - .trim() - .split(SPACES_REGEXP) - .reduce(handleEscaping, []); -}; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -module.exports = { - joinCommand, - parseCommand -}; +exports.default = function (fn) { + return function () { + var gen = fn.apply(this, arguments); + return new _promise2.default(function (resolve, reject) { + function step(key, arg) { + try { + var info = gen[key](arg); + var value = info.value; + } catch (error) { + reject(error); + return; + } + + if (info.done) { + resolve(value); + } else { + return _promise2.default.resolve(value).then(function (value) { + step("next", value); + }, function (err) { + step("throw", err); + }); + } + } + return step("next"); + }); + }; +}; /***/ }), -/* 279 */ -/***/ (function(module, exports, __webpack_require__) { +/* 2 */ +/***/ (function(module, exports) { -// Copyright IBM Corp. 2014,2018. All Rights Reserved. -// Node module: strong-log-transformer -// This file is licensed under the Apache License 2.0. -// License text available at https://opensource.org/licenses/Apache-2.0 +module.exports = __webpack_require__(111); -module.exports = __webpack_require__(280); -module.exports.cli = __webpack_require__(284); +/***/ }), +/* 3 */ +/***/ (function(module, exports) { +module.exports = __webpack_require__(133); /***/ }), -/* 280 */ +/* 4 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -// Copyright IBM Corp. 2014,2018. All Rights Reserved. -// Node module: strong-log-transformer -// This file is licensed under the Apache License 2.0. -// License text available at https://opensource.org/licenses/Apache-2.0 - - - -var stream = __webpack_require__(137); -var util = __webpack_require__(111); -var fs = __webpack_require__(133); -var through = __webpack_require__(281); -var duplexer = __webpack_require__(282); -var StringDecoder = __webpack_require__(283).StringDecoder; -module.exports = Logger; - -Logger.DEFAULTS = { - format: 'text', - tag: '', - mergeMultiline: false, - timeStamp: false, -}; +Object.defineProperty(exports, "__esModule", { + value: true +}); +class MessageError extends Error { + constructor(msg, code) { + super(msg); + this.code = code; + } -var formatters = { - text: textFormatter, - json: jsonFormatter, } -function Logger(options) { - var defaults = JSON.parse(JSON.stringify(Logger.DEFAULTS)); - options = util._extend(defaults, options || {}); - var catcher = deLiner(); - var emitter = catcher; - var transforms = [ - objectifier(), - ]; - - if (options.tag) { - transforms.push(staticTagger(options.tag)); - } - - if (options.mergeMultiline) { - transforms.push(lineMerger()); +exports.MessageError = MessageError; +class ProcessSpawnError extends MessageError { + constructor(msg, code, process) { + super(msg, code); + this.process = process; } - // TODO - // if (options.pidStamp) { - // transforms.push(pidStamper(options.pid)); - // } - - // TODO - // if (options.workerStamp) { - // transforms.push(workerStamper(options.worker)); - // } +} - transforms.push(formatters[options.format](options)); +exports.ProcessSpawnError = ProcessSpawnError; +class SecurityError extends MessageError {} - // restore line endings that were removed by line splitting - transforms.push(reLiner()); +exports.SecurityError = SecurityError; +class ProcessTermError extends MessageError {} - for (var t in transforms) { - emitter = emitter.pipe(transforms[t]); +exports.ProcessTermError = ProcessTermError; +class ResponseError extends Error { + constructor(msg, responseCode) { + super(msg); + this.responseCode = responseCode; } - return duplexer(catcher, emitter); } +exports.ResponseError = ResponseError; -function deLiner() { - var decoder = new StringDecoder('utf8'); - var last = ''; +/***/ }), +/* 5 */ +/***/ (function(module, exports, __webpack_require__) { - return new stream.Transform({ - transform(chunk, _enc, callback) { - last += decoder.write(chunk); - var list = last.split(/\r\n|[\n\v\f\r\x85\u2028\u2029]/g); - last = list.pop(); - for (var i = 0; i < list.length; i++) { - // swallow empty lines - if (list[i]) { - this.push(list[i]); - } - } - callback(); - }, - flush(callback) { - // incomplete UTF8 sequences become UTF8 replacement characters - last += decoder.end(); - if (last) { - this.push(last); - } - callback(); - }, - }); -} +"use strict"; -function reLiner() { - return through(appendNewline); - function appendNewline(line) { - this.emit('data', line + '\n'); - } -} +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getFirstSuitableFolder = exports.readFirstAvailableStream = exports.makeTempDir = exports.hardlinksWork = exports.writeFilePreservingEol = exports.getFileSizeOnDisk = exports.walk = exports.symlink = exports.find = exports.readJsonAndFile = exports.readJson = exports.readFileAny = exports.hardlinkBulk = exports.copyBulk = exports.unlink = exports.glob = exports.link = exports.chmod = exports.lstat = exports.exists = exports.mkdirp = exports.stat = exports.access = exports.rename = exports.readdir = exports.realpath = exports.readlink = exports.writeFile = exports.open = exports.readFileBuffer = exports.lockQueue = exports.constants = undefined; -function objectifier() { - return through(objectify, null, {autoDestroy: false}); +var _asyncToGenerator2; - function objectify(line) { - this.emit('data', { - msg: line, - time: Date.now(), - }); - } +function _load_asyncToGenerator() { + return _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(1)); } -function staticTagger(tag) { - return through(tagger); - - function tagger(logEvent) { - logEvent.tag = tag; - this.emit('data', logEvent); - } -} +let buildActionsForCopy = (() => { + var _ref = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (queue, events, possibleExtraneous, reporter) { -function textFormatter(options) { - return through(textify); + // + let build = (() => { + var _ref5 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (data) { + const src = data.src, + dest = data.dest, + type = data.type; - function textify(logEvent) { - var line = util.format('%s%s', textifyTags(logEvent.tag), - logEvent.msg.toString()); - if (options.timeStamp) { - line = util.format('%s %s', new Date(logEvent.time).toISOString(), line); - } - this.emit('data', line.replace(/\n/g, '\\n')); - } + const onFresh = data.onFresh || noop; + const onDone = data.onDone || noop; - function textifyTags(tags) { - var str = ''; - if (typeof tags === 'string') { - str = tags + ' '; - } else if (typeof tags === 'object') { - for (var t in tags) { - str += t + ':' + tags[t] + ' '; - } - } - return str; - } -} + // TODO https://github.com/yarnpkg/yarn/issues/3751 + // related to bundled dependencies handling + if (files.has(dest.toLowerCase())) { + reporter.verbose(`The case-insensitive file ${dest} shouldn't be copied twice in one bulk copy`); + } else { + files.add(dest.toLowerCase()); + } -function jsonFormatter(options) { - return through(jsonify); + if (type === 'symlink') { + yield mkdirp((_path || _load_path()).default.dirname(dest)); + onFresh(); + actions.symlink.push({ + dest, + linkname: src + }); + onDone(); + return; + } - function jsonify(logEvent) { - if (options.timeStamp) { - logEvent.time = new Date(logEvent.time).toISOString(); - } else { - delete logEvent.time; - } - logEvent.msg = logEvent.msg.toString(); - this.emit('data', JSON.stringify(logEvent)); - } -} + if (events.ignoreBasenames.indexOf((_path || _load_path()).default.basename(src)) >= 0) { + // ignored file + return; + } -function lineMerger(host) { - var previousLine = null; - var flushTimer = null; - var stream = through(lineMergerWrite, lineMergerEnd); - var flush = _flush.bind(stream); + const srcStat = yield lstat(src); + let srcFiles; - return stream; + if (srcStat.isDirectory()) { + srcFiles = yield readdir(src); + } - function lineMergerWrite(line) { - if (/^\s+/.test(line.msg)) { - if (previousLine) { - previousLine.msg += '\n' + line.msg; - } else { - previousLine = line; - } - } else { - flush(); - previousLine = line; - } - // rolling timeout - clearTimeout(flushTimer); - flushTimer = setTimeout(flush.bind(this), 10); - } + let destStat; + try { + // try accessing the destination + destStat = yield lstat(dest); + } catch (e) { + // proceed if destination doesn't exist, otherwise error + if (e.code !== 'ENOENT') { + throw e; + } + } - function _flush() { - if (previousLine) { - this.emit('data', previousLine); - previousLine = null; - } - } + // if destination exists + if (destStat) { + const bothSymlinks = srcStat.isSymbolicLink() && destStat.isSymbolicLink(); + const bothFolders = srcStat.isDirectory() && destStat.isDirectory(); + const bothFiles = srcStat.isFile() && destStat.isFile(); - function lineMergerEnd() { - flush.call(this); - this.emit('end'); - } -} + // EINVAL access errors sometimes happen which shouldn't because node shouldn't be giving + // us modes that aren't valid. investigate this, it's generally safe to proceed. + /* if (srcStat.mode !== destStat.mode) { + try { + await access(dest, srcStat.mode); + } catch (err) {} + } */ -/***/ }), -/* 281 */ -/***/ (function(module, exports, __webpack_require__) { + if (bothFiles && artifactFiles.has(dest)) { + // this file gets changed during build, likely by a custom install script. Don't bother checking it. + onDone(); + reporter.verbose(reporter.lang('verboseFileSkipArtifact', src)); + return; + } -var Stream = __webpack_require__(137) + if (bothFiles && srcStat.size === destStat.size && (0, (_fsNormalized || _load_fsNormalized()).fileDatesEqual)(srcStat.mtime, destStat.mtime)) { + // we can safely assume this is the same file + onDone(); + reporter.verbose(reporter.lang('verboseFileSkip', src, dest, srcStat.size, +srcStat.mtime)); + return; + } -// through -// -// a stream that does nothing but re-emit the input. -// useful for aggregating a series of changing but not ending streams into one stream) + if (bothSymlinks) { + const srcReallink = yield readlink(src); + if (srcReallink === (yield readlink(dest))) { + // if both symlinks are the same then we can continue on + onDone(); + reporter.verbose(reporter.lang('verboseFileSkipSymlink', src, dest, srcReallink)); + return; + } + } -exports = module.exports = through -through.through = through + if (bothFolders) { + // mark files that aren't in this folder as possibly extraneous + const destFiles = yield readdir(dest); + invariant(srcFiles, 'src files not initialised'); -//create a readable writable stream. + for (var _iterator4 = destFiles, _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) { + var _ref6; -function through (write, end, opts) { - write = write || function (data) { this.queue(data) } - end = end || function () { this.queue(null) } + if (_isArray4) { + if (_i4 >= _iterator4.length) break; + _ref6 = _iterator4[_i4++]; + } else { + _i4 = _iterator4.next(); + if (_i4.done) break; + _ref6 = _i4.value; + } - var ended = false, destroyed = false, buffer = [], _ended = false - var stream = new Stream() - stream.readable = stream.writable = true - stream.paused = false + const file = _ref6; -// stream.autoPause = !(opts && opts.autoPause === false) - stream.autoDestroy = !(opts && opts.autoDestroy === false) + if (srcFiles.indexOf(file) < 0) { + const loc = (_path || _load_path()).default.join(dest, file); + possibleExtraneous.add(loc); - stream.write = function (data) { - write.call(this, data) - return !stream.paused - } + if ((yield lstat(loc)).isDirectory()) { + for (var _iterator5 = yield readdir(loc), _isArray5 = Array.isArray(_iterator5), _i5 = 0, _iterator5 = _isArray5 ? _iterator5 : _iterator5[Symbol.iterator]();;) { + var _ref7; - function drain() { - while(buffer.length && !stream.paused) { - var data = buffer.shift() - if(null === data) - return stream.emit('end') - else - stream.emit('data', data) - } - } + if (_isArray5) { + if (_i5 >= _iterator5.length) break; + _ref7 = _iterator5[_i5++]; + } else { + _i5 = _iterator5.next(); + if (_i5.done) break; + _ref7 = _i5.value; + } - stream.queue = stream.push = function (data) { -// console.error(ended) - if(_ended) return stream - if(data === null) _ended = true - buffer.push(data) - drain() - return stream - } + const file = _ref7; - //this will be registered as the first 'end' listener - //must call destroy next tick, to make sure we're after any - //stream piped from here. - //this is only a problem if end is not emitted synchronously. - //a nicer way to do this is to make sure this is the last listener for 'end' + possibleExtraneous.add((_path || _load_path()).default.join(loc, file)); + } + } + } + } + } + } - stream.on('end', function () { - stream.readable = false - if(!stream.writable && stream.autoDestroy) - process.nextTick(function () { - stream.destroy() - }) - }) + if (destStat && destStat.isSymbolicLink()) { + yield (0, (_fsNormalized || _load_fsNormalized()).unlink)(dest); + destStat = null; + } - function _end () { - stream.writable = false - end.call(stream) - if(!stream.readable && stream.autoDestroy) - stream.destroy() - } + if (srcStat.isSymbolicLink()) { + onFresh(); + const linkname = yield readlink(src); + actions.symlink.push({ + dest, + linkname + }); + onDone(); + } else if (srcStat.isDirectory()) { + if (!destStat) { + reporter.verbose(reporter.lang('verboseFileFolder', dest)); + yield mkdirp(dest); + } - stream.end = function (data) { - if(ended) return - ended = true - if(arguments.length) stream.write(data) - _end() // will emit or queue - return stream - } + const destParts = dest.split((_path || _load_path()).default.sep); + while (destParts.length) { + files.add(destParts.join((_path || _load_path()).default.sep).toLowerCase()); + destParts.pop(); + } - stream.destroy = function () { - if(destroyed) return - destroyed = true - ended = true - buffer.length = 0 - stream.writable = stream.readable = false - stream.emit('close') - return stream - } + // push all files to queue + invariant(srcFiles, 'src files not initialised'); + let remaining = srcFiles.length; + if (!remaining) { + onDone(); + } + for (var _iterator6 = srcFiles, _isArray6 = Array.isArray(_iterator6), _i6 = 0, _iterator6 = _isArray6 ? _iterator6 : _iterator6[Symbol.iterator]();;) { + var _ref8; - stream.pause = function () { - if(stream.paused) return - stream.paused = true - return stream - } + if (_isArray6) { + if (_i6 >= _iterator6.length) break; + _ref8 = _iterator6[_i6++]; + } else { + _i6 = _iterator6.next(); + if (_i6.done) break; + _ref8 = _i6.value; + } - stream.resume = function () { - if(stream.paused) { - stream.paused = false - stream.emit('resume') - } - drain() - //may have become paused again, - //as drain emits 'data'. - if(!stream.paused) - stream.emit('drain') - return stream - } - return stream -} + const file = _ref8; + queue.push({ + dest: (_path || _load_path()).default.join(dest, file), + onFresh, + onDone: function (_onDone) { + function onDone() { + return _onDone.apply(this, arguments); + } + onDone.toString = function () { + return _onDone.toString(); + }; -/***/ }), -/* 282 */ -/***/ (function(module, exports, __webpack_require__) { + return onDone; + }(function () { + if (--remaining === 0) { + onDone(); + } + }), + src: (_path || _load_path()).default.join(src, file) + }); + } + } else if (srcStat.isFile()) { + onFresh(); + actions.file.push({ + src, + dest, + atime: srcStat.atime, + mtime: srcStat.mtime, + mode: srcStat.mode + }); + onDone(); + } else { + throw new Error(`unsure how to copy this: ${src}`); + } + }); -var Stream = __webpack_require__(137) -var writeMethods = ["write", "end", "destroy"] -var readMethods = ["resume", "pause"] -var readEvents = ["data", "close"] -var slice = Array.prototype.slice + return function build(_x5) { + return _ref5.apply(this, arguments); + }; + })(); -module.exports = duplex + const artifactFiles = new Set(events.artifactFiles || []); + const files = new Set(); -function forEach (arr, fn) { - if (arr.forEach) { - return arr.forEach(fn) - } + // initialise events + for (var _iterator = queue, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { + var _ref2; - for (var i = 0; i < arr.length; i++) { - fn(arr[i], i) - } -} + if (_isArray) { + if (_i >= _iterator.length) break; + _ref2 = _iterator[_i++]; + } else { + _i = _iterator.next(); + if (_i.done) break; + _ref2 = _i.value; + } -function duplex(writer, reader) { - var stream = new Stream() - var ended = false + const item = _ref2; - forEach(writeMethods, proxyWriter) + const onDone = item.onDone; + item.onDone = function () { + events.onProgress(item.dest); + if (onDone) { + onDone(); + } + }; + } + events.onStart(queue.length); - forEach(readMethods, proxyReader) + // start building actions + const actions = { + file: [], + symlink: [], + link: [] + }; - forEach(readEvents, proxyStream) + // custom concurrency logic as we're always executing stacks of CONCURRENT_QUEUE_ITEMS queue items + // at a time due to the requirement to push items onto the queue + while (queue.length) { + const items = queue.splice(0, CONCURRENT_QUEUE_ITEMS); + yield Promise.all(items.map(build)); + } - reader.on("end", handleEnd) + // simulate the existence of some files to prevent considering them extraneous + for (var _iterator2 = artifactFiles, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) { + var _ref3; - writer.on("drain", function() { - stream.emit("drain") - }) + if (_isArray2) { + if (_i2 >= _iterator2.length) break; + _ref3 = _iterator2[_i2++]; + } else { + _i2 = _iterator2.next(); + if (_i2.done) break; + _ref3 = _i2.value; + } - writer.on("error", reemit) - reader.on("error", reemit) + const file = _ref3; - stream.writable = writer.writable - stream.readable = reader.readable + if (possibleExtraneous.has(file)) { + reporter.verbose(reporter.lang('verboseFilePhantomExtraneous', file)); + possibleExtraneous.delete(file); + } + } - return stream + for (var _iterator3 = possibleExtraneous, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) { + var _ref4; - function proxyWriter(methodName) { - stream[methodName] = method + if (_isArray3) { + if (_i3 >= _iterator3.length) break; + _ref4 = _iterator3[_i3++]; + } else { + _i3 = _iterator3.next(); + if (_i3.done) break; + _ref4 = _i3.value; + } - function method() { - return writer[methodName].apply(writer, arguments) - } + const loc = _ref4; + + if (files.has(loc.toLowerCase())) { + possibleExtraneous.delete(loc); + } } - function proxyReader(methodName) { - stream[methodName] = method + return actions; + }); - function method() { - stream.emit(methodName) - var func = reader[methodName] - if (func) { - return func.apply(reader, arguments) - } - reader.emit(methodName) - } - } + return function buildActionsForCopy(_x, _x2, _x3, _x4) { + return _ref.apply(this, arguments); + }; +})(); - function proxyStream(methodName) { - reader.on(methodName, reemit) +let buildActionsForHardlink = (() => { + var _ref9 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (queue, events, possibleExtraneous, reporter) { - function reemit() { - var args = slice.call(arguments) - args.unshift(methodName) - stream.emit.apply(stream, args) - } - } + // + let build = (() => { + var _ref13 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (data) { + const src = data.src, + dest = data.dest; - function handleEnd() { - if (ended) { - return + const onFresh = data.onFresh || noop; + const onDone = data.onDone || noop; + if (files.has(dest.toLowerCase())) { + // Fixes issue https://github.com/yarnpkg/yarn/issues/2734 + // When bulk hardlinking we have A -> B structure that we want to hardlink to A1 -> B1, + // package-linker passes that modules A1 and B1 need to be hardlinked, + // the recursive linking algorithm of A1 ends up scheduling files in B1 to be linked twice which will case + // an exception. + onDone(); + return; } - ended = true - var args = slice.call(arguments) - args.unshift("end") - stream.emit.apply(stream, args) - } + files.add(dest.toLowerCase()); - function reemit(err) { - stream.emit("error", err) - } -} + if (events.ignoreBasenames.indexOf((_path || _load_path()).default.basename(src)) >= 0) { + // ignored file + return; + } + const srcStat = yield lstat(src); + let srcFiles; -/***/ }), -/* 283 */ -/***/ (function(module, exports) { + if (srcStat.isDirectory()) { + srcFiles = yield readdir(src); + } -module.exports = require("string_decoder"); + const destExists = yield exists(dest); + if (destExists) { + const destStat = yield lstat(dest); -/***/ }), -/* 284 */ -/***/ (function(module, exports, __webpack_require__) { + const bothSymlinks = srcStat.isSymbolicLink() && destStat.isSymbolicLink(); + const bothFolders = srcStat.isDirectory() && destStat.isDirectory(); + const bothFiles = srcStat.isFile() && destStat.isFile(); -"use strict"; -// Copyright IBM Corp. 2014,2018. All Rights Reserved. -// Node module: strong-log-transformer -// This file is licensed under the Apache License 2.0. -// License text available at https://opensource.org/licenses/Apache-2.0 + if (srcStat.mode !== destStat.mode) { + try { + yield access(dest, srcStat.mode); + } catch (err) { + // EINVAL access errors sometimes happen which shouldn't because node shouldn't be giving + // us modes that aren't valid. investigate this, it's generally safe to proceed. + reporter.verbose(err); + } + } + if (bothFiles && artifactFiles.has(dest)) { + // this file gets changed during build, likely by a custom install script. Don't bother checking it. + onDone(); + reporter.verbose(reporter.lang('verboseFileSkipArtifact', src)); + return; + } + // correct hardlink + if (bothFiles && srcStat.ino !== null && srcStat.ino === destStat.ino) { + onDone(); + reporter.verbose(reporter.lang('verboseFileSkip', src, dest, srcStat.ino)); + return; + } -var minimist = __webpack_require__(285); -var path = __webpack_require__(4); + if (bothSymlinks) { + const srcReallink = yield readlink(src); + if (srcReallink === (yield readlink(dest))) { + // if both symlinks are the same then we can continue on + onDone(); + reporter.verbose(reporter.lang('verboseFileSkipSymlink', src, dest, srcReallink)); + return; + } + } -var Logger = __webpack_require__(280); -var pkg = __webpack_require__(286); + if (bothFolders) { + // mark files that aren't in this folder as possibly extraneous + const destFiles = yield readdir(dest); + invariant(srcFiles, 'src files not initialised'); -module.exports = cli; + for (var _iterator10 = destFiles, _isArray10 = Array.isArray(_iterator10), _i10 = 0, _iterator10 = _isArray10 ? _iterator10 : _iterator10[Symbol.iterator]();;) { + var _ref14; -function cli(args) { - var opts = minimist(args.slice(2)); - var $0 = path.basename(args[1]); - var p = console.log.bind(console); - if (opts.v || opts.version) { - version($0, p); - } else if (opts.h || opts.help) { - usage($0, p); - } else if (args.length < 3) { - process.stdin.pipe(Logger()).pipe(process.stdout); - } else { - process.stdin.pipe(Logger(opts)).pipe(process.stdout); - } -} + if (_isArray10) { + if (_i10 >= _iterator10.length) break; + _ref14 = _iterator10[_i10++]; + } else { + _i10 = _iterator10.next(); + if (_i10.done) break; + _ref14 = _i10.value; + } -function version($0, p) { - p('%s v%s', pkg.name, pkg.version); -} + const file = _ref14; -function usage($0, p) { - var PADDING = ' '; - var opt, def; - p('Usage: %s [options]', $0); - p(''); - p('%s', pkg.description); - p(''); - p('OPTIONS:'); - for (opt in Logger.DEFAULTS) { - def = Logger.DEFAULTS[opt]; - if (typeof def === 'boolean') - boolOpt(opt, Logger.DEFAULTS[opt]); - else - stdOpt(opt, Logger.DEFAULTS[opt]); - } - p(''); + if (srcFiles.indexOf(file) < 0) { + const loc = (_path || _load_path()).default.join(dest, file); + possibleExtraneous.add(loc); - function boolOpt(name, def) { - name = name + PADDING.slice(0, 20-name.length); - p(' --%s default: %s', name, def); - } + if ((yield lstat(loc)).isDirectory()) { + for (var _iterator11 = yield readdir(loc), _isArray11 = Array.isArray(_iterator11), _i11 = 0, _iterator11 = _isArray11 ? _iterator11 : _iterator11[Symbol.iterator]();;) { + var _ref15; - function stdOpt(name, def) { - var value = name.toUpperCase() + - PADDING.slice(0, 19 - name.length*2); - p(' --%s %s default: %j', name, value, def); - } -} + if (_isArray11) { + if (_i11 >= _iterator11.length) break; + _ref15 = _iterator11[_i11++]; + } else { + _i11 = _iterator11.next(); + if (_i11.done) break; + _ref15 = _i11.value; + } + const file = _ref15; -/***/ }), -/* 285 */ -/***/ (function(module, exports) { + possibleExtraneous.add((_path || _load_path()).default.join(loc, file)); + } + } + } + } + } + } -module.exports = function (args, opts) { - if (!opts) opts = {}; - - var flags = { bools : {}, strings : {}, unknownFn: null }; + if (srcStat.isSymbolicLink()) { + onFresh(); + const linkname = yield readlink(src); + actions.symlink.push({ + dest, + linkname + }); + onDone(); + } else if (srcStat.isDirectory()) { + reporter.verbose(reporter.lang('verboseFileFolder', dest)); + yield mkdirp(dest); - if (typeof opts['unknown'] === 'function') { - flags.unknownFn = opts['unknown']; - } + const destParts = dest.split((_path || _load_path()).default.sep); + while (destParts.length) { + files.add(destParts.join((_path || _load_path()).default.sep).toLowerCase()); + destParts.pop(); + } - if (typeof opts['boolean'] === 'boolean' && opts['boolean']) { - flags.allBools = true; - } else { - [].concat(opts['boolean']).filter(Boolean).forEach(function (key) { - flags.bools[key] = true; - }); - } - - var aliases = {}; - Object.keys(opts.alias || {}).forEach(function (key) { - aliases[key] = [].concat(opts.alias[key]); - aliases[key].forEach(function (x) { - aliases[x] = [key].concat(aliases[key].filter(function (y) { - return x !== y; - })); - }); - }); + // push all files to queue + invariant(srcFiles, 'src files not initialised'); + let remaining = srcFiles.length; + if (!remaining) { + onDone(); + } + for (var _iterator12 = srcFiles, _isArray12 = Array.isArray(_iterator12), _i12 = 0, _iterator12 = _isArray12 ? _iterator12 : _iterator12[Symbol.iterator]();;) { + var _ref16; - [].concat(opts.string).filter(Boolean).forEach(function (key) { - flags.strings[key] = true; - if (aliases[key]) { - flags.strings[aliases[key]] = true; - } - }); + if (_isArray12) { + if (_i12 >= _iterator12.length) break; + _ref16 = _iterator12[_i12++]; + } else { + _i12 = _iterator12.next(); + if (_i12.done) break; + _ref16 = _i12.value; + } - var defaults = opts['default'] || {}; - - var argv = { _ : [] }; - Object.keys(flags.bools).forEach(function (key) { - setArg(key, defaults[key] === undefined ? false : defaults[key]); - }); - - var notFlags = []; + const file = _ref16; - if (args.indexOf('--') !== -1) { - notFlags = args.slice(args.indexOf('--')+1); - args = args.slice(0, args.indexOf('--')); - } + queue.push({ + onFresh, + src: (_path || _load_path()).default.join(src, file), + dest: (_path || _load_path()).default.join(dest, file), + onDone: function (_onDone2) { + function onDone() { + return _onDone2.apply(this, arguments); + } - function argDefined(key, arg) { - return (flags.allBools && /^--[^=]+$/.test(arg)) || - flags.strings[key] || flags.bools[key] || aliases[key]; - } + onDone.toString = function () { + return _onDone2.toString(); + }; - function setArg (key, val, arg) { - if (arg && flags.unknownFn && !argDefined(key, arg)) { - if (flags.unknownFn(arg) === false) return; + return onDone; + }(function () { + if (--remaining === 0) { + onDone(); + } + }) + }); + } + } else if (srcStat.isFile()) { + onFresh(); + actions.link.push({ + src, + dest, + removeDest: destExists + }); + onDone(); + } else { + throw new Error(`unsure how to copy this: ${src}`); } + }); - var value = !flags.strings[key] && isNumber(val) - ? Number(val) : val - ; - setKey(argv, key.split('.'), value); - - (aliases[key] || []).forEach(function (x) { - setKey(argv, x.split('.'), value); - }); - } - - function setKey (obj, keys, value) { - var o = obj; - for (var i = 0; i < keys.length-1; i++) { - var key = keys[i]; - if (key === '__proto__') return; - if (o[key] === undefined) o[key] = {}; - if (o[key] === Object.prototype || o[key] === Number.prototype - || o[key] === String.prototype) o[key] = {}; - if (o[key] === Array.prototype) o[key] = []; - o = o[key]; - } + return function build(_x10) { + return _ref13.apply(this, arguments); + }; + })(); - var key = keys[keys.length - 1]; - if (key === '__proto__') return; - if (o === Object.prototype || o === Number.prototype - || o === String.prototype) o = {}; - if (o === Array.prototype) o = []; - if (o[key] === undefined || flags.bools[key] || typeof o[key] === 'boolean') { - o[key] = value; - } - else if (Array.isArray(o[key])) { - o[key].push(value); - } - else { - o[key] = [ o[key], value ]; - } - } - - function aliasIsBoolean(key) { - return aliases[key].some(function (x) { - return flags.bools[x]; - }); - } + const artifactFiles = new Set(events.artifactFiles || []); + const files = new Set(); - for (var i = 0; i < args.length; i++) { - var arg = args[i]; - - if (/^--.+=/.test(arg)) { - // Using [\s\S] instead of . because js doesn't support the - // 'dotall' regex modifier. See: - // http://stackoverflow.com/a/1068308/13216 - var m = arg.match(/^--([^=]+)=([\s\S]*)$/); - var key = m[1]; - var value = m[2]; - if (flags.bools[key]) { - value = value !== 'false'; - } - setArg(key, value, arg); - } - else if (/^--no-.+/.test(arg)) { - var key = arg.match(/^--no-(.+)/)[1]; - setArg(key, false, arg); - } - else if (/^--.+/.test(arg)) { - var key = arg.match(/^--(.+)/)[1]; - var next = args[i + 1]; - if (next !== undefined && !/^-/.test(next) - && !flags.bools[key] - && !flags.allBools - && (aliases[key] ? !aliasIsBoolean(key) : true)) { - setArg(key, next, arg); - i++; - } - else if (/^(true|false)$/.test(next)) { - setArg(key, next === 'true', arg); - i++; - } - else { - setArg(key, flags.strings[key] ? '' : true, arg); - } - } - else if (/^-[^-]+/.test(arg)) { - var letters = arg.slice(1,-1).split(''); - - var broken = false; - for (var j = 0; j < letters.length; j++) { - var next = arg.slice(j+2); - - if (next === '-') { - setArg(letters[j], next, arg) - continue; - } - - if (/[A-Za-z]/.test(letters[j]) && /=/.test(next)) { - setArg(letters[j], next.split('=')[1], arg); - broken = true; - break; - } - - if (/[A-Za-z]/.test(letters[j]) - && /-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) { - setArg(letters[j], next, arg); - broken = true; - break; - } - - if (letters[j+1] && letters[j+1].match(/\W/)) { - setArg(letters[j], arg.slice(j+2), arg); - broken = true; - break; - } - else { - setArg(letters[j], flags.strings[letters[j]] ? '' : true, arg); - } - } - - var key = arg.slice(-1)[0]; - if (!broken && key !== '-') { - if (args[i+1] && !/^(-|--)[^-]/.test(args[i+1]) - && !flags.bools[key] - && (aliases[key] ? !aliasIsBoolean(key) : true)) { - setArg(key, args[i+1], arg); - i++; - } - else if (args[i+1] && /^(true|false)$/.test(args[i+1])) { - setArg(key, args[i+1] === 'true', arg); - i++; - } - else { - setArg(key, flags.strings[key] ? '' : true, arg); - } - } - } - else { - if (!flags.unknownFn || flags.unknownFn(arg) !== false) { - argv._.push( - flags.strings['_'] || !isNumber(arg) ? arg : Number(arg) - ); - } - if (opts.stopEarly) { - argv._.push.apply(argv._, args.slice(i + 1)); - break; - } - } - } - - Object.keys(defaults).forEach(function (key) { - if (!hasKey(argv, key.split('.'))) { - setKey(argv, key.split('.'), defaults[key]); - - (aliases[key] || []).forEach(function (x) { - setKey(argv, x.split('.'), defaults[key]); - }); - } - }); - - if (opts['--']) { - argv['--'] = new Array(); - notFlags.forEach(function(key) { - argv['--'].push(key); - }); - } - else { - notFlags.forEach(function(key) { - argv._.push(key); - }); - } + // initialise events + for (var _iterator7 = queue, _isArray7 = Array.isArray(_iterator7), _i7 = 0, _iterator7 = _isArray7 ? _iterator7 : _iterator7[Symbol.iterator]();;) { + var _ref10; - return argv; -}; + if (_isArray7) { + if (_i7 >= _iterator7.length) break; + _ref10 = _iterator7[_i7++]; + } else { + _i7 = _iterator7.next(); + if (_i7.done) break; + _ref10 = _i7.value; + } -function hasKey (obj, keys) { - var o = obj; - keys.slice(0,-1).forEach(function (key) { - o = (o[key] || {}); - }); + const item = _ref10; - var key = keys[keys.length - 1]; - return key in o; -} + const onDone = item.onDone || noop; + item.onDone = function () { + events.onProgress(item.dest); + onDone(); + }; + } + events.onStart(queue.length); -function isNumber (x) { - if (typeof x === 'number') return true; - if (/^0x[0-9a-f]+$/i.test(x)) return true; - return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x); -} + // start building actions + const actions = { + file: [], + symlink: [], + link: [] + }; + // custom concurrency logic as we're always executing stacks of CONCURRENT_QUEUE_ITEMS queue items + // at a time due to the requirement to push items onto the queue + while (queue.length) { + const items = queue.splice(0, CONCURRENT_QUEUE_ITEMS); + yield Promise.all(items.map(build)); + } + // simulate the existence of some files to prevent considering them extraneous + for (var _iterator8 = artifactFiles, _isArray8 = Array.isArray(_iterator8), _i8 = 0, _iterator8 = _isArray8 ? _iterator8 : _iterator8[Symbol.iterator]();;) { + var _ref11; -/***/ }), -/* 286 */ -/***/ (function(module) { + if (_isArray8) { + if (_i8 >= _iterator8.length) break; + _ref11 = _iterator8[_i8++]; + } else { + _i8 = _iterator8.next(); + if (_i8.done) break; + _ref11 = _i8.value; + } -module.exports = JSON.parse("{\"name\":\"strong-log-transformer\",\"version\":\"2.1.0\",\"description\":\"Stream transformer that prefixes lines with timestamps and other things.\",\"author\":\"Ryan Graham \",\"license\":\"Apache-2.0\",\"repository\":{\"type\":\"git\",\"url\":\"git://github.com/strongloop/strong-log-transformer\"},\"keywords\":[\"logging\",\"streams\"],\"bugs\":{\"url\":\"https://github.com/strongloop/strong-log-transformer/issues\"},\"homepage\":\"https://github.com/strongloop/strong-log-transformer\",\"directories\":{\"test\":\"test\"},\"bin\":{\"sl-log-transformer\":\"bin/sl-log-transformer.js\"},\"main\":\"index.js\",\"scripts\":{\"test\":\"tap --100 test/test-*\"},\"dependencies\":{\"duplexer\":\"^0.1.1\",\"minimist\":\"^1.2.0\",\"through\":\"^2.3.4\"},\"devDependencies\":{\"tap\":\"^12.0.1\"},\"engines\":{\"node\":\">=4\"}}"); + const file = _ref11; -/***/ }), -/* 287 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + if (possibleExtraneous.has(file)) { + reporter.verbose(reporter.lang('verboseFilePhantomExtraneous', file)); + possibleExtraneous.delete(file); + } + } -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "workspacePackagePaths", function() { return workspacePackagePaths; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "copyWorkspacePackages", function() { return copyWorkspacePackages; }); -/* harmony import */ var glob__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(146); -/* harmony import */ var glob__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(glob__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4); -/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(111); -/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(util__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(288); -/* harmony import */ var _fs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(130); -/* harmony import */ var _package_json__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(164); -/* harmony import */ var _projects__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(145); -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ + for (var _iterator9 = possibleExtraneous, _isArray9 = Array.isArray(_iterator9), _i9 = 0, _iterator9 = _isArray9 ? _iterator9 : _iterator9[Symbol.iterator]();;) { + var _ref12; + if (_isArray9) { + if (_i9 >= _iterator9.length) break; + _ref12 = _iterator9[_i9++]; + } else { + _i9 = _iterator9.next(); + if (_i9.done) break; + _ref12 = _i9.value; + } + const loc = _ref12; + if (files.has(loc.toLowerCase())) { + possibleExtraneous.delete(loc); + } + } + return actions; + }); + return function buildActionsForHardlink(_x6, _x7, _x8, _x9) { + return _ref9.apply(this, arguments); + }; +})(); +let copyBulk = exports.copyBulk = (() => { + var _ref17 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (queue, reporter, _events) { + const events = { + onStart: _events && _events.onStart || noop, + onProgress: _events && _events.onProgress || noop, + possibleExtraneous: _events ? _events.possibleExtraneous : new Set(), + ignoreBasenames: _events && _events.ignoreBasenames || [], + artifactFiles: _events && _events.artifactFiles || [] + }; -const glob = Object(util__WEBPACK_IMPORTED_MODULE_2__["promisify"])(glob__WEBPACK_IMPORTED_MODULE_0___default.a); -async function workspacePackagePaths(rootPath) { - const rootPkgJson = await Object(_package_json__WEBPACK_IMPORTED_MODULE_5__["readPackageJson"])(rootPath); + const actions = yield buildActionsForCopy(queue, events, events.possibleExtraneous, reporter); + events.onStart(actions.file.length + actions.symlink.length + actions.link.length); - if (!rootPkgJson.workspaces) { - return []; - } + const fileActions = actions.file; - const workspacesPathsPatterns = rootPkgJson.workspaces.packages; - let workspaceProjectsPaths = []; + const currentlyWriting = new Map(); - for (const pattern of workspacesPathsPatterns) { - workspaceProjectsPaths = workspaceProjectsPaths.concat(await packagesFromGlobPattern({ - pattern, - rootPath - })); - } // Filter out exclude glob patterns + yield (_promise || _load_promise()).queue(fileActions, (() => { + var _ref18 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (data) { + let writePromise; + while (writePromise = currentlyWriting.get(data.dest)) { + yield writePromise; + } + reporter.verbose(reporter.lang('verboseFileCopy', data.src, data.dest)); + const copier = (0, (_fsNormalized || _load_fsNormalized()).copyFile)(data, function () { + return currentlyWriting.delete(data.dest); + }); + currentlyWriting.set(data.dest, copier); + events.onProgress(data.dest); + return copier; + }); - for (const pattern of workspacesPathsPatterns) { - if (pattern.startsWith('!')) { - const pathToRemove = path__WEBPACK_IMPORTED_MODULE_1___default.a.join(rootPath, pattern.slice(1), 'package.json'); - workspaceProjectsPaths = workspaceProjectsPaths.filter(p => p !== pathToRemove); - } - } + return function (_x14) { + return _ref18.apply(this, arguments); + }; + })(), CONCURRENT_QUEUE_ITEMS); - return workspaceProjectsPaths; -} -async function copyWorkspacePackages(rootPath) { - const projectPaths = Object(_config__WEBPACK_IMPORTED_MODULE_3__["getProjectPaths"])({ - rootPath + // we need to copy symlinks last as they could reference files we were copying + const symlinkActions = actions.symlink; + yield (_promise || _load_promise()).queue(symlinkActions, function (data) { + const linkname = (_path || _load_path()).default.resolve((_path || _load_path()).default.dirname(data.dest), data.linkname); + reporter.verbose(reporter.lang('verboseFileSymlink', data.dest, linkname)); + return symlink(linkname, data.dest); + }); }); - const projects = await Object(_projects__WEBPACK_IMPORTED_MODULE_6__["getProjects"])(rootPath, projectPaths); - for (const project of projects.values()) { - const dest = path__WEBPACK_IMPORTED_MODULE_1___default.a.resolve(rootPath, 'node_modules', project.name); + return function copyBulk(_x11, _x12, _x13) { + return _ref17.apply(this, arguments); + }; +})(); - if ((await Object(_fs__WEBPACK_IMPORTED_MODULE_4__["isSymlink"])(dest)) === false) { - continue; - } // Remove the symlink +let hardlinkBulk = exports.hardlinkBulk = (() => { + var _ref19 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (queue, reporter, _events) { + const events = { + onStart: _events && _events.onStart || noop, + onProgress: _events && _events.onProgress || noop, + possibleExtraneous: _events ? _events.possibleExtraneous : new Set(), + artifactFiles: _events && _events.artifactFiles || [], + ignoreBasenames: [] + }; + const actions = yield buildActionsForHardlink(queue, events, events.possibleExtraneous, reporter); + events.onStart(actions.file.length + actions.symlink.length + actions.link.length); - await Object(_fs__WEBPACK_IMPORTED_MODULE_4__["unlink"])(dest); // Copy in the package + const fileActions = actions.link; - await Object(_fs__WEBPACK_IMPORTED_MODULE_4__["copyDirectory"])(project.path, dest); - } -} + yield (_promise || _load_promise()).queue(fileActions, (() => { + var _ref20 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (data) { + reporter.verbose(reporter.lang('verboseFileLink', data.src, data.dest)); + if (data.removeDest) { + yield (0, (_fsNormalized || _load_fsNormalized()).unlink)(data.dest); + } + yield link(data.src, data.dest); + }); -function packagesFromGlobPattern({ - pattern, - rootPath -}) { - const globOptions = { - cwd: rootPath, - // Should throw in case of unusual errors when reading the file system - strict: true, - // Always returns absolute paths for matched files - absolute: true, - // Do not match ** against multiple filenames - // (This is only specified because we currently don't have a need for it.) - noglobstar: true - }; - return glob(path__WEBPACK_IMPORTED_MODULE_1___default.a.join(pattern, 'package.json'), globOptions); -} + return function (_x18) { + return _ref20.apply(this, arguments); + }; + })(), CONCURRENT_QUEUE_ITEMS); -/***/ }), -/* 288 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + // we need to copy symlinks last as they could reference files we were copying + const symlinkActions = actions.symlink; + yield (_promise || _load_promise()).queue(symlinkActions, function (data) { + const linkname = (_path || _load_path()).default.resolve((_path || _load_path()).default.dirname(data.dest), data.linkname); + reporter.verbose(reporter.lang('verboseFileSymlink', data.dest, linkname)); + return symlink(linkname, data.dest); + }); + }); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getProjectPaths", function() { return getProjectPaths; }); -/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4); -/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_0__); -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ + return function hardlinkBulk(_x15, _x16, _x17) { + return _ref19.apply(this, arguments); + }; +})(); +let readFileAny = exports.readFileAny = (() => { + var _ref21 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (files) { + for (var _iterator13 = files, _isArray13 = Array.isArray(_iterator13), _i13 = 0, _iterator13 = _isArray13 ? _iterator13 : _iterator13[Symbol.iterator]();;) { + var _ref22; -/** - * Returns all the paths where plugins are located - */ -function getProjectPaths({ - rootPath, - ossOnly, - skipKibanaPlugins -}) { - const projectPaths = [rootPath, Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, 'packages/*')]; // This is needed in order to install the dependencies for the declared - // plugin functional used in the selenium functional tests. - // As we are now using the webpack dll for the client vendors dependencies - // when we run the plugin functional tests against the distributable - // dependencies used by such plugins like @eui, react and react-dom can't - // be loaded from the dll as the context is different from the one declared - // into the webpack dll reference plugin. - // In anyway, have a plugin declaring their own dependencies is the - // correct and the expect behavior. + if (_isArray13) { + if (_i13 >= _iterator13.length) break; + _ref22 = _iterator13[_i13++]; + } else { + _i13 = _iterator13.next(); + if (_i13.done) break; + _ref22 = _i13.value; + } - projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, 'test/plugin_functional/plugins/*')); - projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, 'test/interpreter_functional/plugins/*')); - projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, 'examples/*')); + const file = _ref22; - if (!ossOnly) { - projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, 'x-pack')); - projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, 'x-pack/plugins/*')); - projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, 'x-pack/legacy/plugins/*')); - projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, 'x-pack/test/functional_with_es_ssl/fixtures/plugins/*')); - } + if (yield exists(file)) { + return readFile(file); + } + } + return null; + }); - if (!skipKibanaPlugins) { - projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, '../kibana-extra/*')); - projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, '../kibana-extra/*/packages/*')); - projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, '../kibana-extra/*/plugins/*')); - projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, 'plugins/*')); - projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, 'plugins/*/packages/*')); - projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, 'plugins/*/plugins/*')); - } + return function readFileAny(_x19) { + return _ref21.apply(this, arguments); + }; +})(); - return projectPaths; -} +let readJson = exports.readJson = (() => { + var _ref23 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (loc) { + return (yield readJsonAndFile(loc)).object; + }); -/***/ }), -/* 289 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + return function readJson(_x20) { + return _ref23.apply(this, arguments); + }; +})(); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getAllChecksums", function() { return getAllChecksums; }); -/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(133); -/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(fs__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var crypto__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(290); -/* harmony import */ var crypto__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(crypto__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(111); -/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(util__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(244); -/* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(execa__WEBPACK_IMPORTED_MODULE_3__); -/* harmony import */ var _yarn_lock__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(291); -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ +let readJsonAndFile = exports.readJsonAndFile = (() => { + var _ref24 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (loc) { + const file = yield readFile(loc); + try { + return { + object: (0, (_map || _load_map()).default)(JSON.parse(stripBOM(file))), + content: file + }; + } catch (err) { + err.message = `${loc}: ${err.message}`; + throw err; + } + }); + return function readJsonAndFile(_x21) { + return _ref24.apply(this, arguments); + }; +})(); +let find = exports.find = (() => { + var _ref25 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (filename, dir) { + const parts = dir.split((_path || _load_path()).default.sep); + while (parts.length) { + const loc = parts.concat(filename).join((_path || _load_path()).default.sep); + if (yield exists(loc)) { + return loc; + } else { + parts.pop(); + } + } -const statAsync = Object(util__WEBPACK_IMPORTED_MODULE_2__["promisify"])(fs__WEBPACK_IMPORTED_MODULE_0___default.a.stat); + return false; + }); -const projectBySpecificitySorter = (a, b) => b.path.length - a.path.length; -/** Get the changed files for a set of projects */ + return function find(_x22, _x23) { + return _ref25.apply(this, arguments); + }; +})(); +let symlink = exports.symlink = (() => { + var _ref26 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (src, dest) { + try { + const stats = yield lstat(dest); + if (stats.isSymbolicLink()) { + const resolved = yield realpath(dest); + if (resolved === src) { + return; + } + } + } catch (err) { + if (err.code !== 'ENOENT') { + throw err; + } + } + // We use rimraf for unlink which never throws an ENOENT on missing target + yield (0, (_fsNormalized || _load_fsNormalized()).unlink)(dest); -async function getChangesForProjects(projects, kbn, log) { - log.verbose('getting changed files'); - const { - stdout - } = await execa__WEBPACK_IMPORTED_MODULE_3___default()('git', ['ls-files', '-dmto', '--exclude-standard', '--', ...Array.from(projects.values()).filter(p => kbn.isPartOfRepo(p)).map(p => p.path)], { - cwd: kbn.getAbsolute() + if (process.platform === 'win32') { + // use directory junctions if possible on win32, this requires absolute paths + yield fsSymlink(src, dest, 'junction'); + } else { + // use relative paths otherwise which will be retained if the directory is moved + let relative; + try { + relative = (_path || _load_path()).default.relative((_fs || _load_fs()).default.realpathSync((_path || _load_path()).default.dirname(dest)), (_fs || _load_fs()).default.realpathSync(src)); + } catch (err) { + if (err.code !== 'ENOENT') { + throw err; + } + relative = (_path || _load_path()).default.relative((_path || _load_path()).default.dirname(dest), src); + } + // When path.relative returns an empty string for the current directory, we should instead use + // '.', which is a valid fs.symlink target. + yield fsSymlink(relative || '.', dest); + } }); - const output = stdout.trim(); - const unassignedChanges = new Map(); - - if (output) { - for (const line of output.split('\n')) { - const [tag, ...pathParts] = line.trim().split(' '); - const path = pathParts.join(' '); - switch (tag) { - case 'M': - case 'C': - // for some reason ls-files returns deleted files as both deleted - // and modified, so make sure not to overwrite changes already - // tracked as "deleted" - if (unassignedChanges.get(path) !== 'deleted') { - unassignedChanges.set(path, 'modified'); - } + return function symlink(_x24, _x25) { + return _ref26.apply(this, arguments); + }; +})(); - break; +let walk = exports.walk = (() => { + var _ref27 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (dir, relativeDir, ignoreBasenames = new Set()) { + let files = []; - case 'R': - unassignedChanges.set(path, 'deleted'); - break; + let filenames = yield readdir(dir); + if (ignoreBasenames.size) { + filenames = filenames.filter(function (name) { + return !ignoreBasenames.has(name); + }); + } - case '?': - unassignedChanges.set(path, 'untracked'); - break; + for (var _iterator14 = filenames, _isArray14 = Array.isArray(_iterator14), _i14 = 0, _iterator14 = _isArray14 ? _iterator14 : _iterator14[Symbol.iterator]();;) { + var _ref28; - case 'H': - case 'S': - case 'K': - default: - log.warning(`unexpected modification status "${tag}" for ${path}, please report this!`); - unassignedChanges.set(path, 'invalid'); - break; + if (_isArray14) { + if (_i14 >= _iterator14.length) break; + _ref28 = _iterator14[_i14++]; + } else { + _i14 = _iterator14.next(); + if (_i14.done) break; + _ref28 = _i14.value; } - } - } - const sortedRelevantProjects = Array.from(projects.values()).sort(projectBySpecificitySorter); - const changesByProject = new Map(); + const name = _ref28; - for (const project of sortedRelevantProjects) { - if (kbn.isOutsideRepo(project)) { - changesByProject.set(project, undefined); - continue; - } + const relative = relativeDir ? (_path || _load_path()).default.join(relativeDir, name) : name; + const loc = (_path || _load_path()).default.join(dir, name); + const stat = yield lstat(loc); - const ownChanges = new Map(); - const prefix = kbn.getRelative(project.path); + files.push({ + relative, + basename: name, + absolute: loc, + mtime: +stat.mtime + }); - for (const [path, type] of unassignedChanges) { - if (path.startsWith(prefix)) { - ownChanges.set(path, type); - unassignedChanges.delete(path); + if (stat.isDirectory()) { + files = files.concat((yield walk(loc, relative, ignoreBasenames))); } } - log.verbose(`[${project.name}] found ${ownChanges.size} changes`); - changesByProject.set(project, ownChanges); - } - - if (unassignedChanges.size) { - throw new Error(`unable to assign all change paths to a project: ${JSON.stringify(Array.from(unassignedChanges.entries()))}`); - } + return files; + }); - return changesByProject; -} -/** Get the latest commit sha for a project */ + return function walk(_x26, _x27) { + return _ref27.apply(this, arguments); + }; +})(); +let getFileSizeOnDisk = exports.getFileSizeOnDisk = (() => { + var _ref29 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (loc) { + const stat = yield lstat(loc); + const size = stat.size, + blockSize = stat.blksize; -async function getLatestSha(project, kbn) { - if (kbn.isOutsideRepo(project)) { - return; - } - const { - stdout - } = await execa__WEBPACK_IMPORTED_MODULE_3___default()('git', ['log', '-n', '1', '--pretty=format:%H', '--', project.path], { - cwd: kbn.getAbsolute() + return Math.ceil(size / blockSize) * blockSize; }); - return stdout.trim() || undefined; -} -/** - * Get a list of the absolute dependencies of this project, as resolved - * in the yarn.lock file, does not include other projects in the workspace - * or their dependencies - */ + return function getFileSizeOnDisk(_x28) { + return _ref29.apply(this, arguments); + }; +})(); -function resolveDepsForProject(project, yarnLock, kbn, log) { - /** map of [name@range, name@resolved] */ - const resolved = new Map(); - const queue = Object.entries(project.allDependencies); +let getEolFromFile = (() => { + var _ref30 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (path) { + if (!(yield exists(path))) { + return undefined; + } - while (queue.length) { - const [name, versionRange] = queue.shift(); - const req = `${name}@${versionRange}`; + const buffer = yield readFileBuffer(path); - if (resolved.has(req)) { - continue; + for (let i = 0; i < buffer.length; ++i) { + if (buffer[i] === cr) { + return '\r\n'; + } + if (buffer[i] === lf) { + return '\n'; + } } + return undefined; + }); - if (!kbn.hasProject(name)) { - const pkg = yarnLock[req]; + return function getEolFromFile(_x29) { + return _ref30.apply(this, arguments); + }; +})(); - if (!pkg) { - log.warning('yarn.lock file is out of date, please run `yarn kbn bootstrap` to re-enable caching'); - return; - } +let writeFilePreservingEol = exports.writeFilePreservingEol = (() => { + var _ref31 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (path, data) { + const eol = (yield getEolFromFile(path)) || (_os || _load_os()).default.EOL; + if (eol !== '\n') { + data = data.replace(/\n/g, eol); + } + yield writeFile(path, data); + }); - const res = `${name}@${pkg.version}`; - resolved.set(req, res); - const allDepsEntries = [...Object.entries(pkg.dependencies || {}), ...Object.entries(pkg.optionalDependencies || {})]; + return function writeFilePreservingEol(_x30, _x31) { + return _ref31.apply(this, arguments); + }; +})(); - for (const [childName, childVersionRange] of allDepsEntries) { - queue.push([childName, childVersionRange]); - } +let hardlinksWork = exports.hardlinksWork = (() => { + var _ref32 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (dir) { + const filename = 'test-file' + Math.random(); + const file = (_path || _load_path()).default.join(dir, filename); + const fileLink = (_path || _load_path()).default.join(dir, filename + '-link'); + try { + yield writeFile(file, 'test'); + yield link(file, fileLink); + } catch (err) { + return false; + } finally { + yield (0, (_fsNormalized || _load_fsNormalized()).unlink)(file); + yield (0, (_fsNormalized || _load_fsNormalized()).unlink)(fileLink); } - } + return true; + }); - return Array.from(resolved.values()).sort((a, b) => a.localeCompare(b)); -} -/** - * Get the checksum for a specific project in the workspace - */ + return function hardlinksWork(_x32) { + return _ref32.apply(this, arguments); + }; +})(); +// not a strict polyfill for Node's fs.mkdtemp -async function getChecksum(project, changes, yarnLock, kbn, log) { - const sha = await getLatestSha(project, kbn); - if (sha) { - log.verbose(`[${project.name}] local sha:`, sha); - } +let makeTempDir = exports.makeTempDir = (() => { + var _ref33 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (prefix) { + const dir = (_path || _load_path()).default.join((_os || _load_os()).default.tmpdir(), `yarn-${prefix || ''}-${Date.now()}-${Math.random()}`); + yield (0, (_fsNormalized || _load_fsNormalized()).unlink)(dir); + yield mkdirp(dir); + return dir; + }); - if (!changes || Array.from(changes.values()).includes('invalid')) { - log.warning(`[${project.name}] unable to determine local changes, caching disabled`); - return; - } + return function makeTempDir(_x33) { + return _ref33.apply(this, arguments); + }; +})(); - const changesSummary = await Promise.all(Array.from(changes).sort((a, b) => a[0].localeCompare(b[0])).map(async ([path, type]) => { - if (type === 'deleted') { - return `${path}:deleted`; - } +let readFirstAvailableStream = exports.readFirstAvailableStream = (() => { + var _ref34 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (paths) { + for (var _iterator15 = paths, _isArray15 = Array.isArray(_iterator15), _i15 = 0, _iterator15 = _isArray15 ? _iterator15 : _iterator15[Symbol.iterator]();;) { + var _ref35; - const stats = await statAsync(kbn.getAbsolute(path)); - log.verbose(`[${project.name}] modified time ${stats.mtimeMs} for ${path}`); - return `${path}:${stats.mtimeMs}`; - })); - const deps = await resolveDepsForProject(project, yarnLock, kbn, log); + if (_isArray15) { + if (_i15 >= _iterator15.length) break; + _ref35 = _iterator15[_i15++]; + } else { + _i15 = _iterator15.next(); + if (_i15.done) break; + _ref35 = _i15.value; + } - if (!deps) { - return; - } + const path = _ref35; - log.verbose(`[${project.name}] resolved %d deps`, deps.length); - const checksum = JSON.stringify({ - sha, - changes: changesSummary, - deps - }, null, 2); + try { + const fd = yield open(path, 'r'); + return (_fs || _load_fs()).default.createReadStream(path, { fd }); + } catch (err) { + // Try the next one + } + } + return null; + }); - if (process.env.BOOTSTRAP_CACHE_DEBUG_CHECKSUM) { - return checksum; - } + return function readFirstAvailableStream(_x34) { + return _ref34.apply(this, arguments); + }; +})(); - const hash = crypto__WEBPACK_IMPORTED_MODULE_1___default.a.createHash('sha1'); - hash.update(checksum); - return hash.digest('hex'); -} -/** - * Calculate checksums for all projects in the workspace based on - * - last git commit to project directory - * - un-committed changes - * - resolved dependencies from yarn.lock referenced by project package.json - */ +let getFirstSuitableFolder = exports.getFirstSuitableFolder = (() => { + var _ref36 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (paths, mode = constants.W_OK | constants.X_OK) { + const result = { + skipped: [], + folder: null + }; + for (var _iterator16 = paths, _isArray16 = Array.isArray(_iterator16), _i16 = 0, _iterator16 = _isArray16 ? _iterator16 : _iterator16[Symbol.iterator]();;) { + var _ref37; -async function getAllChecksums(kbn, log) { - const projects = kbn.getAllProjects(); - const changesByProject = await getChangesForProjects(projects, kbn, log); - const yarnLock = await Object(_yarn_lock__WEBPACK_IMPORTED_MODULE_4__["readYarnLock"])(kbn); - /** map of [project.name, cacheKey] */ + if (_isArray16) { + if (_i16 >= _iterator16.length) break; + _ref37 = _iterator16[_i16++]; + } else { + _i16 = _iterator16.next(); + if (_i16.done) break; + _ref37 = _i16.value; + } - const cacheKeys = new Map(); - await Promise.all(Array.from(projects.values()).map(async project => { - cacheKeys.set(project.name, await getChecksum(project, changesByProject.get(project), yarnLock, kbn, log)); - })); - return cacheKeys; -} + const folder = _ref37; -/***/ }), -/* 290 */ -/***/ (function(module, exports) { + try { + yield mkdirp(folder); + yield access(folder, mode); -module.exports = require("crypto"); + result.folder = folder; -/***/ }), -/* 291 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + return result; + } catch (error) { + result.skipped.push({ + error, + folder + }); + } + } + return result; + }); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "readYarnLock", function() { return readYarnLock; }); -/* harmony import */ var _yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(292); -/* harmony import */ var _yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _utils_fs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(130); -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -// @ts-ignore published types are worthless + return function getFirstSuitableFolder(_x35) { + return _ref36.apply(this, arguments); + }; +})(); +exports.copy = copy; +exports.readFile = readFile; +exports.readFileRaw = readFileRaw; +exports.normalizeOS = normalizeOS; -async function readYarnLock(kbn) { - try { - const contents = await Object(_utils_fs__WEBPACK_IMPORTED_MODULE_1__["readFile"])(kbn.getAbsolute('yarn.lock'), 'utf8'); - const yarnLock = Object(_yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0__["parse"])(contents); +var _fs; - if (yarnLock.type === 'success') { - return yarnLock.object; - } +function _load_fs() { + return _fs = _interopRequireDefault(__webpack_require__(3)); +} - throw new Error('unable to read yarn.lock file, please run `yarn kbn bootstrap`'); - } catch (error) { - if (error.code !== 'ENOENT') { - throw error; - } - } +var _glob; - return {}; +function _load_glob() { + return _glob = _interopRequireDefault(__webpack_require__(75)); } -/***/ }), -/* 292 */ -/***/ (function(module, exports, __webpack_require__) { +var _os; -module.exports = -/******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; -/******/ -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; -/******/ -/******/ // identity function for calling harmony imports with the correct context -/******/ __webpack_require__.i = function(value) { return value; }; -/******/ -/******/ // define getter function for harmony exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ if(!__webpack_require__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { -/******/ configurable: false, -/******/ enumerable: true, -/******/ get: getter -/******/ }); -/******/ } -/******/ }; -/******/ -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; -/******/ -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; -/******/ -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; -/******/ -/******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 14); -/******/ }) -/************************************************************************/ -/******/ ([ -/* 0 */ -/***/ (function(module, exports) { +function _load_os() { + return _os = _interopRequireDefault(__webpack_require__(36)); +} -module.exports = __webpack_require__(4); +var _path; -/***/ }), -/* 1 */ -/***/ (function(module, exports, __webpack_require__) { +function _load_path() { + return _path = _interopRequireDefault(__webpack_require__(0)); +} -"use strict"; +var _blockingQueue; +function _load_blockingQueue() { + return _blockingQueue = _interopRequireDefault(__webpack_require__(84)); +} -exports.__esModule = true; +var _promise; -var _promise = __webpack_require__(173); +function _load_promise() { + return _promise = _interopRequireWildcard(__webpack_require__(40)); +} -var _promise2 = _interopRequireDefault(_promise); +var _promise2; -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +function _load_promise2() { + return _promise2 = __webpack_require__(40); +} -exports.default = function (fn) { - return function () { - var gen = fn.apply(this, arguments); - return new _promise2.default(function (resolve, reject) { - function step(key, arg) { - try { - var info = gen[key](arg); - var value = info.value; - } catch (error) { - reject(error); - return; - } +var _map; - if (info.done) { - resolve(value); - } else { - return _promise2.default.resolve(value).then(function (value) { - step("next", value); - }, function (err) { - step("throw", err); - }); - } - } +function _load_map() { + return _map = _interopRequireDefault(__webpack_require__(20)); +} - return step("next"); - }); - }; -}; +var _fsNormalized; -/***/ }), -/* 2 */ -/***/ (function(module, exports) { +function _load_fsNormalized() { + return _fsNormalized = __webpack_require__(164); +} -module.exports = __webpack_require__(111); +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } -/***/ }), -/* 3 */ -/***/ (function(module, exports) { +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -module.exports = __webpack_require__(133); +const constants = exports.constants = typeof (_fs || _load_fs()).default.constants !== 'undefined' ? (_fs || _load_fs()).default.constants : { + R_OK: (_fs || _load_fs()).default.R_OK, + W_OK: (_fs || _load_fs()).default.W_OK, + X_OK: (_fs || _load_fs()).default.X_OK +}; -/***/ }), -/* 4 */ -/***/ (function(module, exports, __webpack_require__) { +const lockQueue = exports.lockQueue = new (_blockingQueue || _load_blockingQueue()).default('fs lock'); -"use strict"; +const readFileBuffer = exports.readFileBuffer = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.readFile); +const open = exports.open = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.open); +const writeFile = exports.writeFile = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.writeFile); +const readlink = exports.readlink = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.readlink); +const realpath = exports.realpath = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.realpath); +const readdir = exports.readdir = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.readdir); +const rename = exports.rename = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.rename); +const access = exports.access = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.access); +const stat = exports.stat = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.stat); +const mkdirp = exports.mkdirp = (0, (_promise2 || _load_promise2()).promisify)(__webpack_require__(116)); +const exists = exports.exists = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.exists, true); +const lstat = exports.lstat = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.lstat); +const chmod = exports.chmod = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.chmod); +const link = exports.link = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.link); +const glob = exports.glob = (0, (_promise2 || _load_promise2()).promisify)((_glob || _load_glob()).default); +exports.unlink = (_fsNormalized || _load_fsNormalized()).unlink; +// fs.copyFile uses the native file copying instructions on the system, performing much better +// than any JS-based solution and consumes fewer resources. Repeated testing to fine tune the +// concurrency level revealed 128 as the sweet spot on a quad-core, 16 CPU Intel system with SSD. -Object.defineProperty(exports, "__esModule", { - value: true -}); -class MessageError extends Error { - constructor(msg, code) { - super(msg); - this.code = code; - } +const CONCURRENT_QUEUE_ITEMS = (_fs || _load_fs()).default.copyFile ? 128 : 4; -} +const fsSymlink = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.symlink); +const invariant = __webpack_require__(7); +const stripBOM = __webpack_require__(122); -exports.MessageError = MessageError; -class ProcessSpawnError extends MessageError { - constructor(msg, code, process) { - super(msg, code); - this.process = process; - } +const noop = () => {}; +function copy(src, dest, reporter) { + return copyBulk([{ src, dest }], reporter); } -exports.ProcessSpawnError = ProcessSpawnError; -class SecurityError extends MessageError {} +function _readFile(loc, encoding) { + return new Promise((resolve, reject) => { + (_fs || _load_fs()).default.readFile(loc, encoding, function (err, content) { + if (err) { + reject(err); + } else { + resolve(content); + } + }); + }); +} -exports.SecurityError = SecurityError; -class ProcessTermError extends MessageError {} +function readFile(loc) { + return _readFile(loc, 'utf8').then(normalizeOS); +} -exports.ProcessTermError = ProcessTermError; -class ResponseError extends Error { - constructor(msg, responseCode) { - super(msg); - this.responseCode = responseCode; - } +function readFileRaw(loc) { + return _readFile(loc, 'binary'); +} +function normalizeOS(body) { + return body.replace(/\r\n/g, '\n'); } -exports.ResponseError = ResponseError; + +const cr = '\r'.charCodeAt(0); +const lf = '\n'.charCodeAt(0); /***/ }), -/* 5 */ +/* 6 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -30863,1181 +30528,867 @@ exports.ResponseError = ResponseError; Object.defineProperty(exports, "__esModule", { value: true }); -exports.getFirstSuitableFolder = exports.readFirstAvailableStream = exports.makeTempDir = exports.hardlinksWork = exports.writeFilePreservingEol = exports.getFileSizeOnDisk = exports.walk = exports.symlink = exports.find = exports.readJsonAndFile = exports.readJson = exports.readFileAny = exports.hardlinkBulk = exports.copyBulk = exports.unlink = exports.glob = exports.link = exports.chmod = exports.lstat = exports.exists = exports.mkdirp = exports.stat = exports.access = exports.rename = exports.readdir = exports.realpath = exports.readlink = exports.writeFile = exports.open = exports.readFileBuffer = exports.lockQueue = exports.constants = undefined; +exports.getPathKey = getPathKey; +const os = __webpack_require__(36); +const path = __webpack_require__(0); +const userHome = __webpack_require__(45).default; -var _asyncToGenerator2; +var _require = __webpack_require__(171); -function _load_asyncToGenerator() { - return _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(1)); -} +const getCacheDir = _require.getCacheDir, + getConfigDir = _require.getConfigDir, + getDataDir = _require.getDataDir; -let buildActionsForCopy = (() => { - var _ref = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (queue, events, possibleExtraneous, reporter) { +const isWebpackBundle = __webpack_require__(227); - // - let build = (() => { - var _ref5 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (data) { - const src = data.src, - dest = data.dest, - type = data.type; +const DEPENDENCY_TYPES = exports.DEPENDENCY_TYPES = ['devDependencies', 'dependencies', 'optionalDependencies', 'peerDependencies']; +const RESOLUTIONS = exports.RESOLUTIONS = 'resolutions'; +const MANIFEST_FIELDS = exports.MANIFEST_FIELDS = [RESOLUTIONS, ...DEPENDENCY_TYPES]; - const onFresh = data.onFresh || noop; - const onDone = data.onDone || noop; +const SUPPORTED_NODE_VERSIONS = exports.SUPPORTED_NODE_VERSIONS = '^4.8.0 || ^5.7.0 || ^6.2.2 || >=8.0.0'; - // TODO https://github.com/yarnpkg/yarn/issues/3751 - // related to bundled dependencies handling - if (files.has(dest.toLowerCase())) { - reporter.verbose(`The case-insensitive file ${dest} shouldn't be copied twice in one bulk copy`); - } else { - files.add(dest.toLowerCase()); - } +const YARN_REGISTRY = exports.YARN_REGISTRY = 'https://registry.yarnpkg.com'; - if (type === 'symlink') { - yield mkdirp((_path || _load_path()).default.dirname(dest)); - onFresh(); - actions.symlink.push({ - dest, - linkname: src - }); - onDone(); - return; - } +const YARN_DOCS = exports.YARN_DOCS = 'https://yarnpkg.com/en/docs/cli/'; +const YARN_INSTALLER_SH = exports.YARN_INSTALLER_SH = 'https://yarnpkg.com/install.sh'; +const YARN_INSTALLER_MSI = exports.YARN_INSTALLER_MSI = 'https://yarnpkg.com/latest.msi'; - if (events.ignoreBasenames.indexOf((_path || _load_path()).default.basename(src)) >= 0) { - // ignored file - return; - } +const SELF_UPDATE_VERSION_URL = exports.SELF_UPDATE_VERSION_URL = 'https://yarnpkg.com/latest-version'; - const srcStat = yield lstat(src); - let srcFiles; +// cache version, bump whenever we make backwards incompatible changes +const CACHE_VERSION = exports.CACHE_VERSION = 2; - if (srcStat.isDirectory()) { - srcFiles = yield readdir(src); - } +// lockfile version, bump whenever we make backwards incompatible changes +const LOCKFILE_VERSION = exports.LOCKFILE_VERSION = 1; - let destStat; - try { - // try accessing the destination - destStat = yield lstat(dest); - } catch (e) { - // proceed if destination doesn't exist, otherwise error - if (e.code !== 'ENOENT') { - throw e; - } - } +// max amount of network requests to perform concurrently +const NETWORK_CONCURRENCY = exports.NETWORK_CONCURRENCY = 8; - // if destination exists - if (destStat) { - const bothSymlinks = srcStat.isSymbolicLink() && destStat.isSymbolicLink(); - const bothFolders = srcStat.isDirectory() && destStat.isDirectory(); - const bothFiles = srcStat.isFile() && destStat.isFile(); +// HTTP timeout used when downloading packages +const NETWORK_TIMEOUT = exports.NETWORK_TIMEOUT = 30 * 1000; // in milliseconds - // EINVAL access errors sometimes happen which shouldn't because node shouldn't be giving - // us modes that aren't valid. investigate this, it's generally safe to proceed. +// max amount of child processes to execute concurrently +const CHILD_CONCURRENCY = exports.CHILD_CONCURRENCY = 5; - /* if (srcStat.mode !== destStat.mode) { - try { - await access(dest, srcStat.mode); - } catch (err) {} - } */ +const REQUIRED_PACKAGE_KEYS = exports.REQUIRED_PACKAGE_KEYS = ['name', 'version', '_uid']; - if (bothFiles && artifactFiles.has(dest)) { - // this file gets changed during build, likely by a custom install script. Don't bother checking it. - onDone(); - reporter.verbose(reporter.lang('verboseFileSkipArtifact', src)); - return; - } +function getPreferredCacheDirectories() { + const preferredCacheDirectories = [getCacheDir()]; - if (bothFiles && srcStat.size === destStat.size && (0, (_fsNormalized || _load_fsNormalized()).fileDatesEqual)(srcStat.mtime, destStat.mtime)) { - // we can safely assume this is the same file - onDone(); - reporter.verbose(reporter.lang('verboseFileSkip', src, dest, srcStat.size, +srcStat.mtime)); - return; - } + if (process.getuid) { + // $FlowFixMe: process.getuid exists, dammit + preferredCacheDirectories.push(path.join(os.tmpdir(), `.yarn-cache-${process.getuid()}`)); + } - if (bothSymlinks) { - const srcReallink = yield readlink(src); - if (srcReallink === (yield readlink(dest))) { - // if both symlinks are the same then we can continue on - onDone(); - reporter.verbose(reporter.lang('verboseFileSkipSymlink', src, dest, srcReallink)); - return; - } - } + preferredCacheDirectories.push(path.join(os.tmpdir(), `.yarn-cache`)); - if (bothFolders) { - // mark files that aren't in this folder as possibly extraneous - const destFiles = yield readdir(dest); - invariant(srcFiles, 'src files not initialised'); + return preferredCacheDirectories; +} - for (var _iterator4 = destFiles, _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) { - var _ref6; +const PREFERRED_MODULE_CACHE_DIRECTORIES = exports.PREFERRED_MODULE_CACHE_DIRECTORIES = getPreferredCacheDirectories(); +const CONFIG_DIRECTORY = exports.CONFIG_DIRECTORY = getConfigDir(); +const DATA_DIRECTORY = exports.DATA_DIRECTORY = getDataDir(); +const LINK_REGISTRY_DIRECTORY = exports.LINK_REGISTRY_DIRECTORY = path.join(DATA_DIRECTORY, 'link'); +const GLOBAL_MODULE_DIRECTORY = exports.GLOBAL_MODULE_DIRECTORY = path.join(DATA_DIRECTORY, 'global'); - if (_isArray4) { - if (_i4 >= _iterator4.length) break; - _ref6 = _iterator4[_i4++]; - } else { - _i4 = _iterator4.next(); - if (_i4.done) break; - _ref6 = _i4.value; - } +const NODE_BIN_PATH = exports.NODE_BIN_PATH = process.execPath; +const YARN_BIN_PATH = exports.YARN_BIN_PATH = getYarnBinPath(); - const file = _ref6; +// Webpack needs to be configured with node.__dirname/__filename = false +function getYarnBinPath() { + if (isWebpackBundle) { + return __filename; + } else { + return path.join(__dirname, '..', 'bin', 'yarn.js'); + } +} - if (srcFiles.indexOf(file) < 0) { - const loc = (_path || _load_path()).default.join(dest, file); - possibleExtraneous.add(loc); +const NODE_MODULES_FOLDER = exports.NODE_MODULES_FOLDER = 'node_modules'; +const NODE_PACKAGE_JSON = exports.NODE_PACKAGE_JSON = 'package.json'; - if ((yield lstat(loc)).isDirectory()) { - for (var _iterator5 = yield readdir(loc), _isArray5 = Array.isArray(_iterator5), _i5 = 0, _iterator5 = _isArray5 ? _iterator5 : _iterator5[Symbol.iterator]();;) { - var _ref7; +const POSIX_GLOBAL_PREFIX = exports.POSIX_GLOBAL_PREFIX = `${process.env.DESTDIR || ''}/usr/local`; +const FALLBACK_GLOBAL_PREFIX = exports.FALLBACK_GLOBAL_PREFIX = path.join(userHome, '.yarn'); - if (_isArray5) { - if (_i5 >= _iterator5.length) break; - _ref7 = _iterator5[_i5++]; - } else { - _i5 = _iterator5.next(); - if (_i5.done) break; - _ref7 = _i5.value; - } +const META_FOLDER = exports.META_FOLDER = '.yarn-meta'; +const INTEGRITY_FILENAME = exports.INTEGRITY_FILENAME = '.yarn-integrity'; +const LOCKFILE_FILENAME = exports.LOCKFILE_FILENAME = 'yarn.lock'; +const METADATA_FILENAME = exports.METADATA_FILENAME = '.yarn-metadata.json'; +const TARBALL_FILENAME = exports.TARBALL_FILENAME = '.yarn-tarball.tgz'; +const CLEAN_FILENAME = exports.CLEAN_FILENAME = '.yarnclean'; - const file = _ref7; +const NPM_LOCK_FILENAME = exports.NPM_LOCK_FILENAME = 'package-lock.json'; +const NPM_SHRINKWRAP_FILENAME = exports.NPM_SHRINKWRAP_FILENAME = 'npm-shrinkwrap.json'; - possibleExtraneous.add((_path || _load_path()).default.join(loc, file)); - } - } - } - } - } - } +const DEFAULT_INDENT = exports.DEFAULT_INDENT = ' '; +const SINGLE_INSTANCE_PORT = exports.SINGLE_INSTANCE_PORT = 31997; +const SINGLE_INSTANCE_FILENAME = exports.SINGLE_INSTANCE_FILENAME = '.yarn-single-instance'; - if (destStat && destStat.isSymbolicLink()) { - yield (0, (_fsNormalized || _load_fsNormalized()).unlink)(dest); - destStat = null; - } +const ENV_PATH_KEY = exports.ENV_PATH_KEY = getPathKey(process.platform, process.env); - if (srcStat.isSymbolicLink()) { - onFresh(); - const linkname = yield readlink(src); - actions.symlink.push({ - dest, - linkname - }); - onDone(); - } else if (srcStat.isDirectory()) { - if (!destStat) { - reporter.verbose(reporter.lang('verboseFileFolder', dest)); - yield mkdirp(dest); - } +function getPathKey(platform, env) { + let pathKey = 'PATH'; - const destParts = dest.split((_path || _load_path()).default.sep); - while (destParts.length) { - files.add(destParts.join((_path || _load_path()).default.sep).toLowerCase()); - destParts.pop(); - } - - // push all files to queue - invariant(srcFiles, 'src files not initialised'); - let remaining = srcFiles.length; - if (!remaining) { - onDone(); - } - for (var _iterator6 = srcFiles, _isArray6 = Array.isArray(_iterator6), _i6 = 0, _iterator6 = _isArray6 ? _iterator6 : _iterator6[Symbol.iterator]();;) { - var _ref8; - - if (_isArray6) { - if (_i6 >= _iterator6.length) break; - _ref8 = _iterator6[_i6++]; - } else { - _i6 = _iterator6.next(); - if (_i6.done) break; - _ref8 = _i6.value; - } + // windows calls its path "Path" usually, but this is not guaranteed. + if (platform === 'win32') { + pathKey = 'Path'; - const file = _ref8; + for (const key in env) { + if (key.toLowerCase() === 'path') { + pathKey = key; + } + } + } - queue.push({ - dest: (_path || _load_path()).default.join(dest, file), - onFresh, - onDone: function (_onDone) { - function onDone() { - return _onDone.apply(this, arguments); - } + return pathKey; +} - onDone.toString = function () { - return _onDone.toString(); - }; +const VERSION_COLOR_SCHEME = exports.VERSION_COLOR_SCHEME = { + major: 'red', + premajor: 'red', + minor: 'yellow', + preminor: 'yellow', + patch: 'green', + prepatch: 'green', + prerelease: 'red', + unchanged: 'white', + unknown: 'red' +}; - return onDone; - }(function () { - if (--remaining === 0) { - onDone(); - } - }), - src: (_path || _load_path()).default.join(src, file) - }); - } - } else if (srcStat.isFile()) { - onFresh(); - actions.file.push({ - src, - dest, - atime: srcStat.atime, - mtime: srcStat.mtime, - mode: srcStat.mode - }); - onDone(); - } else { - throw new Error(`unsure how to copy this: ${src}`); - } - }); +/***/ }), +/* 7 */ +/***/ (function(module, exports, __webpack_require__) { - return function build(_x5) { - return _ref5.apply(this, arguments); - }; - })(); +"use strict"; +/** + * Copyright (c) 2013-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ - const artifactFiles = new Set(events.artifactFiles || []); - const files = new Set(); - // initialise events - for (var _iterator = queue, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { - var _ref2; - if (_isArray) { - if (_i >= _iterator.length) break; - _ref2 = _iterator[_i++]; - } else { - _i = _iterator.next(); - if (_i.done) break; - _ref2 = _i.value; - } +/** + * Use invariant() to assert state which your program assumes to be true. + * + * Provide sprintf-style format (only %s is supported) and arguments + * to provide information about what broke and what you were + * expecting. + * + * The invariant message will be stripped in production, but the invariant + * will remain to ensure logic does not differ in production. + */ - const item = _ref2; +var NODE_ENV = "none"; - const onDone = item.onDone; - item.onDone = function () { - events.onProgress(item.dest); - if (onDone) { - onDone(); - } - }; +var invariant = function(condition, format, a, b, c, d, e, f) { + if (NODE_ENV !== 'production') { + if (format === undefined) { + throw new Error('invariant requires an error message argument'); } - events.onStart(queue.length); - - // start building actions - const actions = { - file: [], - symlink: [], - link: [] - }; + } - // custom concurrency logic as we're always executing stacks of CONCURRENT_QUEUE_ITEMS queue items - // at a time due to the requirement to push items onto the queue - while (queue.length) { - const items = queue.splice(0, CONCURRENT_QUEUE_ITEMS); - yield Promise.all(items.map(build)); + if (!condition) { + var error; + if (format === undefined) { + error = new Error( + 'Minified exception occurred; use the non-minified dev environment ' + + 'for the full error message and additional helpful warnings.' + ); + } else { + var args = [a, b, c, d, e, f]; + var argIndex = 0; + error = new Error( + format.replace(/%s/g, function() { return args[argIndex++]; }) + ); + error.name = 'Invariant Violation'; } - // simulate the existence of some files to prevent considering them extraneous - for (var _iterator2 = artifactFiles, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) { - var _ref3; + error.framesToPop = 1; // we don't care about invariant's own frame + throw error; + } +}; - if (_isArray2) { - if (_i2 >= _iterator2.length) break; - _ref3 = _iterator2[_i2++]; - } else { - _i2 = _iterator2.next(); - if (_i2.done) break; - _ref3 = _i2.value; - } +module.exports = invariant; - const file = _ref3; - if (possibleExtraneous.has(file)) { - reporter.verbose(reporter.lang('verboseFilePhantomExtraneous', file)); - possibleExtraneous.delete(file); - } - } +/***/ }), +/* 8 */, +/* 9 */ +/***/ (function(module, exports) { - for (var _iterator3 = possibleExtraneous, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) { - var _ref4; +module.exports = __webpack_require__(282); - if (_isArray3) { - if (_i3 >= _iterator3.length) break; - _ref4 = _iterator3[_i3++]; - } else { - _i3 = _iterator3.next(); - if (_i3.done) break; - _ref4 = _i3.value; - } +/***/ }), +/* 10 */, +/* 11 */ +/***/ (function(module, exports) { - const loc = _ref4; +// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028 +var global = module.exports = typeof window != 'undefined' && window.Math == Math + ? window : typeof self != 'undefined' && self.Math == Math ? self + // eslint-disable-next-line no-new-func + : Function('return this')(); +if (typeof __g == 'number') __g = global; // eslint-disable-line no-undef - if (files.has(loc.toLowerCase())) { - possibleExtraneous.delete(loc); - } - } - return actions; - }); +/***/ }), +/* 12 */ +/***/ (function(module, exports, __webpack_require__) { - return function buildActionsForCopy(_x, _x2, _x3, _x4) { - return _ref.apply(this, arguments); - }; -})(); +"use strict"; -let buildActionsForHardlink = (() => { - var _ref9 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (queue, events, possibleExtraneous, reporter) { - // - let build = (() => { - var _ref13 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (data) { - const src = data.src, - dest = data.dest; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.sortAlpha = sortAlpha; +exports.entries = entries; +exports.removePrefix = removePrefix; +exports.removeSuffix = removeSuffix; +exports.addSuffix = addSuffix; +exports.hyphenate = hyphenate; +exports.camelCase = camelCase; +exports.compareSortedArrays = compareSortedArrays; +exports.sleep = sleep; +const _camelCase = __webpack_require__(176); - const onFresh = data.onFresh || noop; - const onDone = data.onDone || noop; - if (files.has(dest.toLowerCase())) { - // Fixes issue https://github.com/yarnpkg/yarn/issues/2734 - // When bulk hardlinking we have A -> B structure that we want to hardlink to A1 -> B1, - // package-linker passes that modules A1 and B1 need to be hardlinked, - // the recursive linking algorithm of A1 ends up scheduling files in B1 to be linked twice which will case - // an exception. - onDone(); - return; - } - files.add(dest.toLowerCase()); +function sortAlpha(a, b) { + // sort alphabetically in a deterministic way + const shortLen = Math.min(a.length, b.length); + for (let i = 0; i < shortLen; i++) { + const aChar = a.charCodeAt(i); + const bChar = b.charCodeAt(i); + if (aChar !== bChar) { + return aChar - bChar; + } + } + return a.length - b.length; +} - if (events.ignoreBasenames.indexOf((_path || _load_path()).default.basename(src)) >= 0) { - // ignored file - return; - } +function entries(obj) { + const entries = []; + if (obj) { + for (const key in obj) { + entries.push([key, obj[key]]); + } + } + return entries; +} - const srcStat = yield lstat(src); - let srcFiles; +function removePrefix(pattern, prefix) { + if (pattern.startsWith(prefix)) { + pattern = pattern.slice(prefix.length); + } - if (srcStat.isDirectory()) { - srcFiles = yield readdir(src); - } + return pattern; +} - const destExists = yield exists(dest); - if (destExists) { - const destStat = yield lstat(dest); +function removeSuffix(pattern, suffix) { + if (pattern.endsWith(suffix)) { + return pattern.slice(0, -suffix.length); + } - const bothSymlinks = srcStat.isSymbolicLink() && destStat.isSymbolicLink(); - const bothFolders = srcStat.isDirectory() && destStat.isDirectory(); - const bothFiles = srcStat.isFile() && destStat.isFile(); + return pattern; +} - if (srcStat.mode !== destStat.mode) { - try { - yield access(dest, srcStat.mode); - } catch (err) { - // EINVAL access errors sometimes happen which shouldn't because node shouldn't be giving - // us modes that aren't valid. investigate this, it's generally safe to proceed. - reporter.verbose(err); - } - } +function addSuffix(pattern, suffix) { + if (!pattern.endsWith(suffix)) { + return pattern + suffix; + } - if (bothFiles && artifactFiles.has(dest)) { - // this file gets changed during build, likely by a custom install script. Don't bother checking it. - onDone(); - reporter.verbose(reporter.lang('verboseFileSkipArtifact', src)); - return; - } + return pattern; +} - // correct hardlink - if (bothFiles && srcStat.ino !== null && srcStat.ino === destStat.ino) { - onDone(); - reporter.verbose(reporter.lang('verboseFileSkip', src, dest, srcStat.ino)); - return; - } +function hyphenate(str) { + return str.replace(/[A-Z]/g, match => { + return '-' + match.charAt(0).toLowerCase(); + }); +} - if (bothSymlinks) { - const srcReallink = yield readlink(src); - if (srcReallink === (yield readlink(dest))) { - // if both symlinks are the same then we can continue on - onDone(); - reporter.verbose(reporter.lang('verboseFileSkipSymlink', src, dest, srcReallink)); - return; - } - } +function camelCase(str) { + if (/[A-Z]/.test(str)) { + return null; + } else { + return _camelCase(str); + } +} - if (bothFolders) { - // mark files that aren't in this folder as possibly extraneous - const destFiles = yield readdir(dest); - invariant(srcFiles, 'src files not initialised'); +function compareSortedArrays(array1, array2) { + if (array1.length !== array2.length) { + return false; + } + for (let i = 0, len = array1.length; i < len; i++) { + if (array1[i] !== array2[i]) { + return false; + } + } + return true; +} - for (var _iterator10 = destFiles, _isArray10 = Array.isArray(_iterator10), _i10 = 0, _iterator10 = _isArray10 ? _iterator10 : _iterator10[Symbol.iterator]();;) { - var _ref14; +function sleep(ms) { + return new Promise(resolve => { + setTimeout(resolve, ms); + }); +} - if (_isArray10) { - if (_i10 >= _iterator10.length) break; - _ref14 = _iterator10[_i10++]; - } else { - _i10 = _iterator10.next(); - if (_i10.done) break; - _ref14 = _i10.value; - } +/***/ }), +/* 13 */ +/***/ (function(module, exports, __webpack_require__) { - const file = _ref14; +var store = __webpack_require__(107)('wks'); +var uid = __webpack_require__(111); +var Symbol = __webpack_require__(11).Symbol; +var USE_SYMBOL = typeof Symbol == 'function'; - if (srcFiles.indexOf(file) < 0) { - const loc = (_path || _load_path()).default.join(dest, file); - possibleExtraneous.add(loc); +var $exports = module.exports = function (name) { + return store[name] || (store[name] = + USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : uid)('Symbol.' + name)); +}; - if ((yield lstat(loc)).isDirectory()) { - for (var _iterator11 = yield readdir(loc), _isArray11 = Array.isArray(_iterator11), _i11 = 0, _iterator11 = _isArray11 ? _iterator11 : _iterator11[Symbol.iterator]();;) { - var _ref15; +$exports.store = store; - if (_isArray11) { - if (_i11 >= _iterator11.length) break; - _ref15 = _iterator11[_i11++]; - } else { - _i11 = _iterator11.next(); - if (_i11.done) break; - _ref15 = _i11.value; - } - const file = _ref15; +/***/ }), +/* 14 */ +/***/ (function(module, exports, __webpack_require__) { - possibleExtraneous.add((_path || _load_path()).default.join(loc, file)); - } - } - } - } - } - } +"use strict"; - if (srcStat.isSymbolicLink()) { - onFresh(); - const linkname = yield readlink(src); - actions.symlink.push({ - dest, - linkname - }); - onDone(); - } else if (srcStat.isDirectory()) { - reporter.verbose(reporter.lang('verboseFileFolder', dest)); - yield mkdirp(dest); - const destParts = dest.split((_path || _load_path()).default.sep); - while (destParts.length) { - files.add(destParts.join((_path || _load_path()).default.sep).toLowerCase()); - destParts.pop(); - } +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.stringify = exports.parse = undefined; - // push all files to queue - invariant(srcFiles, 'src files not initialised'); - let remaining = srcFiles.length; - if (!remaining) { - onDone(); - } - for (var _iterator12 = srcFiles, _isArray12 = Array.isArray(_iterator12), _i12 = 0, _iterator12 = _isArray12 ? _iterator12 : _iterator12[Symbol.iterator]();;) { - var _ref16; +var _asyncToGenerator2; - if (_isArray12) { - if (_i12 >= _iterator12.length) break; - _ref16 = _iterator12[_i12++]; - } else { - _i12 = _iterator12.next(); - if (_i12.done) break; - _ref16 = _i12.value; - } +function _load_asyncToGenerator() { + return _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(1)); +} - const file = _ref16; +var _parse; - queue.push({ - onFresh, - src: (_path || _load_path()).default.join(src, file), - dest: (_path || _load_path()).default.join(dest, file), - onDone: function (_onDone2) { - function onDone() { - return _onDone2.apply(this, arguments); - } +function _load_parse() { + return _parse = __webpack_require__(81); +} - onDone.toString = function () { - return _onDone2.toString(); - }; +Object.defineProperty(exports, 'parse', { + enumerable: true, + get: function get() { + return _interopRequireDefault(_parse || _load_parse()).default; + } +}); - return onDone; - }(function () { - if (--remaining === 0) { - onDone(); - } - }) - }); - } - } else if (srcStat.isFile()) { - onFresh(); - actions.link.push({ - src, - dest, - removeDest: destExists - }); - onDone(); - } else { - throw new Error(`unsure how to copy this: ${src}`); - } - }); +var _stringify; - return function build(_x10) { - return _ref13.apply(this, arguments); - }; - })(); +function _load_stringify() { + return _stringify = __webpack_require__(150); +} - const artifactFiles = new Set(events.artifactFiles || []); - const files = new Set(); +Object.defineProperty(exports, 'stringify', { + enumerable: true, + get: function get() { + return _interopRequireDefault(_stringify || _load_stringify()).default; + } +}); +exports.implodeEntry = implodeEntry; +exports.explodeEntry = explodeEntry; - // initialise events - for (var _iterator7 = queue, _isArray7 = Array.isArray(_iterator7), _i7 = 0, _iterator7 = _isArray7 ? _iterator7 : _iterator7[Symbol.iterator]();;) { - var _ref10; - - if (_isArray7) { - if (_i7 >= _iterator7.length) break; - _ref10 = _iterator7[_i7++]; - } else { - _i7 = _iterator7.next(); - if (_i7.done) break; - _ref10 = _i7.value; - } - - const item = _ref10; - - const onDone = item.onDone || noop; - item.onDone = function () { - events.onProgress(item.dest); - onDone(); - }; - } - events.onStart(queue.length); +var _misc; - // start building actions - const actions = { - file: [], - symlink: [], - link: [] - }; +function _load_misc() { + return _misc = __webpack_require__(12); +} - // custom concurrency logic as we're always executing stacks of CONCURRENT_QUEUE_ITEMS queue items - // at a time due to the requirement to push items onto the queue - while (queue.length) { - const items = queue.splice(0, CONCURRENT_QUEUE_ITEMS); - yield Promise.all(items.map(build)); - } +var _normalizePattern; - // simulate the existence of some files to prevent considering them extraneous - for (var _iterator8 = artifactFiles, _isArray8 = Array.isArray(_iterator8), _i8 = 0, _iterator8 = _isArray8 ? _iterator8 : _iterator8[Symbol.iterator]();;) { - var _ref11; +function _load_normalizePattern() { + return _normalizePattern = __webpack_require__(29); +} - if (_isArray8) { - if (_i8 >= _iterator8.length) break; - _ref11 = _iterator8[_i8++]; - } else { - _i8 = _iterator8.next(); - if (_i8.done) break; - _ref11 = _i8.value; - } +var _parse2; - const file = _ref11; +function _load_parse2() { + return _parse2 = _interopRequireDefault(__webpack_require__(81)); +} - if (possibleExtraneous.has(file)) { - reporter.verbose(reporter.lang('verboseFilePhantomExtraneous', file)); - possibleExtraneous.delete(file); - } - } +var _constants; - for (var _iterator9 = possibleExtraneous, _isArray9 = Array.isArray(_iterator9), _i9 = 0, _iterator9 = _isArray9 ? _iterator9 : _iterator9[Symbol.iterator]();;) { - var _ref12; +function _load_constants() { + return _constants = __webpack_require__(6); +} - if (_isArray9) { - if (_i9 >= _iterator9.length) break; - _ref12 = _iterator9[_i9++]; - } else { - _i9 = _iterator9.next(); - if (_i9.done) break; - _ref12 = _i9.value; - } +var _fs; - const loc = _ref12; +function _load_fs() { + return _fs = _interopRequireWildcard(__webpack_require__(5)); +} - if (files.has(loc.toLowerCase())) { - possibleExtraneous.delete(loc); - } - } +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } - return actions; - }); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - return function buildActionsForHardlink(_x6, _x7, _x8, _x9) { - return _ref9.apply(this, arguments); - }; -})(); +const invariant = __webpack_require__(7); -let copyBulk = exports.copyBulk = (() => { - var _ref17 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (queue, reporter, _events) { - const events = { - onStart: _events && _events.onStart || noop, - onProgress: _events && _events.onProgress || noop, - possibleExtraneous: _events ? _events.possibleExtraneous : new Set(), - ignoreBasenames: _events && _events.ignoreBasenames || [], - artifactFiles: _events && _events.artifactFiles || [] - }; +const path = __webpack_require__(0); +const ssri = __webpack_require__(55); - const actions = yield buildActionsForCopy(queue, events, events.possibleExtraneous, reporter); - events.onStart(actions.file.length + actions.symlink.length + actions.link.length); +function getName(pattern) { + return (0, (_normalizePattern || _load_normalizePattern()).normalizePattern)(pattern).name; +} - const fileActions = actions.file; +function blankObjectUndefined(obj) { + return obj && Object.keys(obj).length ? obj : undefined; +} - const currentlyWriting = new Map(); +function keyForRemote(remote) { + return remote.resolved || (remote.reference && remote.hash ? `${remote.reference}#${remote.hash}` : null); +} - yield (_promise || _load_promise()).queue(fileActions, (() => { - var _ref18 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (data) { - let writePromise; - while (writePromise = currentlyWriting.get(data.dest)) { - yield writePromise; - } +function serializeIntegrity(integrity) { + // We need this because `Integrity.toString()` does not use sorting to ensure a stable string output + // See https://git.io/vx2Hy + return integrity.toString().split(' ').sort().join(' '); +} - reporter.verbose(reporter.lang('verboseFileCopy', data.src, data.dest)); - const copier = (0, (_fsNormalized || _load_fsNormalized()).copyFile)(data, function () { - return currentlyWriting.delete(data.dest); - }); - currentlyWriting.set(data.dest, copier); - events.onProgress(data.dest); - return copier; - }); +function implodeEntry(pattern, obj) { + const inferredName = getName(pattern); + const integrity = obj.integrity ? serializeIntegrity(obj.integrity) : ''; + const imploded = { + name: inferredName === obj.name ? undefined : obj.name, + version: obj.version, + uid: obj.uid === obj.version ? undefined : obj.uid, + resolved: obj.resolved, + registry: obj.registry === 'npm' ? undefined : obj.registry, + dependencies: blankObjectUndefined(obj.dependencies), + optionalDependencies: blankObjectUndefined(obj.optionalDependencies), + permissions: blankObjectUndefined(obj.permissions), + prebuiltVariants: blankObjectUndefined(obj.prebuiltVariants) + }; + if (integrity) { + imploded.integrity = integrity; + } + return imploded; +} - return function (_x14) { - return _ref18.apply(this, arguments); - }; - })(), CONCURRENT_QUEUE_ITEMS); +function explodeEntry(pattern, obj) { + obj.optionalDependencies = obj.optionalDependencies || {}; + obj.dependencies = obj.dependencies || {}; + obj.uid = obj.uid || obj.version; + obj.permissions = obj.permissions || {}; + obj.registry = obj.registry || 'npm'; + obj.name = obj.name || getName(pattern); + const integrity = obj.integrity; + if (integrity && integrity.isIntegrity) { + obj.integrity = ssri.parse(integrity); + } + return obj; +} - // we need to copy symlinks last as they could reference files we were copying - const symlinkActions = actions.symlink; - yield (_promise || _load_promise()).queue(symlinkActions, function (data) { - const linkname = (_path || _load_path()).default.resolve((_path || _load_path()).default.dirname(data.dest), data.linkname); - reporter.verbose(reporter.lang('verboseFileSymlink', data.dest, linkname)); - return symlink(linkname, data.dest); - }); - }); +class Lockfile { + constructor({ cache, source, parseResultType } = {}) { + this.source = source || ''; + this.cache = cache; + this.parseResultType = parseResultType; + } - return function copyBulk(_x11, _x12, _x13) { - return _ref17.apply(this, arguments); - }; -})(); + // source string if the `cache` was parsed -let hardlinkBulk = exports.hardlinkBulk = (() => { - var _ref19 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (queue, reporter, _events) { - const events = { - onStart: _events && _events.onStart || noop, - onProgress: _events && _events.onProgress || noop, - possibleExtraneous: _events ? _events.possibleExtraneous : new Set(), - artifactFiles: _events && _events.artifactFiles || [], - ignoreBasenames: [] - }; - const actions = yield buildActionsForHardlink(queue, events, events.possibleExtraneous, reporter); - events.onStart(actions.file.length + actions.symlink.length + actions.link.length); + // if true, we're parsing an old yarn file and need to update integrity fields + hasEntriesExistWithoutIntegrity() { + if (!this.cache) { + return false; + } - const fileActions = actions.link; + for (const key in this.cache) { + // $FlowFixMe - `this.cache` is clearly defined at this point + if (!/^.*@(file:|http)/.test(key) && this.cache[key] && !this.cache[key].integrity) { + return true; + } + } - yield (_promise || _load_promise()).queue(fileActions, (() => { - var _ref20 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (data) { - reporter.verbose(reporter.lang('verboseFileLink', data.src, data.dest)); - if (data.removeDest) { - yield (0, (_fsNormalized || _load_fsNormalized()).unlink)(data.dest); - } - yield link(data.src, data.dest); - }); + return false; + } - return function (_x18) { - return _ref20.apply(this, arguments); - }; - })(), CONCURRENT_QUEUE_ITEMS); + static fromDirectory(dir, reporter) { + return (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* () { + // read the manifest in this directory + const lockfileLoc = path.join(dir, (_constants || _load_constants()).LOCKFILE_FILENAME); - // we need to copy symlinks last as they could reference files we were copying - const symlinkActions = actions.symlink; - yield (_promise || _load_promise()).queue(symlinkActions, function (data) { - const linkname = (_path || _load_path()).default.resolve((_path || _load_path()).default.dirname(data.dest), data.linkname); - reporter.verbose(reporter.lang('verboseFileSymlink', data.dest, linkname)); - return symlink(linkname, data.dest); - }); - }); + let lockfile; + let rawLockfile = ''; + let parseResult; - return function hardlinkBulk(_x15, _x16, _x17) { - return _ref19.apply(this, arguments); - }; -})(); + if (yield (_fs || _load_fs()).exists(lockfileLoc)) { + rawLockfile = yield (_fs || _load_fs()).readFile(lockfileLoc); + parseResult = (0, (_parse2 || _load_parse2()).default)(rawLockfile, lockfileLoc); -let readFileAny = exports.readFileAny = (() => { - var _ref21 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (files) { - for (var _iterator13 = files, _isArray13 = Array.isArray(_iterator13), _i13 = 0, _iterator13 = _isArray13 ? _iterator13 : _iterator13[Symbol.iterator]();;) { - var _ref22; + if (reporter) { + if (parseResult.type === 'merge') { + reporter.info(reporter.lang('lockfileMerged')); + } else if (parseResult.type === 'conflict') { + reporter.warn(reporter.lang('lockfileConflict')); + } + } - if (_isArray13) { - if (_i13 >= _iterator13.length) break; - _ref22 = _iterator13[_i13++]; - } else { - _i13 = _iterator13.next(); - if (_i13.done) break; - _ref22 = _i13.value; + lockfile = parseResult.object; + } else if (reporter) { + reporter.info(reporter.lang('noLockfileFound')); } - const file = _ref22; + return new Lockfile({ cache: lockfile, source: rawLockfile, parseResultType: parseResult && parseResult.type }); + })(); + } - if (yield exists(file)) { - return readFile(file); - } + getLocked(pattern) { + const cache = this.cache; + if (!cache) { + return undefined; } - return null; - }); - return function readFileAny(_x19) { - return _ref21.apply(this, arguments); - }; -})(); + const shrunk = pattern in cache && cache[pattern]; -let readJson = exports.readJson = (() => { - var _ref23 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (loc) { - return (yield readJsonAndFile(loc)).object; - }); + if (typeof shrunk === 'string') { + return this.getLocked(shrunk); + } else if (shrunk) { + explodeEntry(pattern, shrunk); + return shrunk; + } - return function readJson(_x20) { - return _ref23.apply(this, arguments); - }; -})(); + return undefined; + } -let readJsonAndFile = exports.readJsonAndFile = (() => { - var _ref24 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (loc) { - const file = yield readFile(loc); - try { - return { - object: (0, (_map || _load_map()).default)(JSON.parse(stripBOM(file))), - content: file - }; - } catch (err) { - err.message = `${loc}: ${err.message}`; - throw err; + removePattern(pattern) { + const cache = this.cache; + if (!cache) { + return; } - }); + delete cache[pattern]; + } - return function readJsonAndFile(_x21) { - return _ref24.apply(this, arguments); - }; -})(); + getLockfile(patterns) { + const lockfile = {}; + const seen = new Map(); -let find = exports.find = (() => { - var _ref25 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (filename, dir) { - const parts = dir.split((_path || _load_path()).default.sep); + // order by name so that lockfile manifest is assigned to the first dependency with this manifest + // the others that have the same remoteKey will just refer to the first + // ordering allows for consistency in lockfile when it is serialized + const sortedPatternsKeys = Object.keys(patterns).sort((_misc || _load_misc()).sortAlpha); - while (parts.length) { - const loc = parts.concat(filename).join((_path || _load_path()).default.sep); + for (var _iterator = sortedPatternsKeys, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { + var _ref; - if (yield exists(loc)) { - return loc; + if (_isArray) { + if (_i >= _iterator.length) break; + _ref = _iterator[_i++]; } else { - parts.pop(); + _i = _iterator.next(); + if (_i.done) break; + _ref = _i.value; } - } - return false; - }); + const pattern = _ref; - return function find(_x22, _x23) { - return _ref25.apply(this, arguments); - }; -})(); + const pkg = patterns[pattern]; + const remote = pkg._remote, + ref = pkg._reference; -let symlink = exports.symlink = (() => { - var _ref26 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (src, dest) { - try { - const stats = yield lstat(dest); - if (stats.isSymbolicLink()) { - const resolved = yield realpath(dest); - if (resolved === src) { - return; + invariant(ref, 'Package is missing a reference'); + invariant(remote, 'Package is missing a remote'); + + const remoteKey = keyForRemote(remote); + const seenPattern = remoteKey && seen.get(remoteKey); + if (seenPattern) { + // no point in duplicating it + lockfile[pattern] = seenPattern; + + // if we're relying on our name being inferred and two of the patterns have + // different inferred names then we need to set it + if (!seenPattern.name && getName(pattern) !== pkg.name) { + seenPattern.name = pkg.name; } + continue; } - } catch (err) { - if (err.code !== 'ENOENT') { - throw err; - } - } - // We use rimraf for unlink which never throws an ENOENT on missing target - yield (0, (_fsNormalized || _load_fsNormalized()).unlink)(dest); + const obj = implodeEntry(pattern, { + name: pkg.name, + version: pkg.version, + uid: pkg._uid, + resolved: remote.resolved, + integrity: remote.integrity, + registry: remote.registry, + dependencies: pkg.dependencies, + peerDependencies: pkg.peerDependencies, + optionalDependencies: pkg.optionalDependencies, + permissions: ref.permissions, + prebuiltVariants: pkg.prebuiltVariants + }); - if (process.platform === 'win32') { - // use directory junctions if possible on win32, this requires absolute paths - yield fsSymlink(src, dest, 'junction'); - } else { - // use relative paths otherwise which will be retained if the directory is moved - let relative; - try { - relative = (_path || _load_path()).default.relative((_fs || _load_fs()).default.realpathSync((_path || _load_path()).default.dirname(dest)), (_fs || _load_fs()).default.realpathSync(src)); - } catch (err) { - if (err.code !== 'ENOENT') { - throw err; - } - relative = (_path || _load_path()).default.relative((_path || _load_path()).default.dirname(dest), src); + lockfile[pattern] = obj; + + if (remoteKey) { + seen.set(remoteKey, obj); } - // When path.relative returns an empty string for the current directory, we should instead use - // '.', which is a valid fs.symlink target. - yield fsSymlink(relative || '.', dest); } - }); - return function symlink(_x24, _x25) { - return _ref26.apply(this, arguments); - }; -})(); + return lockfile; + } +} +exports.default = Lockfile; -let walk = exports.walk = (() => { - var _ref27 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (dir, relativeDir, ignoreBasenames = new Set()) { - let files = []; +/***/ }), +/* 15 */, +/* 16 */, +/* 17 */ +/***/ (function(module, exports) { - let filenames = yield readdir(dir); - if (ignoreBasenames.size) { - filenames = filenames.filter(function (name) { - return !ignoreBasenames.has(name); - }); - } +module.exports = __webpack_require__(137); - for (var _iterator14 = filenames, _isArray14 = Array.isArray(_iterator14), _i14 = 0, _iterator14 = _isArray14 ? _iterator14 : _iterator14[Symbol.iterator]();;) { - var _ref28; +/***/ }), +/* 18 */, +/* 19 */, +/* 20 */ +/***/ (function(module, exports, __webpack_require__) { - if (_isArray14) { - if (_i14 >= _iterator14.length) break; - _ref28 = _iterator14[_i14++]; +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = nullify; +function nullify(obj = {}) { + if (Array.isArray(obj)) { + for (var _iterator = obj, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { + var _ref; + + if (_isArray) { + if (_i >= _iterator.length) break; + _ref = _iterator[_i++]; } else { - _i14 = _iterator14.next(); - if (_i14.done) break; - _ref28 = _i14.value; + _i = _iterator.next(); + if (_i.done) break; + _ref = _i.value; } - const name = _ref28; - - const relative = relativeDir ? (_path || _load_path()).default.join(relativeDir, name) : name; - const loc = (_path || _load_path()).default.join(dir, name); - const stat = yield lstat(loc); + const item = _ref; - files.push({ - relative, - basename: name, - absolute: loc, - mtime: +stat.mtime - }); + nullify(item); + } + } else if (obj !== null && typeof obj === 'object' || typeof obj === 'function') { + Object.setPrototypeOf(obj, null); - if (stat.isDirectory()) { - files = files.concat((yield walk(loc, relative, ignoreBasenames))); + // for..in can only be applied to 'object', not 'function' + if (typeof obj === 'object') { + for (const key in obj) { + nullify(obj[key]); } } + } - return files; - }); - - return function walk(_x26, _x27) { - return _ref27.apply(this, arguments); - }; -})(); + return obj; +} -let getFileSizeOnDisk = exports.getFileSizeOnDisk = (() => { - var _ref29 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (loc) { - const stat = yield lstat(loc); - const size = stat.size, - blockSize = stat.blksize; - - - return Math.ceil(size / blockSize) * blockSize; - }); - - return function getFileSizeOnDisk(_x28) { - return _ref29.apply(this, arguments); - }; -})(); +/***/ }), +/* 21 */, +/* 22 */ +/***/ (function(module, exports) { -let getEolFromFile = (() => { - var _ref30 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (path) { - if (!(yield exists(path))) { - return undefined; - } +module.exports = __webpack_require__(139); - const buffer = yield readFileBuffer(path); +/***/ }), +/* 23 */ +/***/ (function(module, exports) { - for (let i = 0; i < buffer.length; ++i) { - if (buffer[i] === cr) { - return '\r\n'; - } - if (buffer[i] === lf) { - return '\n'; - } - } - return undefined; - }); +var core = module.exports = { version: '2.5.7' }; +if (typeof __e == 'number') __e = core; // eslint-disable-line no-undef - return function getEolFromFile(_x29) { - return _ref30.apply(this, arguments); - }; -})(); -let writeFilePreservingEol = exports.writeFilePreservingEol = (() => { - var _ref31 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (path, data) { - const eol = (yield getEolFromFile(path)) || (_os || _load_os()).default.EOL; - if (eol !== '\n') { - data = data.replace(/\n/g, eol); - } - yield writeFile(path, data); - }); +/***/ }), +/* 24 */, +/* 25 */, +/* 26 */, +/* 27 */ +/***/ (function(module, exports, __webpack_require__) { - return function writeFilePreservingEol(_x30, _x31) { - return _ref31.apply(this, arguments); - }; -})(); +var isObject = __webpack_require__(34); +module.exports = function (it) { + if (!isObject(it)) throw TypeError(it + ' is not an object!'); + return it; +}; -let hardlinksWork = exports.hardlinksWork = (() => { - var _ref32 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (dir) { - const filename = 'test-file' + Math.random(); - const file = (_path || _load_path()).default.join(dir, filename); - const fileLink = (_path || _load_path()).default.join(dir, filename + '-link'); - try { - yield writeFile(file, 'test'); - yield link(file, fileLink); - } catch (err) { - return false; - } finally { - yield (0, (_fsNormalized || _load_fsNormalized()).unlink)(file); - yield (0, (_fsNormalized || _load_fsNormalized()).unlink)(fileLink); - } - return true; - }); - return function hardlinksWork(_x32) { - return _ref32.apply(this, arguments); - }; -})(); +/***/ }), +/* 28 */, +/* 29 */ +/***/ (function(module, exports, __webpack_require__) { -// not a strict polyfill for Node's fs.mkdtemp +"use strict"; -let makeTempDir = exports.makeTempDir = (() => { - var _ref33 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (prefix) { - const dir = (_path || _load_path()).default.join((_os || _load_os()).default.tmpdir(), `yarn-${prefix || ''}-${Date.now()}-${Math.random()}`); - yield (0, (_fsNormalized || _load_fsNormalized()).unlink)(dir); - yield mkdirp(dir); - return dir; - }); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.normalizePattern = normalizePattern; - return function makeTempDir(_x33) { - return _ref33.apply(this, arguments); - }; -})(); +/** + * Explode and normalize a pattern into its name and range. + */ -let readFirstAvailableStream = exports.readFirstAvailableStream = (() => { - var _ref34 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (paths) { - for (var _iterator15 = paths, _isArray15 = Array.isArray(_iterator15), _i15 = 0, _iterator15 = _isArray15 ? _iterator15 : _iterator15[Symbol.iterator]();;) { - var _ref35; +function normalizePattern(pattern) { + let hasVersion = false; + let range = 'latest'; + let name = pattern; - if (_isArray15) { - if (_i15 >= _iterator15.length) break; - _ref35 = _iterator15[_i15++]; - } else { - _i15 = _iterator15.next(); - if (_i15.done) break; - _ref35 = _i15.value; - } + // if we're a scope then remove the @ and add it back later + let isScoped = false; + if (name[0] === '@') { + isScoped = true; + name = name.slice(1); + } - const path = _ref35; + // take first part as the name + const parts = name.split('@'); + if (parts.length > 1) { + name = parts.shift(); + range = parts.join('@'); - try { - const fd = yield open(path, 'r'); - return (_fs || _load_fs()).default.createReadStream(path, { fd }); - } catch (err) { - // Try the next one - } + if (range) { + hasVersion = true; + } else { + range = '*'; } - return null; - }); - - return function readFirstAvailableStream(_x34) { - return _ref34.apply(this, arguments); - }; -})(); - -let getFirstSuitableFolder = exports.getFirstSuitableFolder = (() => { - var _ref36 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (paths, mode = constants.W_OK | constants.X_OK) { - const result = { - skipped: [], - folder: null - }; - - for (var _iterator16 = paths, _isArray16 = Array.isArray(_iterator16), _i16 = 0, _iterator16 = _isArray16 ? _iterator16 : _iterator16[Symbol.iterator]();;) { - var _ref37; - - if (_isArray16) { - if (_i16 >= _iterator16.length) break; - _ref37 = _iterator16[_i16++]; - } else { - _i16 = _iterator16.next(); - if (_i16.done) break; - _ref37 = _i16.value; - } + } - const folder = _ref37; + // add back @ scope suffix + if (isScoped) { + name = `@${name}`; + } - try { - yield mkdirp(folder); - yield access(folder, mode); + return { name, range, hasVersion }; +} - result.folder = folder; +/***/ }), +/* 30 */, +/* 31 */ +/***/ (function(module, exports, __webpack_require__) { - return result; - } catch (error) { - result.skipped.push({ - error, - folder - }); - } - } - return result; - }); +var dP = __webpack_require__(50); +var createDesc = __webpack_require__(106); +module.exports = __webpack_require__(33) ? function (object, key, value) { + return dP.f(object, key, createDesc(1, value)); +} : function (object, key, value) { + object[key] = value; + return object; +}; - return function getFirstSuitableFolder(_x35) { - return _ref36.apply(this, arguments); - }; -})(); -exports.copy = copy; -exports.readFile = readFile; -exports.readFileRaw = readFileRaw; -exports.normalizeOS = normalizeOS; +/***/ }), +/* 32 */ +/***/ (function(module, exports, __webpack_require__) { -var _fs; +/* eslint-disable node/no-deprecated-api */ +var buffer = __webpack_require__(63) +var Buffer = buffer.Buffer -function _load_fs() { - return _fs = _interopRequireDefault(__webpack_require__(3)); +// alternative to using Object.keys for old browsers +function copyProps (src, dst) { + for (var key in src) { + dst[key] = src[key] + } } - -var _glob; - -function _load_glob() { - return _glob = _interopRequireDefault(__webpack_require__(75)); +if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) { + module.exports = buffer +} else { + // Copy properties from require('buffer') + copyProps(buffer, exports) + exports.Buffer = SafeBuffer } -var _os; - -function _load_os() { - return _os = _interopRequireDefault(__webpack_require__(36)); +function SafeBuffer (arg, encodingOrOffset, length) { + return Buffer(arg, encodingOrOffset, length) } -var _path; +// Copy static methods from Buffer +copyProps(Buffer, SafeBuffer) -function _load_path() { - return _path = _interopRequireDefault(__webpack_require__(0)); +SafeBuffer.from = function (arg, encodingOrOffset, length) { + if (typeof arg === 'number') { + throw new TypeError('Argument must not be a number') + } + return Buffer(arg, encodingOrOffset, length) } -var _blockingQueue; - -function _load_blockingQueue() { - return _blockingQueue = _interopRequireDefault(__webpack_require__(84)); +SafeBuffer.alloc = function (size, fill, encoding) { + if (typeof size !== 'number') { + throw new TypeError('Argument must be a number') + } + var buf = Buffer(size) + if (fill !== undefined) { + if (typeof encoding === 'string') { + buf.fill(fill, encoding) + } else { + buf.fill(fill) + } + } else { + buf.fill(0) + } + return buf } -var _promise; - -function _load_promise() { - return _promise = _interopRequireWildcard(__webpack_require__(40)); +SafeBuffer.allocUnsafe = function (size) { + if (typeof size !== 'number') { + throw new TypeError('Argument must be a number') + } + return Buffer(size) } -var _promise2; - -function _load_promise2() { - return _promise2 = __webpack_require__(40); +SafeBuffer.allocUnsafeSlow = function (size) { + if (typeof size !== 'number') { + throw new TypeError('Argument must be a number') + } + return buffer.SlowBuffer(size) } -var _map; - -function _load_map() { - return _map = _interopRequireDefault(__webpack_require__(20)); -} -var _fsNormalized; +/***/ }), +/* 33 */ +/***/ (function(module, exports, __webpack_require__) { -function _load_fsNormalized() { - return _fsNormalized = __webpack_require__(164); -} +// Thank's IE8 for his funny defineProperty +module.exports = !__webpack_require__(85)(function () { + return Object.defineProperty({}, 'a', { get: function () { return 7; } }).a != 7; +}); -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +/***/ }), +/* 34 */ +/***/ (function(module, exports) { -const constants = exports.constants = typeof (_fs || _load_fs()).default.constants !== 'undefined' ? (_fs || _load_fs()).default.constants : { - R_OK: (_fs || _load_fs()).default.R_OK, - W_OK: (_fs || _load_fs()).default.W_OK, - X_OK: (_fs || _load_fs()).default.X_OK +module.exports = function (it) { + return typeof it === 'object' ? it !== null : typeof it === 'function'; }; -const lockQueue = exports.lockQueue = new (_blockingQueue || _load_blockingQueue()).default('fs lock'); - -const readFileBuffer = exports.readFileBuffer = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.readFile); -const open = exports.open = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.open); -const writeFile = exports.writeFile = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.writeFile); -const readlink = exports.readlink = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.readlink); -const realpath = exports.realpath = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.realpath); -const readdir = exports.readdir = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.readdir); -const rename = exports.rename = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.rename); -const access = exports.access = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.access); -const stat = exports.stat = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.stat); -const mkdirp = exports.mkdirp = (0, (_promise2 || _load_promise2()).promisify)(__webpack_require__(116)); -const exists = exports.exists = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.exists, true); -const lstat = exports.lstat = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.lstat); -const chmod = exports.chmod = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.chmod); -const link = exports.link = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.link); -const glob = exports.glob = (0, (_promise2 || _load_promise2()).promisify)((_glob || _load_glob()).default); -exports.unlink = (_fsNormalized || _load_fsNormalized()).unlink; - -// fs.copyFile uses the native file copying instructions on the system, performing much better -// than any JS-based solution and consumes fewer resources. Repeated testing to fine tune the -// concurrency level revealed 128 as the sweet spot on a quad-core, 16 CPU Intel system with SSD. - -const CONCURRENT_QUEUE_ITEMS = (_fs || _load_fs()).default.copyFile ? 128 : 4; - -const fsSymlink = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.symlink); -const invariant = __webpack_require__(7); -const stripBOM = __webpack_require__(122); - -const noop = () => {}; - -function copy(src, dest, reporter) { - return copyBulk([{ src, dest }], reporter); -} -function _readFile(loc, encoding) { - return new Promise((resolve, reject) => { - (_fs || _load_fs()).default.readFile(loc, encoding, function (err, content) { - if (err) { - reject(err); - } else { - resolve(content); - } - }); - }); -} +/***/ }), +/* 35 */ +/***/ (function(module, exports) { -function readFile(loc) { - return _readFile(loc, 'utf8').then(normalizeOS); -} +module.exports = {}; -function readFileRaw(loc) { - return _readFile(loc, 'binary'); -} -function normalizeOS(body) { - return body.replace(/\r\n/g, '\n'); -} +/***/ }), +/* 36 */ +/***/ (function(module, exports) { -const cr = '\r'.charCodeAt(0); -const lf = '\n'.charCodeAt(0); +module.exports = __webpack_require__(120); /***/ }), -/* 6 */ +/* 37 */, +/* 38 */, +/* 39 */, +/* 40 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -32046,9807 +31397,9900 @@ const lf = '\n'.charCodeAt(0); Object.defineProperty(exports, "__esModule", { value: true }); -exports.getPathKey = getPathKey; -const os = __webpack_require__(36); -const path = __webpack_require__(0); -const userHome = __webpack_require__(45).default; - -var _require = __webpack_require__(171); - -const getCacheDir = _require.getCacheDir, - getConfigDir = _require.getConfigDir, - getDataDir = _require.getDataDir; - -const isWebpackBundle = __webpack_require__(227); - -const DEPENDENCY_TYPES = exports.DEPENDENCY_TYPES = ['devDependencies', 'dependencies', 'optionalDependencies', 'peerDependencies']; -const RESOLUTIONS = exports.RESOLUTIONS = 'resolutions'; -const MANIFEST_FIELDS = exports.MANIFEST_FIELDS = [RESOLUTIONS, ...DEPENDENCY_TYPES]; - -const SUPPORTED_NODE_VERSIONS = exports.SUPPORTED_NODE_VERSIONS = '^4.8.0 || ^5.7.0 || ^6.2.2 || >=8.0.0'; - -const YARN_REGISTRY = exports.YARN_REGISTRY = 'https://registry.yarnpkg.com'; +exports.wait = wait; +exports.promisify = promisify; +exports.queue = queue; +function wait(delay) { + return new Promise(resolve => { + setTimeout(resolve, delay); + }); +} -const YARN_DOCS = exports.YARN_DOCS = 'https://yarnpkg.com/en/docs/cli/'; -const YARN_INSTALLER_SH = exports.YARN_INSTALLER_SH = 'https://yarnpkg.com/install.sh'; -const YARN_INSTALLER_MSI = exports.YARN_INSTALLER_MSI = 'https://yarnpkg.com/latest.msi'; +function promisify(fn, firstData) { + return function (...args) { + return new Promise(function (resolve, reject) { + args.push(function (err, ...result) { + let res = result; -const SELF_UPDATE_VERSION_URL = exports.SELF_UPDATE_VERSION_URL = 'https://yarnpkg.com/latest-version'; + if (result.length <= 1) { + res = result[0]; + } -// cache version, bump whenever we make backwards incompatible changes -const CACHE_VERSION = exports.CACHE_VERSION = 2; + if (firstData) { + res = err; + err = null; + } -// lockfile version, bump whenever we make backwards incompatible changes -const LOCKFILE_VERSION = exports.LOCKFILE_VERSION = 1; + if (err) { + reject(err); + } else { + resolve(res); + } + }); -// max amount of network requests to perform concurrently -const NETWORK_CONCURRENCY = exports.NETWORK_CONCURRENCY = 8; + fn.apply(null, args); + }); + }; +} -// HTTP timeout used when downloading packages -const NETWORK_TIMEOUT = exports.NETWORK_TIMEOUT = 30 * 1000; // in milliseconds +function queue(arr, promiseProducer, concurrency = Infinity) { + concurrency = Math.min(concurrency, arr.length); -// max amount of child processes to execute concurrently -const CHILD_CONCURRENCY = exports.CHILD_CONCURRENCY = 5; + // clone + arr = arr.slice(); -const REQUIRED_PACKAGE_KEYS = exports.REQUIRED_PACKAGE_KEYS = ['name', 'version', '_uid']; + const results = []; + let total = arr.length; + if (!total) { + return Promise.resolve(results); + } -function getPreferredCacheDirectories() { - const preferredCacheDirectories = [getCacheDir()]; + return new Promise((resolve, reject) => { + for (let i = 0; i < concurrency; i++) { + next(); + } - if (process.getuid) { - // $FlowFixMe: process.getuid exists, dammit - preferredCacheDirectories.push(path.join(os.tmpdir(), `.yarn-cache-${process.getuid()}`)); - } + function next() { + const item = arr.shift(); + const promise = promiseProducer(item); - preferredCacheDirectories.push(path.join(os.tmpdir(), `.yarn-cache`)); + promise.then(function (result) { + results.push(result); - return preferredCacheDirectories; + total--; + if (total === 0) { + resolve(results); + } else { + if (arr.length) { + next(); + } + } + }, reject); + } + }); } -const PREFERRED_MODULE_CACHE_DIRECTORIES = exports.PREFERRED_MODULE_CACHE_DIRECTORIES = getPreferredCacheDirectories(); -const CONFIG_DIRECTORY = exports.CONFIG_DIRECTORY = getConfigDir(); -const DATA_DIRECTORY = exports.DATA_DIRECTORY = getDataDir(); -const LINK_REGISTRY_DIRECTORY = exports.LINK_REGISTRY_DIRECTORY = path.join(DATA_DIRECTORY, 'link'); -const GLOBAL_MODULE_DIRECTORY = exports.GLOBAL_MODULE_DIRECTORY = path.join(DATA_DIRECTORY, 'global'); +/***/ }), +/* 41 */ +/***/ (function(module, exports, __webpack_require__) { -const NODE_BIN_PATH = exports.NODE_BIN_PATH = process.execPath; -const YARN_BIN_PATH = exports.YARN_BIN_PATH = getYarnBinPath(); +var global = __webpack_require__(11); +var core = __webpack_require__(23); +var ctx = __webpack_require__(48); +var hide = __webpack_require__(31); +var has = __webpack_require__(49); +var PROTOTYPE = 'prototype'; -// Webpack needs to be configured with node.__dirname/__filename = false -function getYarnBinPath() { - if (isWebpackBundle) { - return __filename; - } else { - return path.join(__dirname, '..', 'bin', 'yarn.js'); +var $export = function (type, name, source) { + var IS_FORCED = type & $export.F; + var IS_GLOBAL = type & $export.G; + var IS_STATIC = type & $export.S; + var IS_PROTO = type & $export.P; + var IS_BIND = type & $export.B; + var IS_WRAP = type & $export.W; + var exports = IS_GLOBAL ? core : core[name] || (core[name] = {}); + var expProto = exports[PROTOTYPE]; + var target = IS_GLOBAL ? global : IS_STATIC ? global[name] : (global[name] || {})[PROTOTYPE]; + var key, own, out; + if (IS_GLOBAL) source = name; + for (key in source) { + // contains in native + own = !IS_FORCED && target && target[key] !== undefined; + if (own && has(exports, key)) continue; + // export native or passed + out = own ? target[key] : source[key]; + // prevent global pollution for namespaces + exports[key] = IS_GLOBAL && typeof target[key] != 'function' ? source[key] + // bind timers to global for call from export context + : IS_BIND && own ? ctx(out, global) + // wrap global constructors for prevent change them in library + : IS_WRAP && target[key] == out ? (function (C) { + var F = function (a, b, c) { + if (this instanceof C) { + switch (arguments.length) { + case 0: return new C(); + case 1: return new C(a); + case 2: return new C(a, b); + } return new C(a, b, c); + } return C.apply(this, arguments); + }; + F[PROTOTYPE] = C[PROTOTYPE]; + return F; + // make static versions for prototype methods + })(out) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out; + // export proto methods to core.%CONSTRUCTOR%.methods.%NAME% + if (IS_PROTO) { + (exports.virtual || (exports.virtual = {}))[key] = out; + // export proto methods to core.%CONSTRUCTOR%.prototype.%NAME% + if (type & $export.R && expProto && !expProto[key]) hide(expProto, key, out); + } } -} - -const NODE_MODULES_FOLDER = exports.NODE_MODULES_FOLDER = 'node_modules'; -const NODE_PACKAGE_JSON = exports.NODE_PACKAGE_JSON = 'package.json'; - -const POSIX_GLOBAL_PREFIX = exports.POSIX_GLOBAL_PREFIX = `${process.env.DESTDIR || ''}/usr/local`; -const FALLBACK_GLOBAL_PREFIX = exports.FALLBACK_GLOBAL_PREFIX = path.join(userHome, '.yarn'); - -const META_FOLDER = exports.META_FOLDER = '.yarn-meta'; -const INTEGRITY_FILENAME = exports.INTEGRITY_FILENAME = '.yarn-integrity'; -const LOCKFILE_FILENAME = exports.LOCKFILE_FILENAME = 'yarn.lock'; -const METADATA_FILENAME = exports.METADATA_FILENAME = '.yarn-metadata.json'; -const TARBALL_FILENAME = exports.TARBALL_FILENAME = '.yarn-tarball.tgz'; -const CLEAN_FILENAME = exports.CLEAN_FILENAME = '.yarnclean'; - -const NPM_LOCK_FILENAME = exports.NPM_LOCK_FILENAME = 'package-lock.json'; -const NPM_SHRINKWRAP_FILENAME = exports.NPM_SHRINKWRAP_FILENAME = 'npm-shrinkwrap.json'; - -const DEFAULT_INDENT = exports.DEFAULT_INDENT = ' '; -const SINGLE_INSTANCE_PORT = exports.SINGLE_INSTANCE_PORT = 31997; -const SINGLE_INSTANCE_FILENAME = exports.SINGLE_INSTANCE_FILENAME = '.yarn-single-instance'; - -const ENV_PATH_KEY = exports.ENV_PATH_KEY = getPathKey(process.platform, process.env); - -function getPathKey(platform, env) { - let pathKey = 'PATH'; +}; +// type bitmap +$export.F = 1; // forced +$export.G = 2; // global +$export.S = 4; // static +$export.P = 8; // proto +$export.B = 16; // bind +$export.W = 32; // wrap +$export.U = 64; // safe +$export.R = 128; // real proto method for `library` +module.exports = $export; - // windows calls its path "Path" usually, but this is not guaranteed. - if (platform === 'win32') { - pathKey = 'Path'; - for (const key in env) { - if (key.toLowerCase() === 'path') { - pathKey = key; - } - } - } +/***/ }), +/* 42 */ +/***/ (function(module, exports, __webpack_require__) { - return pathKey; +try { + var util = __webpack_require__(2); + if (typeof util.inherits !== 'function') throw ''; + module.exports = util.inherits; +} catch (e) { + module.exports = __webpack_require__(224); } -const VERSION_COLOR_SCHEME = exports.VERSION_COLOR_SCHEME = { - major: 'red', - premajor: 'red', - minor: 'yellow', - preminor: 'yellow', - patch: 'green', - prepatch: 'green', - prerelease: 'red', - unchanged: 'white', - unknown: 'red' -}; /***/ }), -/* 7 */ +/* 43 */, +/* 44 */, +/* 45 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -/** - * Copyright (c) 2013-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.home = undefined; -/** - * Use invariant() to assert state which your program assumes to be true. - * - * Provide sprintf-style format (only %s is supported) and arguments - * to provide information about what broke and what you were - * expecting. - * - * The invariant message will be stripped in production, but the invariant - * will remain to ensure logic does not differ in production. - */ +var _rootUser; -var NODE_ENV = "none"; +function _load_rootUser() { + return _rootUser = _interopRequireDefault(__webpack_require__(169)); +} -var invariant = function(condition, format, a, b, c, d, e, f) { - if (NODE_ENV !== 'production') { - if (format === undefined) { - throw new Error('invariant requires an error message argument'); - } - } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - if (!condition) { - var error; - if (format === undefined) { - error = new Error( - 'Minified exception occurred; use the non-minified dev environment ' + - 'for the full error message and additional helpful warnings.' - ); - } else { - var args = [a, b, c, d, e, f]; - var argIndex = 0; - error = new Error( - format.replace(/%s/g, function() { return args[argIndex++]; }) - ); - error.name = 'Invariant Violation'; - } +const path = __webpack_require__(0); - error.framesToPop = 1; // we don't care about invariant's own frame - throw error; - } -}; +const home = exports.home = __webpack_require__(36).homedir(); -module.exports = invariant; +const userHomeDir = (_rootUser || _load_rootUser()).default ? path.resolve('/usr/local/share') : home; +exports.default = userHomeDir; /***/ }), -/* 8 */, -/* 9 */ +/* 46 */ /***/ (function(module, exports) { -module.exports = __webpack_require__(290); +module.exports = function (it) { + if (typeof it != 'function') throw TypeError(it + ' is not a function!'); + return it; +}; + /***/ }), -/* 10 */, -/* 11 */ +/* 47 */ /***/ (function(module, exports) { -// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028 -var global = module.exports = typeof window != 'undefined' && window.Math == Math - ? window : typeof self != 'undefined' && self.Math == Math ? self - // eslint-disable-next-line no-new-func - : Function('return this')(); -if (typeof __g == 'number') __g = global; // eslint-disable-line no-undef +var toString = {}.toString; + +module.exports = function (it) { + return toString.call(it).slice(8, -1); +}; /***/ }), -/* 12 */ +/* 48 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.sortAlpha = sortAlpha; -exports.entries = entries; -exports.removePrefix = removePrefix; -exports.removeSuffix = removeSuffix; -exports.addSuffix = addSuffix; -exports.hyphenate = hyphenate; -exports.camelCase = camelCase; -exports.compareSortedArrays = compareSortedArrays; -exports.sleep = sleep; -const _camelCase = __webpack_require__(176); - -function sortAlpha(a, b) { - // sort alphabetically in a deterministic way - const shortLen = Math.min(a.length, b.length); - for (let i = 0; i < shortLen; i++) { - const aChar = a.charCodeAt(i); - const bChar = b.charCodeAt(i); - if (aChar !== bChar) { - return aChar - bChar; - } - } - return a.length - b.length; -} - -function entries(obj) { - const entries = []; - if (obj) { - for (const key in obj) { - entries.push([key, obj[key]]); - } - } - return entries; -} - -function removePrefix(pattern, prefix) { - if (pattern.startsWith(prefix)) { - pattern = pattern.slice(prefix.length); - } - - return pattern; -} - -function removeSuffix(pattern, suffix) { - if (pattern.endsWith(suffix)) { - return pattern.slice(0, -suffix.length); - } - - return pattern; -} - -function addSuffix(pattern, suffix) { - if (!pattern.endsWith(suffix)) { - return pattern + suffix; +// optional / simple context binding +var aFunction = __webpack_require__(46); +module.exports = function (fn, that, length) { + aFunction(fn); + if (that === undefined) return fn; + switch (length) { + case 1: return function (a) { + return fn.call(that, a); + }; + case 2: return function (a, b) { + return fn.call(that, a, b); + }; + case 3: return function (a, b, c) { + return fn.call(that, a, b, c); + }; } + return function (/* ...args */) { + return fn.apply(that, arguments); + }; +}; - return pattern; -} - -function hyphenate(str) { - return str.replace(/[A-Z]/g, match => { - return '-' + match.charAt(0).toLowerCase(); - }); -} -function camelCase(str) { - if (/[A-Z]/.test(str)) { - return null; - } else { - return _camelCase(str); - } -} +/***/ }), +/* 49 */ +/***/ (function(module, exports) { -function compareSortedArrays(array1, array2) { - if (array1.length !== array2.length) { - return false; - } - for (let i = 0, len = array1.length; i < len; i++) { - if (array1[i] !== array2[i]) { - return false; - } - } - return true; -} +var hasOwnProperty = {}.hasOwnProperty; +module.exports = function (it, key) { + return hasOwnProperty.call(it, key); +}; -function sleep(ms) { - return new Promise(resolve => { - setTimeout(resolve, ms); - }); -} /***/ }), -/* 13 */ +/* 50 */ /***/ (function(module, exports, __webpack_require__) { -var store = __webpack_require__(107)('wks'); -var uid = __webpack_require__(111); -var Symbol = __webpack_require__(11).Symbol; -var USE_SYMBOL = typeof Symbol == 'function'; +var anObject = __webpack_require__(27); +var IE8_DOM_DEFINE = __webpack_require__(184); +var toPrimitive = __webpack_require__(201); +var dP = Object.defineProperty; -var $exports = module.exports = function (name) { - return store[name] || (store[name] = - USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : uid)('Symbol.' + name)); +exports.f = __webpack_require__(33) ? Object.defineProperty : function defineProperty(O, P, Attributes) { + anObject(O); + P = toPrimitive(P, true); + anObject(Attributes); + if (IE8_DOM_DEFINE) try { + return dP(O, P, Attributes); + } catch (e) { /* empty */ } + if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported!'); + if ('value' in Attributes) O[P] = Attributes.value; + return O; }; -$exports.store = store; +/***/ }), +/* 51 */, +/* 52 */, +/* 53 */, +/* 54 */ +/***/ (function(module, exports) { + +module.exports = __webpack_require__(155); /***/ }), -/* 14 */ +/* 55 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.stringify = exports.parse = undefined; +const Buffer = __webpack_require__(32).Buffer -var _asyncToGenerator2; +const crypto = __webpack_require__(9) +const Transform = __webpack_require__(17).Transform -function _load_asyncToGenerator() { - return _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(1)); -} +const SPEC_ALGORITHMS = ['sha256', 'sha384', 'sha512'] -var _parse; +const BASE64_REGEX = /^[a-z0-9+/]+(?:=?=?)$/i +const SRI_REGEX = /^([^-]+)-([^?]+)([?\S*]*)$/ +const STRICT_SRI_REGEX = /^([^-]+)-([A-Za-z0-9+/=]{44,88})(\?[\x21-\x7E]*)*$/ +const VCHAR_REGEX = /^[\x21-\x7E]+$/ -function _load_parse() { - return _parse = __webpack_require__(81); -} +class Hash { + get isHash () { return true } + constructor (hash, opts) { + const strict = !!(opts && opts.strict) + this.source = hash.trim() + // 3.1. Integrity metadata (called "Hash" by ssri) + // https://w3c.github.io/webappsec-subresource-integrity/#integrity-metadata-description + const match = this.source.match( + strict + ? STRICT_SRI_REGEX + : SRI_REGEX + ) + if (!match) { return } + if (strict && !SPEC_ALGORITHMS.some(a => a === match[1])) { return } + this.algorithm = match[1] + this.digest = match[2] -Object.defineProperty(exports, 'parse', { - enumerable: true, - get: function get() { - return _interopRequireDefault(_parse || _load_parse()).default; + const rawOpts = match[3] + this.options = rawOpts ? rawOpts.slice(1).split('?') : [] } -}); - -var _stringify; - -function _load_stringify() { - return _stringify = __webpack_require__(150); -} - -Object.defineProperty(exports, 'stringify', { - enumerable: true, - get: function get() { - return _interopRequireDefault(_stringify || _load_stringify()).default; + hexDigest () { + return this.digest && Buffer.from(this.digest, 'base64').toString('hex') + } + toJSON () { + return this.toString() + } + toString (opts) { + if (opts && opts.strict) { + // Strict mode enforces the standard as close to the foot of the + // letter as it can. + if (!( + // The spec has very restricted productions for algorithms. + // https://www.w3.org/TR/CSP2/#source-list-syntax + SPEC_ALGORITHMS.some(x => x === this.algorithm) && + // Usually, if someone insists on using a "different" base64, we + // leave it as-is, since there's multiple standards, and the + // specified is not a URL-safe variant. + // https://www.w3.org/TR/CSP2/#base64_value + this.digest.match(BASE64_REGEX) && + // Option syntax is strictly visual chars. + // https://w3c.github.io/webappsec-subresource-integrity/#grammardef-option-expression + // https://tools.ietf.org/html/rfc5234#appendix-B.1 + (this.options || []).every(opt => opt.match(VCHAR_REGEX)) + )) { + return '' + } + } + const options = this.options && this.options.length + ? `?${this.options.join('?')}` + : '' + return `${this.algorithm}-${this.digest}${options}` } -}); -exports.implodeEntry = implodeEntry; -exports.explodeEntry = explodeEntry; - -var _misc; - -function _load_misc() { - return _misc = __webpack_require__(12); } -var _normalizePattern; - -function _load_normalizePattern() { - return _normalizePattern = __webpack_require__(29); +class Integrity { + get isIntegrity () { return true } + toJSON () { + return this.toString() + } + toString (opts) { + opts = opts || {} + let sep = opts.sep || ' ' + if (opts.strict) { + // Entries must be separated by whitespace, according to spec. + sep = sep.replace(/\S+/g, ' ') + } + return Object.keys(this).map(k => { + return this[k].map(hash => { + return Hash.prototype.toString.call(hash, opts) + }).filter(x => x.length).join(sep) + }).filter(x => x.length).join(sep) + } + concat (integrity, opts) { + const other = typeof integrity === 'string' + ? integrity + : stringify(integrity, opts) + return parse(`${this.toString(opts)} ${other}`, opts) + } + hexDigest () { + return parse(this, {single: true}).hexDigest() + } + match (integrity, opts) { + const other = parse(integrity, opts) + const algo = other.pickAlgorithm(opts) + return ( + this[algo] && + other[algo] && + this[algo].find(hash => + other[algo].find(otherhash => + hash.digest === otherhash.digest + ) + ) + ) || false + } + pickAlgorithm (opts) { + const pickAlgorithm = (opts && opts.pickAlgorithm) || getPrioritizedHash + const keys = Object.keys(this) + if (!keys.length) { + throw new Error(`No algorithms available for ${ + JSON.stringify(this.toString()) + }`) + } + return keys.reduce((acc, algo) => { + return pickAlgorithm(acc, algo) || acc + }) + } } -var _parse2; - -function _load_parse2() { - return _parse2 = _interopRequireDefault(__webpack_require__(81)); +module.exports.parse = parse +function parse (sri, opts) { + opts = opts || {} + if (typeof sri === 'string') { + return _parse(sri, opts) + } else if (sri.algorithm && sri.digest) { + const fullSri = new Integrity() + fullSri[sri.algorithm] = [sri] + return _parse(stringify(fullSri, opts), opts) + } else { + return _parse(stringify(sri, opts), opts) + } } -var _constants; - -function _load_constants() { - return _constants = __webpack_require__(6); +function _parse (integrity, opts) { + // 3.4.3. Parse metadata + // https://w3c.github.io/webappsec-subresource-integrity/#parse-metadata + if (opts.single) { + return new Hash(integrity, opts) + } + return integrity.trim().split(/\s+/).reduce((acc, string) => { + const hash = new Hash(string, opts) + if (hash.algorithm && hash.digest) { + const algo = hash.algorithm + if (!acc[algo]) { acc[algo] = [] } + acc[algo].push(hash) + } + return acc + }, new Integrity()) } -var _fs; - -function _load_fs() { - return _fs = _interopRequireWildcard(__webpack_require__(5)); +module.exports.stringify = stringify +function stringify (obj, opts) { + if (obj.algorithm && obj.digest) { + return Hash.prototype.toString.call(obj, opts) + } else if (typeof obj === 'string') { + return stringify(parse(obj, opts), opts) + } else { + return Integrity.prototype.toString.call(obj, opts) + } } -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const invariant = __webpack_require__(7); - -const path = __webpack_require__(0); -const ssri = __webpack_require__(55); +module.exports.fromHex = fromHex +function fromHex (hexDigest, algorithm, opts) { + const optString = (opts && opts.options && opts.options.length) + ? `?${opts.options.join('?')}` + : '' + return parse( + `${algorithm}-${ + Buffer.from(hexDigest, 'hex').toString('base64') + }${optString}`, opts + ) +} -function getName(pattern) { - return (0, (_normalizePattern || _load_normalizePattern()).normalizePattern)(pattern).name; +module.exports.fromData = fromData +function fromData (data, opts) { + opts = opts || {} + const algorithms = opts.algorithms || ['sha512'] + const optString = opts.options && opts.options.length + ? `?${opts.options.join('?')}` + : '' + return algorithms.reduce((acc, algo) => { + const digest = crypto.createHash(algo).update(data).digest('base64') + const hash = new Hash( + `${algo}-${digest}${optString}`, + opts + ) + if (hash.algorithm && hash.digest) { + const algo = hash.algorithm + if (!acc[algo]) { acc[algo] = [] } + acc[algo].push(hash) + } + return acc + }, new Integrity()) } -function blankObjectUndefined(obj) { - return obj && Object.keys(obj).length ? obj : undefined; +module.exports.fromStream = fromStream +function fromStream (stream, opts) { + opts = opts || {} + const P = opts.Promise || Promise + const istream = integrityStream(opts) + return new P((resolve, reject) => { + stream.pipe(istream) + stream.on('error', reject) + istream.on('error', reject) + let sri + istream.on('integrity', s => { sri = s }) + istream.on('end', () => resolve(sri)) + istream.on('data', () => {}) + }) } -function keyForRemote(remote) { - return remote.resolved || (remote.reference && remote.hash ? `${remote.reference}#${remote.hash}` : null); +module.exports.checkData = checkData +function checkData (data, sri, opts) { + opts = opts || {} + sri = parse(sri, opts) + if (!Object.keys(sri).length) { + if (opts.error) { + throw Object.assign( + new Error('No valid integrity hashes to check against'), { + code: 'EINTEGRITY' + } + ) + } else { + return false + } + } + const algorithm = sri.pickAlgorithm(opts) + const digest = crypto.createHash(algorithm).update(data).digest('base64') + const newSri = parse({algorithm, digest}) + const match = newSri.match(sri, opts) + if (match || !opts.error) { + return match + } else if (typeof opts.size === 'number' && (data.length !== opts.size)) { + const err = new Error(`data size mismatch when checking ${sri}.\n Wanted: ${opts.size}\n Found: ${data.length}`) + err.code = 'EBADSIZE' + err.found = data.length + err.expected = opts.size + err.sri = sri + throw err + } else { + const err = new Error(`Integrity checksum failed when using ${algorithm}: Wanted ${sri}, but got ${newSri}. (${data.length} bytes)`) + err.code = 'EINTEGRITY' + err.found = newSri + err.expected = sri + err.algorithm = algorithm + err.sri = sri + throw err + } } -function serializeIntegrity(integrity) { - // We need this because `Integrity.toString()` does not use sorting to ensure a stable string output - // See https://git.io/vx2Hy - return integrity.toString().split(' ').sort().join(' '); +module.exports.checkStream = checkStream +function checkStream (stream, sri, opts) { + opts = opts || {} + const P = opts.Promise || Promise + const checker = integrityStream(Object.assign({}, opts, { + integrity: sri + })) + return new P((resolve, reject) => { + stream.pipe(checker) + stream.on('error', reject) + checker.on('error', reject) + let sri + checker.on('verified', s => { sri = s }) + checker.on('end', () => resolve(sri)) + checker.on('data', () => {}) + }) } -function implodeEntry(pattern, obj) { - const inferredName = getName(pattern); - const integrity = obj.integrity ? serializeIntegrity(obj.integrity) : ''; - const imploded = { - name: inferredName === obj.name ? undefined : obj.name, - version: obj.version, - uid: obj.uid === obj.version ? undefined : obj.uid, - resolved: obj.resolved, - registry: obj.registry === 'npm' ? undefined : obj.registry, - dependencies: blankObjectUndefined(obj.dependencies), - optionalDependencies: blankObjectUndefined(obj.optionalDependencies), - permissions: blankObjectUndefined(obj.permissions), - prebuiltVariants: blankObjectUndefined(obj.prebuiltVariants) - }; - if (integrity) { - imploded.integrity = integrity; - } - return imploded; +module.exports.integrityStream = integrityStream +function integrityStream (opts) { + opts = opts || {} + // For verification + const sri = opts.integrity && parse(opts.integrity, opts) + const goodSri = sri && Object.keys(sri).length + const algorithm = goodSri && sri.pickAlgorithm(opts) + const digests = goodSri && sri[algorithm] + // Calculating stream + const algorithms = Array.from( + new Set( + (opts.algorithms || ['sha512']) + .concat(algorithm ? [algorithm] : []) + ) + ) + const hashes = algorithms.map(crypto.createHash) + let streamSize = 0 + const stream = new Transform({ + transform (chunk, enc, cb) { + streamSize += chunk.length + hashes.forEach(h => h.update(chunk, enc)) + cb(null, chunk, enc) + } + }).on('end', () => { + const optString = (opts.options && opts.options.length) + ? `?${opts.options.join('?')}` + : '' + const newSri = parse(hashes.map((h, i) => { + return `${algorithms[i]}-${h.digest('base64')}${optString}` + }).join(' '), opts) + // Integrity verification mode + const match = goodSri && newSri.match(sri, opts) + if (typeof opts.size === 'number' && streamSize !== opts.size) { + const err = new Error(`stream size mismatch when checking ${sri}.\n Wanted: ${opts.size}\n Found: ${streamSize}`) + err.code = 'EBADSIZE' + err.found = streamSize + err.expected = opts.size + err.sri = sri + stream.emit('error', err) + } else if (opts.integrity && !match) { + const err = new Error(`${sri} integrity checksum failed when using ${algorithm}: wanted ${digests} but got ${newSri}. (${streamSize} bytes)`) + err.code = 'EINTEGRITY' + err.found = newSri + err.expected = digests + err.algorithm = algorithm + err.sri = sri + stream.emit('error', err) + } else { + stream.emit('size', streamSize) + stream.emit('integrity', newSri) + match && stream.emit('verified', match) + } + }) + return stream } -function explodeEntry(pattern, obj) { - obj.optionalDependencies = obj.optionalDependencies || {}; - obj.dependencies = obj.dependencies || {}; - obj.uid = obj.uid || obj.version; - obj.permissions = obj.permissions || {}; - obj.registry = obj.registry || 'npm'; - obj.name = obj.name || getName(pattern); - const integrity = obj.integrity; - if (integrity && integrity.isIntegrity) { - obj.integrity = ssri.parse(integrity); +module.exports.create = createIntegrity +function createIntegrity (opts) { + opts = opts || {} + const algorithms = opts.algorithms || ['sha512'] + const optString = opts.options && opts.options.length + ? `?${opts.options.join('?')}` + : '' + + const hashes = algorithms.map(crypto.createHash) + + return { + update: function (chunk, enc) { + hashes.forEach(h => h.update(chunk, enc)) + return this + }, + digest: function (enc) { + const integrity = algorithms.reduce((acc, algo) => { + const digest = hashes.shift().digest('base64') + const hash = new Hash( + `${algo}-${digest}${optString}`, + opts + ) + if (hash.algorithm && hash.digest) { + const algo = hash.algorithm + if (!acc[algo]) { acc[algo] = [] } + acc[algo].push(hash) + } + return acc + }, new Integrity()) + + return integrity + } } - return obj; } -class Lockfile { - constructor({ cache, source, parseResultType } = {}) { - this.source = source || ''; - this.cache = cache; - this.parseResultType = parseResultType; - } +const NODE_HASHES = new Set(crypto.getHashes()) - // source string if the `cache` was parsed +// This is a Best Effort™ at a reasonable priority for hash algos +const DEFAULT_PRIORITY = [ + 'md5', 'whirlpool', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512', + // TODO - it's unclear _which_ of these Node will actually use as its name + // for the algorithm, so we guesswork it based on the OpenSSL names. + 'sha3', + 'sha3-256', 'sha3-384', 'sha3-512', + 'sha3_256', 'sha3_384', 'sha3_512' +].filter(algo => NODE_HASHES.has(algo)) +function getPrioritizedHash (algo1, algo2) { + return DEFAULT_PRIORITY.indexOf(algo1.toLowerCase()) >= DEFAULT_PRIORITY.indexOf(algo2.toLowerCase()) + ? algo1 + : algo2 +} - // if true, we're parsing an old yarn file and need to update integrity fields - hasEntriesExistWithoutIntegrity() { - if (!this.cache) { - return false; - } - for (const key in this.cache) { - // $FlowFixMe - `this.cache` is clearly defined at this point - if (!/^.*@(file:|http)/.test(key) && this.cache[key] && !this.cache[key].integrity) { - return true; - } - } +/***/ }), +/* 56 */, +/* 57 */, +/* 58 */, +/* 59 */, +/* 60 */ +/***/ (function(module, exports, __webpack_require__) { - return false; - } +module.exports = minimatch +minimatch.Minimatch = Minimatch - static fromDirectory(dir, reporter) { - return (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* () { - // read the manifest in this directory - const lockfileLoc = path.join(dir, (_constants || _load_constants()).LOCKFILE_FILENAME); +var path = { sep: '/' } +try { + path = __webpack_require__(0) +} catch (er) {} - let lockfile; - let rawLockfile = ''; - let parseResult; +var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {} +var expand = __webpack_require__(175) - if (yield (_fs || _load_fs()).exists(lockfileLoc)) { - rawLockfile = yield (_fs || _load_fs()).readFile(lockfileLoc); - parseResult = (0, (_parse2 || _load_parse2()).default)(rawLockfile, lockfileLoc); +var plTypes = { + '!': { open: '(?:(?!(?:', close: '))[^/]*?)'}, + '?': { open: '(?:', close: ')?' }, + '+': { open: '(?:', close: ')+' }, + '*': { open: '(?:', close: ')*' }, + '@': { open: '(?:', close: ')' } +} - if (reporter) { - if (parseResult.type === 'merge') { - reporter.info(reporter.lang('lockfileMerged')); - } else if (parseResult.type === 'conflict') { - reporter.warn(reporter.lang('lockfileConflict')); - } - } +// any single thing other than / +// don't need to escape / when using new RegExp() +var qmark = '[^/]' - lockfile = parseResult.object; - } else if (reporter) { - reporter.info(reporter.lang('noLockfileFound')); - } +// * => any number of characters +var star = qmark + '*?' - return new Lockfile({ cache: lockfile, source: rawLockfile, parseResultType: parseResult && parseResult.type }); - })(); - } +// ** when dots are allowed. Anything goes, except .. and . +// not (^ or / followed by one or two dots followed by $ or /), +// followed by anything, any number of times. +var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?' - getLocked(pattern) { - const cache = this.cache; - if (!cache) { - return undefined; - } +// not a ^ or / followed by a dot, +// followed by anything, any number of times. +var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?' - const shrunk = pattern in cache && cache[pattern]; +// characters that need to be escaped in RegExp. +var reSpecials = charSet('().*{}+?[]^$\\!') - if (typeof shrunk === 'string') { - return this.getLocked(shrunk); - } else if (shrunk) { - explodeEntry(pattern, shrunk); - return shrunk; - } +// "abc" -> { a:true, b:true, c:true } +function charSet (s) { + return s.split('').reduce(function (set, c) { + set[c] = true + return set + }, {}) +} - return undefined; - } +// normalizes slashes. +var slashSplit = /\/+/ - removePattern(pattern) { - const cache = this.cache; - if (!cache) { - return; - } - delete cache[pattern]; +minimatch.filter = filter +function filter (pattern, options) { + options = options || {} + return function (p, i, list) { + return minimatch(p, pattern, options) } +} - getLockfile(patterns) { - const lockfile = {}; - const seen = new Map(); +function ext (a, b) { + a = a || {} + b = b || {} + var t = {} + Object.keys(b).forEach(function (k) { + t[k] = b[k] + }) + Object.keys(a).forEach(function (k) { + t[k] = a[k] + }) + return t +} - // order by name so that lockfile manifest is assigned to the first dependency with this manifest - // the others that have the same remoteKey will just refer to the first - // ordering allows for consistency in lockfile when it is serialized - const sortedPatternsKeys = Object.keys(patterns).sort((_misc || _load_misc()).sortAlpha); +minimatch.defaults = function (def) { + if (!def || !Object.keys(def).length) return minimatch - for (var _iterator = sortedPatternsKeys, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { - var _ref; + var orig = minimatch - if (_isArray) { - if (_i >= _iterator.length) break; - _ref = _iterator[_i++]; - } else { - _i = _iterator.next(); - if (_i.done) break; - _ref = _i.value; - } + var m = function minimatch (p, pattern, options) { + return orig.minimatch(p, pattern, ext(def, options)) + } - const pattern = _ref; + m.Minimatch = function Minimatch (pattern, options) { + return new orig.Minimatch(pattern, ext(def, options)) + } - const pkg = patterns[pattern]; - const remote = pkg._remote, - ref = pkg._reference; + return m +} - invariant(ref, 'Package is missing a reference'); - invariant(remote, 'Package is missing a remote'); +Minimatch.defaults = function (def) { + if (!def || !Object.keys(def).length) return Minimatch + return minimatch.defaults(def).Minimatch +} - const remoteKey = keyForRemote(remote); - const seenPattern = remoteKey && seen.get(remoteKey); - if (seenPattern) { - // no point in duplicating it - lockfile[pattern] = seenPattern; +function minimatch (p, pattern, options) { + if (typeof pattern !== 'string') { + throw new TypeError('glob pattern string required') + } - // if we're relying on our name being inferred and two of the patterns have - // different inferred names then we need to set it - if (!seenPattern.name && getName(pattern) !== pkg.name) { - seenPattern.name = pkg.name; - } - continue; - } - const obj = implodeEntry(pattern, { - name: pkg.name, - version: pkg.version, - uid: pkg._uid, - resolved: remote.resolved, - integrity: remote.integrity, - registry: remote.registry, - dependencies: pkg.dependencies, - peerDependencies: pkg.peerDependencies, - optionalDependencies: pkg.optionalDependencies, - permissions: ref.permissions, - prebuiltVariants: pkg.prebuiltVariants - }); + if (!options) options = {} - lockfile[pattern] = obj; + // shortcut: comments match nothing. + if (!options.nocomment && pattern.charAt(0) === '#') { + return false + } - if (remoteKey) { - seen.set(remoteKey, obj); - } - } + // "" only matches "" + if (pattern.trim() === '') return p === '' - return lockfile; - } + return new Minimatch(pattern, options).match(p) } -exports.default = Lockfile; -/***/ }), -/* 15 */, -/* 16 */, -/* 17 */ -/***/ (function(module, exports) { +function Minimatch (pattern, options) { + if (!(this instanceof Minimatch)) { + return new Minimatch(pattern, options) + } -module.exports = __webpack_require__(137); + if (typeof pattern !== 'string') { + throw new TypeError('glob pattern string required') + } -/***/ }), -/* 18 */, -/* 19 */, -/* 20 */ -/***/ (function(module, exports, __webpack_require__) { + if (!options) options = {} + pattern = pattern.trim() -"use strict"; + // windows support: need to use /, not \ + if (path.sep !== '/') { + pattern = pattern.split(path.sep).join('/') + } + this.options = options + this.set = [] + this.pattern = pattern + this.regexp = null + this.negate = false + this.comment = false + this.empty = false -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = nullify; -function nullify(obj = {}) { - if (Array.isArray(obj)) { - for (var _iterator = obj, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { - var _ref; - - if (_isArray) { - if (_i >= _iterator.length) break; - _ref = _iterator[_i++]; - } else { - _i = _iterator.next(); - if (_i.done) break; - _ref = _i.value; - } - - const item = _ref; - - nullify(item); - } - } else if (obj !== null && typeof obj === 'object' || typeof obj === 'function') { - Object.setPrototypeOf(obj, null); - - // for..in can only be applied to 'object', not 'function' - if (typeof obj === 'object') { - for (const key in obj) { - nullify(obj[key]); - } - } - } - - return obj; + // make the set of regexps etc. + this.make() } -/***/ }), -/* 21 */, -/* 22 */ -/***/ (function(module, exports) { - -module.exports = __webpack_require__(139); - -/***/ }), -/* 23 */ -/***/ (function(module, exports) { - -var core = module.exports = { version: '2.5.7' }; -if (typeof __e == 'number') __e = core; // eslint-disable-line no-undef - +Minimatch.prototype.debug = function () {} -/***/ }), -/* 24 */, -/* 25 */, -/* 26 */, -/* 27 */ -/***/ (function(module, exports, __webpack_require__) { +Minimatch.prototype.make = make +function make () { + // don't do it more than once. + if (this._made) return -var isObject = __webpack_require__(34); -module.exports = function (it) { - if (!isObject(it)) throw TypeError(it + ' is not an object!'); - return it; -}; + var pattern = this.pattern + var options = this.options + // empty patterns and comments match nothing. + if (!options.nocomment && pattern.charAt(0) === '#') { + this.comment = true + return + } + if (!pattern) { + this.empty = true + return + } -/***/ }), -/* 28 */, -/* 29 */ -/***/ (function(module, exports, __webpack_require__) { + // step 1: figure out negation, etc. + this.parseNegate() -"use strict"; + // step 2: expand braces + var set = this.globSet = this.braceExpand() + if (options.debug) this.debug = console.error -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.normalizePattern = normalizePattern; + this.debug(this.pattern, set) -/** - * Explode and normalize a pattern into its name and range. - */ + // step 3: now we have a set, so turn each one into a series of path-portion + // matching patterns. + // These will be regexps, except in the case of "**", which is + // set to the GLOBSTAR object for globstar behavior, + // and will not contain any / characters + set = this.globParts = set.map(function (s) { + return s.split(slashSplit) + }) -function normalizePattern(pattern) { - let hasVersion = false; - let range = 'latest'; - let name = pattern; + this.debug(this.pattern, set) - // if we're a scope then remove the @ and add it back later - let isScoped = false; - if (name[0] === '@') { - isScoped = true; - name = name.slice(1); - } + // glob --> regexps + set = set.map(function (s, si, set) { + return s.map(this.parse, this) + }, this) - // take first part as the name - const parts = name.split('@'); - if (parts.length > 1) { - name = parts.shift(); - range = parts.join('@'); + this.debug(this.pattern, set) - if (range) { - hasVersion = true; - } else { - range = '*'; - } - } + // filter out everything that didn't compile properly. + set = set.filter(function (s) { + return s.indexOf(false) === -1 + }) - // add back @ scope suffix - if (isScoped) { - name = `@${name}`; - } + this.debug(this.pattern, set) - return { name, range, hasVersion }; + this.set = set } -/***/ }), -/* 30 */, -/* 31 */ -/***/ (function(module, exports, __webpack_require__) { - -var dP = __webpack_require__(50); -var createDesc = __webpack_require__(106); -module.exports = __webpack_require__(33) ? function (object, key, value) { - return dP.f(object, key, createDesc(1, value)); -} : function (object, key, value) { - object[key] = value; - return object; -}; - - -/***/ }), -/* 32 */ -/***/ (function(module, exports, __webpack_require__) { +Minimatch.prototype.parseNegate = parseNegate +function parseNegate () { + var pattern = this.pattern + var negate = false + var options = this.options + var negateOffset = 0 -/* eslint-disable node/no-deprecated-api */ -var buffer = __webpack_require__(63) -var Buffer = buffer.Buffer + if (options.nonegate) return -// alternative to using Object.keys for old browsers -function copyProps (src, dst) { - for (var key in src) { - dst[key] = src[key] + for (var i = 0, l = pattern.length + ; i < l && pattern.charAt(i) === '!' + ; i++) { + negate = !negate + negateOffset++ } -} -if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) { - module.exports = buffer -} else { - // Copy properties from require('buffer') - copyProps(buffer, exports) - exports.Buffer = SafeBuffer -} -function SafeBuffer (arg, encodingOrOffset, length) { - return Buffer(arg, encodingOrOffset, length) + if (negateOffset) this.pattern = pattern.substr(negateOffset) + this.negate = negate } -// Copy static methods from Buffer -copyProps(Buffer, SafeBuffer) - -SafeBuffer.from = function (arg, encodingOrOffset, length) { - if (typeof arg === 'number') { - throw new TypeError('Argument must not be a number') - } - return Buffer(arg, encodingOrOffset, length) +// Brace expansion: +// a{b,c}d -> abd acd +// a{b,}c -> abc ac +// a{0..3}d -> a0d a1d a2d a3d +// a{b,c{d,e}f}g -> abg acdfg acefg +// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg +// +// Invalid sets are not expanded. +// a{2..}b -> a{2..}b +// a{b}c -> a{b}c +minimatch.braceExpand = function (pattern, options) { + return braceExpand(pattern, options) } -SafeBuffer.alloc = function (size, fill, encoding) { - if (typeof size !== 'number') { - throw new TypeError('Argument must be a number') - } - var buf = Buffer(size) - if (fill !== undefined) { - if (typeof encoding === 'string') { - buf.fill(fill, encoding) +Minimatch.prototype.braceExpand = braceExpand + +function braceExpand (pattern, options) { + if (!options) { + if (this instanceof Minimatch) { + options = this.options } else { - buf.fill(fill) + options = {} } - } else { - buf.fill(0) } - return buf -} -SafeBuffer.allocUnsafe = function (size) { - if (typeof size !== 'number') { - throw new TypeError('Argument must be a number') - } - return Buffer(size) -} + pattern = typeof pattern === 'undefined' + ? this.pattern : pattern -SafeBuffer.allocUnsafeSlow = function (size) { - if (typeof size !== 'number') { - throw new TypeError('Argument must be a number') + if (typeof pattern === 'undefined') { + throw new TypeError('undefined pattern') } - return buffer.SlowBuffer(size) -} + if (options.nobrace || + !pattern.match(/\{.*\}/)) { + // shortcut. no need to expand. + return [pattern] + } -/***/ }), -/* 33 */ -/***/ (function(module, exports, __webpack_require__) { + return expand(pattern) +} -// Thank's IE8 for his funny defineProperty -module.exports = !__webpack_require__(85)(function () { - return Object.defineProperty({}, 'a', { get: function () { return 7; } }).a != 7; -}); +// parse a component of the expanded set. +// At this point, no pattern may contain "/" in it +// so we're going to return a 2d array, where each entry is the full +// pattern, split on '/', and then turned into a regular expression. +// A regexp is made at the end which joins each array with an +// escaped /, and another full one which joins each regexp with |. +// +// Following the lead of Bash 4.1, note that "**" only has special meaning +// when it is the *only* thing in a path portion. Otherwise, any series +// of * is equivalent to a single *. Globstar behavior is enabled by +// default, and can be disabled by setting options.noglobstar. +Minimatch.prototype.parse = parse +var SUBPARSE = {} +function parse (pattern, isSub) { + if (pattern.length > 1024 * 64) { + throw new TypeError('pattern is too long') + } + var options = this.options -/***/ }), -/* 34 */ -/***/ (function(module, exports) { + // shortcuts + if (!options.noglobstar && pattern === '**') return GLOBSTAR + if (pattern === '') return '' -module.exports = function (it) { - return typeof it === 'object' ? it !== null : typeof it === 'function'; -}; + var re = '' + var hasMagic = !!options.nocase + var escaping = false + // ? => one single character + var patternListStack = [] + var negativeLists = [] + var stateChar + var inClass = false + var reClassStart = -1 + var classStart = -1 + // . and .. never match anything that doesn't start with ., + // even when options.dot is set. + var patternStart = pattern.charAt(0) === '.' ? '' // anything + // not (start or / followed by . or .. followed by / or end) + : options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))' + : '(?!\\.)' + var self = this + function clearStateChar () { + if (stateChar) { + // we had some state-tracking character + // that wasn't consumed by this pass. + switch (stateChar) { + case '*': + re += star + hasMagic = true + break + case '?': + re += qmark + hasMagic = true + break + default: + re += '\\' + stateChar + break + } + self.debug('clearStateChar %j %j', stateChar, re) + stateChar = false + } + } -/***/ }), -/* 35 */ -/***/ (function(module, exports) { + for (var i = 0, len = pattern.length, c + ; (i < len) && (c = pattern.charAt(i)) + ; i++) { + this.debug('%s\t%s %s %j', pattern, i, re, c) -module.exports = {}; + // skip over any that are escaped. + if (escaping && reSpecials[c]) { + re += '\\' + c + escaping = false + continue + } + switch (c) { + case '/': + // completely not allowed, even escaped. + // Should already be path-split by now. + return false -/***/ }), -/* 36 */ -/***/ (function(module, exports) { + case '\\': + clearStateChar() + escaping = true + continue -module.exports = __webpack_require__(120); + // the various stateChar values + // for the "extglob" stuff. + case '?': + case '*': + case '+': + case '@': + case '!': + this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c) -/***/ }), -/* 37 */, -/* 38 */, -/* 39 */, -/* 40 */ -/***/ (function(module, exports, __webpack_require__) { + // all of those are literals inside a class, except that + // the glob [!a] means [^a] in regexp + if (inClass) { + this.debug(' in class') + if (c === '!' && i === classStart + 1) c = '^' + re += c + continue + } -"use strict"; + // if we already have a stateChar, then it means + // that there was something like ** or +? in there. + // Handle the stateChar, then proceed with this one. + self.debug('call clearStateChar %j', stateChar) + clearStateChar() + stateChar = c + // if extglob is disabled, then +(asdf|foo) isn't a thing. + // just clear the statechar *now*, rather than even diving into + // the patternList stuff. + if (options.noext) clearStateChar() + continue + case '(': + if (inClass) { + re += '(' + continue + } -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.wait = wait; -exports.promisify = promisify; -exports.queue = queue; -function wait(delay) { - return new Promise(resolve => { - setTimeout(resolve, delay); - }); -} + if (!stateChar) { + re += '\\(' + continue + } -function promisify(fn, firstData) { - return function (...args) { - return new Promise(function (resolve, reject) { - args.push(function (err, ...result) { - let res = result; + patternListStack.push({ + type: stateChar, + start: i - 1, + reStart: re.length, + open: plTypes[stateChar].open, + close: plTypes[stateChar].close + }) + // negation is (?:(?!js)[^/]*) + re += stateChar === '!' ? '(?:(?!(?:' : '(?:' + this.debug('plType %j %j', stateChar, re) + stateChar = false + continue - if (result.length <= 1) { - res = result[0]; + case ')': + if (inClass || !patternListStack.length) { + re += '\\)' + continue } - if (firstData) { - res = err; - err = null; + clearStateChar() + hasMagic = true + var pl = patternListStack.pop() + // negation is (?:(?!js)[^/]*) + // The others are (?:) + re += pl.close + if (pl.type === '!') { + negativeLists.push(pl) } + pl.reEnd = re.length + continue - if (err) { - reject(err); - } else { - resolve(res); + case '|': + if (inClass || !patternListStack.length || escaping) { + re += '\\|' + escaping = false + continue } - }); - - fn.apply(null, args); - }); - }; -} - -function queue(arr, promiseProducer, concurrency = Infinity) { - concurrency = Math.min(concurrency, arr.length); - // clone - arr = arr.slice(); + clearStateChar() + re += '|' + continue - const results = []; - let total = arr.length; - if (!total) { - return Promise.resolve(results); - } + // these are mostly the same in regexp and glob + case '[': + // swallow any state-tracking char before the [ + clearStateChar() - return new Promise((resolve, reject) => { - for (let i = 0; i < concurrency; i++) { - next(); - } + if (inClass) { + re += '\\' + c + continue + } - function next() { - const item = arr.shift(); - const promise = promiseProducer(item); + inClass = true + classStart = i + reClassStart = re.length + re += c + continue - promise.then(function (result) { - results.push(result); + case ']': + // a right bracket shall lose its special + // meaning and represent itself in + // a bracket expression if it occurs + // first in the list. -- POSIX.2 2.8.3.2 + if (i === classStart + 1 || !inClass) { + re += '\\' + c + escaping = false + continue + } - total--; - if (total === 0) { - resolve(results); - } else { - if (arr.length) { - next(); + // handle the case where we left a class open. + // "[z-a]" is valid, equivalent to "\[z-a\]" + if (inClass) { + // split where the last [ was, make sure we don't have + // an invalid re. if so, re-walk the contents of the + // would-be class to re-translate any characters that + // were passed through as-is + // TODO: It would probably be faster to determine this + // without a try/catch and a new RegExp, but it's tricky + // to do safely. For now, this is safe and works. + var cs = pattern.substring(classStart + 1, i) + try { + RegExp('[' + cs + ']') + } catch (er) { + // not a valid class! + var sp = this.parse(cs, SUBPARSE) + re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]' + hasMagic = hasMagic || sp[1] + inClass = false + continue } } - }, reject); - } - }); -} -/***/ }), -/* 41 */ -/***/ (function(module, exports, __webpack_require__) { + // finish up the class. + hasMagic = true + inClass = false + re += c + continue -var global = __webpack_require__(11); -var core = __webpack_require__(23); -var ctx = __webpack_require__(48); -var hide = __webpack_require__(31); -var has = __webpack_require__(49); -var PROTOTYPE = 'prototype'; + default: + // swallow any state char that wasn't consumed + clearStateChar() -var $export = function (type, name, source) { - var IS_FORCED = type & $export.F; - var IS_GLOBAL = type & $export.G; - var IS_STATIC = type & $export.S; - var IS_PROTO = type & $export.P; - var IS_BIND = type & $export.B; - var IS_WRAP = type & $export.W; - var exports = IS_GLOBAL ? core : core[name] || (core[name] = {}); - var expProto = exports[PROTOTYPE]; - var target = IS_GLOBAL ? global : IS_STATIC ? global[name] : (global[name] || {})[PROTOTYPE]; - var key, own, out; - if (IS_GLOBAL) source = name; - for (key in source) { - // contains in native - own = !IS_FORCED && target && target[key] !== undefined; - if (own && has(exports, key)) continue; - // export native or passed - out = own ? target[key] : source[key]; - // prevent global pollution for namespaces - exports[key] = IS_GLOBAL && typeof target[key] != 'function' ? source[key] - // bind timers to global for call from export context - : IS_BIND && own ? ctx(out, global) - // wrap global constructors for prevent change them in library - : IS_WRAP && target[key] == out ? (function (C) { - var F = function (a, b, c) { - if (this instanceof C) { - switch (arguments.length) { - case 0: return new C(); - case 1: return new C(a); - case 2: return new C(a, b); - } return new C(a, b, c); - } return C.apply(this, arguments); - }; - F[PROTOTYPE] = C[PROTOTYPE]; - return F; - // make static versions for prototype methods - })(out) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out; - // export proto methods to core.%CONSTRUCTOR%.methods.%NAME% - if (IS_PROTO) { - (exports.virtual || (exports.virtual = {}))[key] = out; - // export proto methods to core.%CONSTRUCTOR%.prototype.%NAME% - if (type & $export.R && expProto && !expProto[key]) hide(expProto, key, out); - } - } -}; -// type bitmap -$export.F = 1; // forced -$export.G = 2; // global -$export.S = 4; // static -$export.P = 8; // proto -$export.B = 16; // bind -$export.W = 32; // wrap -$export.U = 64; // safe -$export.R = 128; // real proto method for `library` -module.exports = $export; + if (escaping) { + // no need + escaping = false + } else if (reSpecials[c] + && !(c === '^' && inClass)) { + re += '\\' + } + re += c -/***/ }), -/* 42 */ -/***/ (function(module, exports, __webpack_require__) { + } // switch + } // for -try { - var util = __webpack_require__(2); - if (typeof util.inherits !== 'function') throw ''; - module.exports = util.inherits; -} catch (e) { - module.exports = __webpack_require__(224); -} + // handle the case where we left a class open. + // "[abc" is valid, equivalent to "\[abc" + if (inClass) { + // split where the last [ was, and escape it + // this is a huge pita. We now have to re-walk + // the contents of the would-be class to re-translate + // any characters that were passed through as-is + cs = pattern.substr(classStart + 1) + sp = this.parse(cs, SUBPARSE) + re = re.substr(0, reClassStart) + '\\[' + sp[0] + hasMagic = hasMagic || sp[1] + } + // handle the case where we had a +( thing at the *end* + // of the pattern. + // each pattern list stack adds 3 chars, and we need to go through + // and escape any | chars that were passed through as-is for the regexp. + // Go through and escape them, taking care not to double-escape any + // | chars that were already escaped. + for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) { + var tail = re.slice(pl.reStart + pl.open.length) + this.debug('setting tail', re, pl) + // maybe some even number of \, then maybe 1 \, followed by a | + tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, function (_, $1, $2) { + if (!$2) { + // the | isn't already escaped, so escape it. + $2 = '\\' + } -/***/ }), -/* 43 */, -/* 44 */, -/* 45 */ -/***/ (function(module, exports, __webpack_require__) { + // need to escape all those slashes *again*, without escaping the + // one that we need for escaping the | character. As it works out, + // escaping an even number of slashes can be done by simply repeating + // it exactly after itself. That's why this trick works. + // + // I am sorry that you have to see this. + return $1 + $1 + $2 + '|' + }) -"use strict"; + this.debug('tail=%j\n %s', tail, tail, pl, re) + var t = pl.type === '*' ? star + : pl.type === '?' ? qmark + : '\\' + pl.type + hasMagic = true + re = re.slice(0, pl.reStart) + t + '\\(' + tail + } -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.home = undefined; + // handle trailing things that only matter at the very end. + clearStateChar() + if (escaping) { + // trailing \\ + re += '\\\\' + } -var _rootUser; + // only need to apply the nodot start if the re starts with + // something that could conceivably capture a dot + var addPatternStart = false + switch (re.charAt(0)) { + case '.': + case '[': + case '(': addPatternStart = true + } -function _load_rootUser() { - return _rootUser = _interopRequireDefault(__webpack_require__(169)); -} + // Hack to work around lack of negative lookbehind in JS + // A pattern like: *.!(x).!(y|z) needs to ensure that a name + // like 'a.xyz.yz' doesn't match. So, the first negative + // lookahead, has to look ALL the way ahead, to the end of + // the pattern. + for (var n = negativeLists.length - 1; n > -1; n--) { + var nl = negativeLists[n] -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + var nlBefore = re.slice(0, nl.reStart) + var nlFirst = re.slice(nl.reStart, nl.reEnd - 8) + var nlLast = re.slice(nl.reEnd - 8, nl.reEnd) + var nlAfter = re.slice(nl.reEnd) -const path = __webpack_require__(0); + nlLast += nlAfter -const home = exports.home = __webpack_require__(36).homedir(); + // Handle nested stuff like *(*.js|!(*.json)), where open parens + // mean that we should *not* include the ) in the bit that is considered + // "after" the negated section. + var openParensBefore = nlBefore.split('(').length - 1 + var cleanAfter = nlAfter + for (i = 0; i < openParensBefore; i++) { + cleanAfter = cleanAfter.replace(/\)[+*?]?/, '') + } + nlAfter = cleanAfter -const userHomeDir = (_rootUser || _load_rootUser()).default ? path.resolve('/usr/local/share') : home; + var dollar = '' + if (nlAfter === '' && isSub !== SUBPARSE) { + dollar = '$' + } + var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast + re = newRe + } -exports.default = userHomeDir; + // if the re is not "" at this point, then we need to make sure + // it doesn't match against an empty path part. + // Otherwise a/* will match a/, which it should not. + if (re !== '' && hasMagic) { + re = '(?=.)' + re + } -/***/ }), -/* 46 */ -/***/ (function(module, exports) { + if (addPatternStart) { + re = patternStart + re + } -module.exports = function (it) { - if (typeof it != 'function') throw TypeError(it + ' is not a function!'); - return it; -}; + // parsing just a piece of a larger pattern. + if (isSub === SUBPARSE) { + return [re, hasMagic] + } + // skip the regexp for non-magical patterns + // unescape anything in it, though, so that it'll be + // an exact match against a file etc. + if (!hasMagic) { + return globUnescape(pattern) + } -/***/ }), -/* 47 */ -/***/ (function(module, exports) { + var flags = options.nocase ? 'i' : '' + try { + var regExp = new RegExp('^' + re + '$', flags) + } catch (er) { + // If it was an invalid regular expression, then it can't match + // anything. This trick looks for a character after the end of + // the string, which is of course impossible, except in multi-line + // mode, but it's not a /m regex. + return new RegExp('$.') + } -var toString = {}.toString; + regExp._glob = pattern + regExp._src = re -module.exports = function (it) { - return toString.call(it).slice(8, -1); -}; + return regExp +} +minimatch.makeRe = function (pattern, options) { + return new Minimatch(pattern, options || {}).makeRe() +} -/***/ }), -/* 48 */ -/***/ (function(module, exports, __webpack_require__) { +Minimatch.prototype.makeRe = makeRe +function makeRe () { + if (this.regexp || this.regexp === false) return this.regexp -// optional / simple context binding -var aFunction = __webpack_require__(46); -module.exports = function (fn, that, length) { - aFunction(fn); - if (that === undefined) return fn; - switch (length) { - case 1: return function (a) { - return fn.call(that, a); - }; - case 2: return function (a, b) { - return fn.call(that, a, b); - }; - case 3: return function (a, b, c) { - return fn.call(that, a, b, c); - }; + // at this point, this.set is a 2d array of partial + // pattern strings, or "**". + // + // It's better to use .match(). This function shouldn't + // be used, really, but it's pretty convenient sometimes, + // when you just want to work with a regex. + var set = this.set + + if (!set.length) { + this.regexp = false + return this.regexp } - return function (/* ...args */) { - return fn.apply(that, arguments); - }; -}; + var options = this.options + var twoStar = options.noglobstar ? star + : options.dot ? twoStarDot + : twoStarNoDot + var flags = options.nocase ? 'i' : '' -/***/ }), -/* 49 */ -/***/ (function(module, exports) { + var re = set.map(function (pattern) { + return pattern.map(function (p) { + return (p === GLOBSTAR) ? twoStar + : (typeof p === 'string') ? regExpEscape(p) + : p._src + }).join('\\\/') + }).join('|') -var hasOwnProperty = {}.hasOwnProperty; -module.exports = function (it, key) { - return hasOwnProperty.call(it, key); -}; + // must match entire pattern + // ending in a * or ** will make it less strict. + re = '^(?:' + re + ')$' + // can match anything, as long as it's not this. + if (this.negate) re = '^(?!' + re + ').*$' -/***/ }), -/* 50 */ -/***/ (function(module, exports, __webpack_require__) { + try { + this.regexp = new RegExp(re, flags) + } catch (ex) { + this.regexp = false + } + return this.regexp +} -var anObject = __webpack_require__(27); -var IE8_DOM_DEFINE = __webpack_require__(184); -var toPrimitive = __webpack_require__(201); -var dP = Object.defineProperty; +minimatch.match = function (list, pattern, options) { + options = options || {} + var mm = new Minimatch(pattern, options) + list = list.filter(function (f) { + return mm.match(f) + }) + if (mm.options.nonull && !list.length) { + list.push(pattern) + } + return list +} -exports.f = __webpack_require__(33) ? Object.defineProperty : function defineProperty(O, P, Attributes) { - anObject(O); - P = toPrimitive(P, true); - anObject(Attributes); - if (IE8_DOM_DEFINE) try { - return dP(O, P, Attributes); - } catch (e) { /* empty */ } - if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported!'); - if ('value' in Attributes) O[P] = Attributes.value; - return O; -}; +Minimatch.prototype.match = match +function match (f, partial) { + this.debug('match', f, this.pattern) + // short-circuit in the case of busted things. + // comments, etc. + if (this.comment) return false + if (this.empty) return f === '' + if (f === '/' && partial) return true -/***/ }), -/* 51 */, -/* 52 */, -/* 53 */, -/* 54 */ -/***/ (function(module, exports) { + var options = this.options -module.exports = __webpack_require__(155); + // windows: need to use /, not \ + if (path.sep !== '/') { + f = f.split(path.sep).join('/') + } -/***/ }), -/* 55 */ -/***/ (function(module, exports, __webpack_require__) { + // treat the test path as a set of pathparts. + f = f.split(slashSplit) + this.debug(this.pattern, 'split', f) -"use strict"; + // just ONE of the pattern sets in this.set needs to match + // in order for it to be valid. If negating, then just one + // match means that we have failed. + // Either way, return on the first hit. + var set = this.set + this.debug(this.pattern, 'set', set) -const Buffer = __webpack_require__(32).Buffer + // Find the basename of the path by looking for the last non-empty segment + var filename + var i + for (i = f.length - 1; i >= 0; i--) { + filename = f[i] + if (filename) break + } -const crypto = __webpack_require__(9) -const Transform = __webpack_require__(17).Transform + for (i = 0; i < set.length; i++) { + var pattern = set[i] + var file = f + if (options.matchBase && pattern.length === 1) { + file = [filename] + } + var hit = this.matchOne(file, pattern, partial) + if (hit) { + if (options.flipNegate) return true + return !this.negate + } + } -const SPEC_ALGORITHMS = ['sha256', 'sha384', 'sha512'] + // didn't get any hits. this is success if it's a negative + // pattern, failure otherwise. + if (options.flipNegate) return false + return this.negate +} -const BASE64_REGEX = /^[a-z0-9+/]+(?:=?=?)$/i -const SRI_REGEX = /^([^-]+)-([^?]+)([?\S*]*)$/ -const STRICT_SRI_REGEX = /^([^-]+)-([A-Za-z0-9+/=]{44,88})(\?[\x21-\x7E]*)*$/ -const VCHAR_REGEX = /^[\x21-\x7E]+$/ +// set partial to true to test if, for example, +// "/a/b" matches the start of "/*/b/*/d" +// Partial means, if you run out of file before you run +// out of pattern, then that's fine, as long as all +// the parts match. +Minimatch.prototype.matchOne = function (file, pattern, partial) { + var options = this.options -class Hash { - get isHash () { return true } - constructor (hash, opts) { - const strict = !!(opts && opts.strict) - this.source = hash.trim() - // 3.1. Integrity metadata (called "Hash" by ssri) - // https://w3c.github.io/webappsec-subresource-integrity/#integrity-metadata-description - const match = this.source.match( - strict - ? STRICT_SRI_REGEX - : SRI_REGEX - ) - if (!match) { return } - if (strict && !SPEC_ALGORITHMS.some(a => a === match[1])) { return } - this.algorithm = match[1] - this.digest = match[2] + this.debug('matchOne', + { 'this': this, file: file, pattern: pattern }) - const rawOpts = match[3] - this.options = rawOpts ? rawOpts.slice(1).split('?') : [] - } - hexDigest () { - return this.digest && Buffer.from(this.digest, 'base64').toString('hex') - } - toJSON () { - return this.toString() - } - toString (opts) { - if (opts && opts.strict) { - // Strict mode enforces the standard as close to the foot of the - // letter as it can. - if (!( - // The spec has very restricted productions for algorithms. - // https://www.w3.org/TR/CSP2/#source-list-syntax - SPEC_ALGORITHMS.some(x => x === this.algorithm) && - // Usually, if someone insists on using a "different" base64, we - // leave it as-is, since there's multiple standards, and the - // specified is not a URL-safe variant. - // https://www.w3.org/TR/CSP2/#base64_value - this.digest.match(BASE64_REGEX) && - // Option syntax is strictly visual chars. - // https://w3c.github.io/webappsec-subresource-integrity/#grammardef-option-expression - // https://tools.ietf.org/html/rfc5234#appendix-B.1 - (this.options || []).every(opt => opt.match(VCHAR_REGEX)) - )) { - return '' - } - } - const options = this.options && this.options.length - ? `?${this.options.join('?')}` - : '' - return `${this.algorithm}-${this.digest}${options}` - } -} + this.debug('matchOne', file.length, pattern.length) -class Integrity { - get isIntegrity () { return true } - toJSON () { - return this.toString() - } - toString (opts) { - opts = opts || {} - let sep = opts.sep || ' ' - if (opts.strict) { - // Entries must be separated by whitespace, according to spec. - sep = sep.replace(/\S+/g, ' ') - } - return Object.keys(this).map(k => { - return this[k].map(hash => { - return Hash.prototype.toString.call(hash, opts) - }).filter(x => x.length).join(sep) - }).filter(x => x.length).join(sep) - } - concat (integrity, opts) { - const other = typeof integrity === 'string' - ? integrity - : stringify(integrity, opts) - return parse(`${this.toString(opts)} ${other}`, opts) - } - hexDigest () { - return parse(this, {single: true}).hexDigest() - } - match (integrity, opts) { - const other = parse(integrity, opts) - const algo = other.pickAlgorithm(opts) - return ( - this[algo] && - other[algo] && - this[algo].find(hash => - other[algo].find(otherhash => - hash.digest === otherhash.digest - ) - ) - ) || false - } - pickAlgorithm (opts) { - const pickAlgorithm = (opts && opts.pickAlgorithm) || getPrioritizedHash - const keys = Object.keys(this) - if (!keys.length) { - throw new Error(`No algorithms available for ${ - JSON.stringify(this.toString()) - }`) - } - return keys.reduce((acc, algo) => { - return pickAlgorithm(acc, algo) || acc - }) - } -} + for (var fi = 0, + pi = 0, + fl = file.length, + pl = pattern.length + ; (fi < fl) && (pi < pl) + ; fi++, pi++) { + this.debug('matchOne loop') + var p = pattern[pi] + var f = file[fi] -module.exports.parse = parse -function parse (sri, opts) { - opts = opts || {} - if (typeof sri === 'string') { - return _parse(sri, opts) - } else if (sri.algorithm && sri.digest) { - const fullSri = new Integrity() - fullSri[sri.algorithm] = [sri] - return _parse(stringify(fullSri, opts), opts) - } else { - return _parse(stringify(sri, opts), opts) - } -} + this.debug(pattern, p, f) -function _parse (integrity, opts) { - // 3.4.3. Parse metadata - // https://w3c.github.io/webappsec-subresource-integrity/#parse-metadata - if (opts.single) { - return new Hash(integrity, opts) - } - return integrity.trim().split(/\s+/).reduce((acc, string) => { - const hash = new Hash(string, opts) - if (hash.algorithm && hash.digest) { - const algo = hash.algorithm - if (!acc[algo]) { acc[algo] = [] } - acc[algo].push(hash) - } - return acc - }, new Integrity()) -} + // should be impossible. + // some invalid regexp stuff in the set. + if (p === false) return false -module.exports.stringify = stringify -function stringify (obj, opts) { - if (obj.algorithm && obj.digest) { - return Hash.prototype.toString.call(obj, opts) - } else if (typeof obj === 'string') { - return stringify(parse(obj, opts), opts) - } else { - return Integrity.prototype.toString.call(obj, opts) - } -} + if (p === GLOBSTAR) { + this.debug('GLOBSTAR', [pattern, p, f]) -module.exports.fromHex = fromHex -function fromHex (hexDigest, algorithm, opts) { - const optString = (opts && opts.options && opts.options.length) - ? `?${opts.options.join('?')}` - : '' - return parse( - `${algorithm}-${ - Buffer.from(hexDigest, 'hex').toString('base64') - }${optString}`, opts - ) -} + // "**" + // a/**/b/**/c would match the following: + // a/b/x/y/z/c + // a/x/y/z/b/c + // a/b/x/b/x/c + // a/b/c + // To do this, take the rest of the pattern after + // the **, and see if it would match the file remainder. + // If so, return success. + // If not, the ** "swallows" a segment, and try again. + // This is recursively awful. + // + // a/**/b/**/c matching a/b/x/y/z/c + // - a matches a + // - doublestar + // - matchOne(b/x/y/z/c, b/**/c) + // - b matches b + // - doublestar + // - matchOne(x/y/z/c, c) -> no + // - matchOne(y/z/c, c) -> no + // - matchOne(z/c, c) -> no + // - matchOne(c, c) yes, hit + var fr = fi + var pr = pi + 1 + if (pr === pl) { + this.debug('** at the end') + // a ** at the end will just swallow the rest. + // We have found a match. + // however, it will not swallow /.x, unless + // options.dot is set. + // . and .. are *never* matched by **, for explosively + // exponential reasons. + for (; fi < fl; fi++) { + if (file[fi] === '.' || file[fi] === '..' || + (!options.dot && file[fi].charAt(0) === '.')) return false + } + return true + } -module.exports.fromData = fromData -function fromData (data, opts) { - opts = opts || {} - const algorithms = opts.algorithms || ['sha512'] - const optString = opts.options && opts.options.length - ? `?${opts.options.join('?')}` - : '' - return algorithms.reduce((acc, algo) => { - const digest = crypto.createHash(algo).update(data).digest('base64') - const hash = new Hash( - `${algo}-${digest}${optString}`, - opts - ) - if (hash.algorithm && hash.digest) { - const algo = hash.algorithm - if (!acc[algo]) { acc[algo] = [] } - acc[algo].push(hash) - } - return acc - }, new Integrity()) -} + // ok, let's see if we can swallow whatever we can. + while (fr < fl) { + var swallowee = file[fr] -module.exports.fromStream = fromStream -function fromStream (stream, opts) { - opts = opts || {} - const P = opts.Promise || Promise - const istream = integrityStream(opts) - return new P((resolve, reject) => { - stream.pipe(istream) - stream.on('error', reject) - istream.on('error', reject) - let sri - istream.on('integrity', s => { sri = s }) - istream.on('end', () => resolve(sri)) - istream.on('data', () => {}) - }) -} + this.debug('\nglobstar while', file, fr, pattern, pr, swallowee) -module.exports.checkData = checkData -function checkData (data, sri, opts) { - opts = opts || {} - sri = parse(sri, opts) - if (!Object.keys(sri).length) { - if (opts.error) { - throw Object.assign( - new Error('No valid integrity hashes to check against'), { - code: 'EINTEGRITY' + // XXX remove this slice. Just pass the start index. + if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { + this.debug('globstar found match!', fr, fl, swallowee) + // found a match. + return true + } else { + // can't swallow "." or ".." ever. + // can only swallow ".foo" when explicitly asked. + if (swallowee === '.' || swallowee === '..' || + (!options.dot && swallowee.charAt(0) === '.')) { + this.debug('dot detected!', file, fr, pattern, pr) + break + } + + // ** swallows a segment, and continue. + this.debug('globstar swallow a segment, and continue') + fr++ } - ) - } else { + } + + // no match was found. + // However, in partial mode, we can't say this is necessarily over. + // If there's more *pattern* left, then + if (partial) { + // ran out of file + this.debug('\n>>> no match, partial?', file, fr, pattern, pr) + if (fr === fl) return true + } return false } + + // something other than ** + // non-magic patterns just have to match exactly + // patterns with magic have been turned into regexps. + var hit + if (typeof p === 'string') { + if (options.nocase) { + hit = f.toLowerCase() === p.toLowerCase() + } else { + hit = f === p + } + this.debug('string match', p, f, hit) + } else { + hit = f.match(p) + this.debug('pattern match', p, f, hit) + } + + if (!hit) return false } - const algorithm = sri.pickAlgorithm(opts) - const digest = crypto.createHash(algorithm).update(data).digest('base64') - const newSri = parse({algorithm, digest}) - const match = newSri.match(sri, opts) - if (match || !opts.error) { - return match - } else if (typeof opts.size === 'number' && (data.length !== opts.size)) { - const err = new Error(`data size mismatch when checking ${sri}.\n Wanted: ${opts.size}\n Found: ${data.length}`) - err.code = 'EBADSIZE' - err.found = data.length - err.expected = opts.size - err.sri = sri - throw err - } else { - const err = new Error(`Integrity checksum failed when using ${algorithm}: Wanted ${sri}, but got ${newSri}. (${data.length} bytes)`) - err.code = 'EINTEGRITY' - err.found = newSri - err.expected = sri - err.algorithm = algorithm - err.sri = sri - throw err + + // Note: ending in / means that we'll get a final "" + // at the end of the pattern. This can only match a + // corresponding "" at the end of the file. + // If the file ends in /, then it can only match a + // a pattern that ends in /, unless the pattern just + // doesn't have any more for it. But, a/b/ should *not* + // match "a/b/*", even though "" matches against the + // [^/]*? pattern, except in partial mode, where it might + // simply not be reached yet. + // However, a/b/ should still satisfy a/* + + // now either we fell off the end of the pattern, or we're done. + if (fi === fl && pi === pl) { + // ran out of pattern and filename at the same time. + // an exact hit! + return true + } else if (fi === fl) { + // ran out of file, but still had pattern left. + // this is ok if we're doing the match as part of + // a glob fs traversal. + return partial + } else if (pi === pl) { + // ran out of pattern, still have file left. + // this is only acceptable if we're on the very last + // empty segment of a file with a trailing slash. + // a/* should match a/b/ + var emptyFileEnd = (fi === fl - 1) && (file[fi] === '') + return emptyFileEnd } + + // should be unreachable. + throw new Error('wtf?') } -module.exports.checkStream = checkStream -function checkStream (stream, sri, opts) { - opts = opts || {} - const P = opts.Promise || Promise - const checker = integrityStream(Object.assign({}, opts, { - integrity: sri - })) - return new P((resolve, reject) => { - stream.pipe(checker) - stream.on('error', reject) - checker.on('error', reject) - let sri - checker.on('verified', s => { sri = s }) - checker.on('end', () => resolve(sri)) - checker.on('data', () => {}) - }) +// replace stuff like \* with * +function globUnescape (s) { + return s.replace(/\\(.)/g, '$1') } -module.exports.integrityStream = integrityStream -function integrityStream (opts) { - opts = opts || {} - // For verification - const sri = opts.integrity && parse(opts.integrity, opts) - const goodSri = sri && Object.keys(sri).length - const algorithm = goodSri && sri.pickAlgorithm(opts) - const digests = goodSri && sri[algorithm] - // Calculating stream - const algorithms = Array.from( - new Set( - (opts.algorithms || ['sha512']) - .concat(algorithm ? [algorithm] : []) - ) - ) - const hashes = algorithms.map(crypto.createHash) - let streamSize = 0 - const stream = new Transform({ - transform (chunk, enc, cb) { - streamSize += chunk.length - hashes.forEach(h => h.update(chunk, enc)) - cb(null, chunk, enc) - } - }).on('end', () => { - const optString = (opts.options && opts.options.length) - ? `?${opts.options.join('?')}` - : '' - const newSri = parse(hashes.map((h, i) => { - return `${algorithms[i]}-${h.digest('base64')}${optString}` - }).join(' '), opts) - // Integrity verification mode - const match = goodSri && newSri.match(sri, opts) - if (typeof opts.size === 'number' && streamSize !== opts.size) { - const err = new Error(`stream size mismatch when checking ${sri}.\n Wanted: ${opts.size}\n Found: ${streamSize}`) - err.code = 'EBADSIZE' - err.found = streamSize - err.expected = opts.size - err.sri = sri - stream.emit('error', err) - } else if (opts.integrity && !match) { - const err = new Error(`${sri} integrity checksum failed when using ${algorithm}: wanted ${digests} but got ${newSri}. (${streamSize} bytes)`) - err.code = 'EINTEGRITY' - err.found = newSri - err.expected = digests - err.algorithm = algorithm - err.sri = sri - stream.emit('error', err) - } else { - stream.emit('size', streamSize) - stream.emit('integrity', newSri) - match && stream.emit('verified', match) - } - }) - return stream +function regExpEscape (s) { + return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') } -module.exports.create = createIntegrity -function createIntegrity (opts) { - opts = opts || {} - const algorithms = opts.algorithms || ['sha512'] - const optString = opts.options && opts.options.length - ? `?${opts.options.join('?')}` - : '' - const hashes = algorithms.map(crypto.createHash) +/***/ }), +/* 61 */ +/***/ (function(module, exports, __webpack_require__) { - return { - update: function (chunk, enc) { - hashes.forEach(h => h.update(chunk, enc)) - return this +var wrappy = __webpack_require__(123) +module.exports = wrappy(once) +module.exports.strict = wrappy(onceStrict) + +once.proto = once(function () { + Object.defineProperty(Function.prototype, 'once', { + value: function () { + return once(this) }, - digest: function (enc) { - const integrity = algorithms.reduce((acc, algo) => { - const digest = hashes.shift().digest('base64') - const hash = new Hash( - `${algo}-${digest}${optString}`, - opts - ) - if (hash.algorithm && hash.digest) { - const algo = hash.algorithm - if (!acc[algo]) { acc[algo] = [] } - acc[algo].push(hash) - } - return acc - }, new Integrity()) + configurable: true + }) - return integrity - } + Object.defineProperty(Function.prototype, 'onceStrict', { + value: function () { + return onceStrict(this) + }, + configurable: true + }) +}) + +function once (fn) { + var f = function () { + if (f.called) return f.value + f.called = true + return f.value = fn.apply(this, arguments) } + f.called = false + return f } -const NODE_HASHES = new Set(crypto.getHashes()) +function onceStrict (fn) { + var f = function () { + if (f.called) + throw new Error(f.onceError) + f.called = true + return f.value = fn.apply(this, arguments) + } + var name = fn.name || 'Function wrapped with `once`' + f.onceError = name + " shouldn't be called more than once" + f.called = false + return f +} -// This is a Best Effort™ at a reasonable priority for hash algos -const DEFAULT_PRIORITY = [ - 'md5', 'whirlpool', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512', - // TODO - it's unclear _which_ of these Node will actually use as its name - // for the algorithm, so we guesswork it based on the OpenSSL names. - 'sha3', - 'sha3-256', 'sha3-384', 'sha3-512', - 'sha3_256', 'sha3_384', 'sha3_512' -].filter(algo => NODE_HASHES.has(algo)) -function getPrioritizedHash (algo1, algo2) { - return DEFAULT_PRIORITY.indexOf(algo1.toLowerCase()) >= DEFAULT_PRIORITY.indexOf(algo2.toLowerCase()) - ? algo1 - : algo2 -} +/***/ }), +/* 62 */, +/* 63 */ +/***/ (function(module, exports) { +module.exports = __webpack_require__(285); /***/ }), -/* 56 */, -/* 57 */, -/* 58 */, -/* 59 */, -/* 60 */ -/***/ (function(module, exports, __webpack_require__) { +/* 64 */, +/* 65 */, +/* 66 */, +/* 67 */ +/***/ (function(module, exports) { -module.exports = minimatch -minimatch.Minimatch = Minimatch +// 7.2.1 RequireObjectCoercible(argument) +module.exports = function (it) { + if (it == undefined) throw TypeError("Can't call method on " + it); + return it; +}; -var path = { sep: '/' } -try { - path = __webpack_require__(0) -} catch (er) {} -var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {} -var expand = __webpack_require__(175) +/***/ }), +/* 68 */ +/***/ (function(module, exports, __webpack_require__) { -var plTypes = { - '!': { open: '(?:(?!(?:', close: '))[^/]*?)'}, - '?': { open: '(?:', close: ')?' }, - '+': { open: '(?:', close: ')+' }, - '*': { open: '(?:', close: ')*' }, - '@': { open: '(?:', close: ')' } -} +var isObject = __webpack_require__(34); +var document = __webpack_require__(11).document; +// typeof document.createElement is 'object' in old IE +var is = isObject(document) && isObject(document.createElement); +module.exports = function (it) { + return is ? document.createElement(it) : {}; +}; -// any single thing other than / -// don't need to escape / when using new RegExp() -var qmark = '[^/]' -// * => any number of characters -var star = qmark + '*?' +/***/ }), +/* 69 */ +/***/ (function(module, exports) { -// ** when dots are allowed. Anything goes, except .. and . -// not (^ or / followed by one or two dots followed by $ or /), -// followed by anything, any number of times. -var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?' +module.exports = true; -// not a ^ or / followed by a dot, -// followed by anything, any number of times. -var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?' -// characters that need to be escaped in RegExp. -var reSpecials = charSet('().*{}+?[]^$\\!') +/***/ }), +/* 70 */ +/***/ (function(module, exports, __webpack_require__) { -// "abc" -> { a:true, b:true, c:true } -function charSet (s) { - return s.split('').reduce(function (set, c) { - set[c] = true - return set - }, {}) -} +"use strict"; -// normalizes slashes. -var slashSplit = /\/+/ +// 25.4.1.5 NewPromiseCapability(C) +var aFunction = __webpack_require__(46); -minimatch.filter = filter -function filter (pattern, options) { - options = options || {} - return function (p, i, list) { - return minimatch(p, pattern, options) - } +function PromiseCapability(C) { + var resolve, reject; + this.promise = new C(function ($$resolve, $$reject) { + if (resolve !== undefined || reject !== undefined) throw TypeError('Bad Promise constructor'); + resolve = $$resolve; + reject = $$reject; + }); + this.resolve = aFunction(resolve); + this.reject = aFunction(reject); } -function ext (a, b) { - a = a || {} - b = b || {} - var t = {} - Object.keys(b).forEach(function (k) { - t[k] = b[k] - }) - Object.keys(a).forEach(function (k) { - t[k] = a[k] - }) - return t -} +module.exports.f = function (C) { + return new PromiseCapability(C); +}; -minimatch.defaults = function (def) { - if (!def || !Object.keys(def).length) return minimatch - var orig = minimatch +/***/ }), +/* 71 */ +/***/ (function(module, exports, __webpack_require__) { - var m = function minimatch (p, pattern, options) { - return orig.minimatch(p, pattern, ext(def, options)) - } +var def = __webpack_require__(50).f; +var has = __webpack_require__(49); +var TAG = __webpack_require__(13)('toStringTag'); - m.Minimatch = function Minimatch (pattern, options) { - return new orig.Minimatch(pattern, ext(def, options)) - } +module.exports = function (it, tag, stat) { + if (it && !has(it = stat ? it : it.prototype, TAG)) def(it, TAG, { configurable: true, value: tag }); +}; - return m -} -Minimatch.defaults = function (def) { - if (!def || !Object.keys(def).length) return Minimatch - return minimatch.defaults(def).Minimatch -} +/***/ }), +/* 72 */ +/***/ (function(module, exports, __webpack_require__) { -function minimatch (p, pattern, options) { - if (typeof pattern !== 'string') { - throw new TypeError('glob pattern string required') - } +var shared = __webpack_require__(107)('keys'); +var uid = __webpack_require__(111); +module.exports = function (key) { + return shared[key] || (shared[key] = uid(key)); +}; - if (!options) options = {} - // shortcut: comments match nothing. - if (!options.nocomment && pattern.charAt(0) === '#') { - return false - } +/***/ }), +/* 73 */ +/***/ (function(module, exports) { - // "" only matches "" - if (pattern.trim() === '') return p === '' +// 7.1.4 ToInteger +var ceil = Math.ceil; +var floor = Math.floor; +module.exports = function (it) { + return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it); +}; - return new Minimatch(pattern, options).match(p) -} -function Minimatch (pattern, options) { - if (!(this instanceof Minimatch)) { - return new Minimatch(pattern, options) - } +/***/ }), +/* 74 */ +/***/ (function(module, exports, __webpack_require__) { - if (typeof pattern !== 'string') { - throw new TypeError('glob pattern string required') - } +// to indexed object, toObject with fallback for non-array-like ES3 strings +var IObject = __webpack_require__(131); +var defined = __webpack_require__(67); +module.exports = function (it) { + return IObject(defined(it)); +}; - if (!options) options = {} - pattern = pattern.trim() - // windows support: need to use /, not \ - if (path.sep !== '/') { - pattern = pattern.split(path.sep).join('/') - } +/***/ }), +/* 75 */ +/***/ (function(module, exports, __webpack_require__) { - this.options = options - this.set = [] - this.pattern = pattern - this.regexp = null - this.negate = false - this.comment = false - this.empty = false +// Approach: +// +// 1. Get the minimatch set +// 2. For each pattern in the set, PROCESS(pattern, false) +// 3. Store matches per-set, then uniq them +// +// PROCESS(pattern, inGlobStar) +// Get the first [n] items from pattern that are all strings +// Join these together. This is PREFIX. +// If there is no more remaining, then stat(PREFIX) and +// add to matches if it succeeds. END. +// +// If inGlobStar and PREFIX is symlink and points to dir +// set ENTRIES = [] +// else readdir(PREFIX) as ENTRIES +// If fail, END +// +// with ENTRIES +// If pattern[n] is GLOBSTAR +// // handle the case where the globstar match is empty +// // by pruning it out, and testing the resulting pattern +// PROCESS(pattern[0..n] + pattern[n+1 .. $], false) +// // handle other cases. +// for ENTRY in ENTRIES (not dotfiles) +// // attach globstar + tail onto the entry +// // Mark that this entry is a globstar match +// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $], true) +// +// else // not globstar +// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot) +// Test ENTRY against pattern[n] +// If fails, continue +// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $]) +// +// Caveat: +// Cache all stats and readdirs results to minimize syscall. Since all +// we ever care about is existence and directory-ness, we can just keep +// `true` for files, and [children,...] for directories, or `false` for +// things that don't exist. - // make the set of regexps etc. - this.make() -} +module.exports = glob -Minimatch.prototype.debug = function () {} +var fs = __webpack_require__(3) +var rp = __webpack_require__(114) +var minimatch = __webpack_require__(60) +var Minimatch = minimatch.Minimatch +var inherits = __webpack_require__(42) +var EE = __webpack_require__(54).EventEmitter +var path = __webpack_require__(0) +var assert = __webpack_require__(22) +var isAbsolute = __webpack_require__(76) +var globSync = __webpack_require__(218) +var common = __webpack_require__(115) +var alphasort = common.alphasort +var alphasorti = common.alphasorti +var setopts = common.setopts +var ownProp = common.ownProp +var inflight = __webpack_require__(223) +var util = __webpack_require__(2) +var childrenIgnored = common.childrenIgnored +var isIgnored = common.isIgnored -Minimatch.prototype.make = make -function make () { - // don't do it more than once. - if (this._made) return +var once = __webpack_require__(61) - var pattern = this.pattern - var options = this.options +function glob (pattern, options, cb) { + if (typeof options === 'function') cb = options, options = {} + if (!options) options = {} - // empty patterns and comments match nothing. - if (!options.nocomment && pattern.charAt(0) === '#') { - this.comment = true - return - } - if (!pattern) { - this.empty = true - return + if (options.sync) { + if (cb) + throw new TypeError('callback provided to sync glob') + return globSync(pattern, options) } - // step 1: figure out negation, etc. - this.parseNegate() + return new Glob(pattern, options, cb) +} - // step 2: expand braces - var set = this.globSet = this.braceExpand() +glob.sync = globSync +var GlobSync = glob.GlobSync = globSync.GlobSync - if (options.debug) this.debug = console.error +// old api surface +glob.glob = glob - this.debug(this.pattern, set) +function extend (origin, add) { + if (add === null || typeof add !== 'object') { + return origin + } - // step 3: now we have a set, so turn each one into a series of path-portion - // matching patterns. - // These will be regexps, except in the case of "**", which is - // set to the GLOBSTAR object for globstar behavior, - // and will not contain any / characters - set = this.globParts = set.map(function (s) { - return s.split(slashSplit) - }) + var keys = Object.keys(add) + var i = keys.length + while (i--) { + origin[keys[i]] = add[keys[i]] + } + return origin +} - this.debug(this.pattern, set) +glob.hasMagic = function (pattern, options_) { + var options = extend({}, options_) + options.noprocess = true - // glob --> regexps - set = set.map(function (s, si, set) { - return s.map(this.parse, this) - }, this) + var g = new Glob(pattern, options) + var set = g.minimatch.set - this.debug(this.pattern, set) + if (!pattern) + return false - // filter out everything that didn't compile properly. - set = set.filter(function (s) { - return s.indexOf(false) === -1 - }) + if (set.length > 1) + return true - this.debug(this.pattern, set) + for (var j = 0; j < set[0].length; j++) { + if (typeof set[0][j] !== 'string') + return true + } - this.set = set + return false } -Minimatch.prototype.parseNegate = parseNegate -function parseNegate () { - var pattern = this.pattern - var negate = false - var options = this.options - var negateOffset = 0 - - if (options.nonegate) return - - for (var i = 0, l = pattern.length - ; i < l && pattern.charAt(i) === '!' - ; i++) { - negate = !negate - negateOffset++ +glob.Glob = Glob +inherits(Glob, EE) +function Glob (pattern, options, cb) { + if (typeof options === 'function') { + cb = options + options = null } - if (negateOffset) this.pattern = pattern.substr(negateOffset) - this.negate = negate -} - -// Brace expansion: -// a{b,c}d -> abd acd -// a{b,}c -> abc ac -// a{0..3}d -> a0d a1d a2d a3d -// a{b,c{d,e}f}g -> abg acdfg acefg -// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg -// -// Invalid sets are not expanded. -// a{2..}b -> a{2..}b -// a{b}c -> a{b}c -minimatch.braceExpand = function (pattern, options) { - return braceExpand(pattern, options) -} + if (options && options.sync) { + if (cb) + throw new TypeError('callback provided to sync glob') + return new GlobSync(pattern, options) + } -Minimatch.prototype.braceExpand = braceExpand + if (!(this instanceof Glob)) + return new Glob(pattern, options, cb) -function braceExpand (pattern, options) { - if (!options) { - if (this instanceof Minimatch) { - options = this.options - } else { - options = {} - } - } + setopts(this, pattern, options) + this._didRealPath = false - pattern = typeof pattern === 'undefined' - ? this.pattern : pattern + // process each pattern in the minimatch set + var n = this.minimatch.set.length - if (typeof pattern === 'undefined') { - throw new TypeError('undefined pattern') - } + // The matches are stored as {: true,...} so that + // duplicates are automagically pruned. + // Later, we do an Object.keys() on these. + // Keep them as a list so we can fill in when nonull is set. + this.matches = new Array(n) - if (options.nobrace || - !pattern.match(/\{.*\}/)) { - // shortcut. no need to expand. - return [pattern] + if (typeof cb === 'function') { + cb = once(cb) + this.on('error', cb) + this.on('end', function (matches) { + cb(null, matches) + }) } - return expand(pattern) -} + var self = this + this._processing = 0 -// parse a component of the expanded set. -// At this point, no pattern may contain "/" in it -// so we're going to return a 2d array, where each entry is the full -// pattern, split on '/', and then turned into a regular expression. -// A regexp is made at the end which joins each array with an -// escaped /, and another full one which joins each regexp with |. -// -// Following the lead of Bash 4.1, note that "**" only has special meaning -// when it is the *only* thing in a path portion. Otherwise, any series -// of * is equivalent to a single *. Globstar behavior is enabled by -// default, and can be disabled by setting options.noglobstar. -Minimatch.prototype.parse = parse -var SUBPARSE = {} -function parse (pattern, isSub) { - if (pattern.length > 1024 * 64) { - throw new TypeError('pattern is too long') - } + this._emitQueue = [] + this._processQueue = [] + this.paused = false - var options = this.options + if (this.noprocess) + return this - // shortcuts - if (!options.noglobstar && pattern === '**') return GLOBSTAR - if (pattern === '') return '' + if (n === 0) + return done() - var re = '' - var hasMagic = !!options.nocase - var escaping = false - // ? => one single character - var patternListStack = [] - var negativeLists = [] - var stateChar - var inClass = false - var reClassStart = -1 - var classStart = -1 - // . and .. never match anything that doesn't start with ., - // even when options.dot is set. - var patternStart = pattern.charAt(0) === '.' ? '' // anything - // not (start or / followed by . or .. followed by / or end) - : options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))' - : '(?!\\.)' - var self = this + var sync = true + for (var i = 0; i < n; i ++) { + this._process(this.minimatch.set[i], i, false, done) + } + sync = false - function clearStateChar () { - if (stateChar) { - // we had some state-tracking character - // that wasn't consumed by this pass. - switch (stateChar) { - case '*': - re += star - hasMagic = true - break - case '?': - re += qmark - hasMagic = true - break - default: - re += '\\' + stateChar - break + function done () { + --self._processing + if (self._processing <= 0) { + if (sync) { + process.nextTick(function () { + self._finish() + }) + } else { + self._finish() } - self.debug('clearStateChar %j %j', stateChar, re) - stateChar = false } } +} - for (var i = 0, len = pattern.length, c - ; (i < len) && (c = pattern.charAt(i)) - ; i++) { - this.debug('%s\t%s %s %j', pattern, i, re, c) +Glob.prototype._finish = function () { + assert(this instanceof Glob) + if (this.aborted) + return - // skip over any that are escaped. - if (escaping && reSpecials[c]) { - re += '\\' + c - escaping = false - continue - } + if (this.realpath && !this._didRealpath) + return this._realpath() - switch (c) { - case '/': - // completely not allowed, even escaped. - // Should already be path-split by now. - return false + common.finish(this) + this.emit('end', this.found) +} - case '\\': - clearStateChar() - escaping = true - continue +Glob.prototype._realpath = function () { + if (this._didRealpath) + return - // the various stateChar values - // for the "extglob" stuff. - case '?': - case '*': - case '+': - case '@': - case '!': - this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c) + this._didRealpath = true - // all of those are literals inside a class, except that - // the glob [!a] means [^a] in regexp - if (inClass) { - this.debug(' in class') - if (c === '!' && i === classStart + 1) c = '^' - re += c - continue - } + var n = this.matches.length + if (n === 0) + return this._finish() - // if we already have a stateChar, then it means - // that there was something like ** or +? in there. - // Handle the stateChar, then proceed with this one. - self.debug('call clearStateChar %j', stateChar) - clearStateChar() - stateChar = c - // if extglob is disabled, then +(asdf|foo) isn't a thing. - // just clear the statechar *now*, rather than even diving into - // the patternList stuff. - if (options.noext) clearStateChar() - continue + var self = this + for (var i = 0; i < this.matches.length; i++) + this._realpathSet(i, next) - case '(': - if (inClass) { - re += '(' - continue - } + function next () { + if (--n === 0) + self._finish() + } +} - if (!stateChar) { - re += '\\(' - continue - } +Glob.prototype._realpathSet = function (index, cb) { + var matchset = this.matches[index] + if (!matchset) + return cb() - patternListStack.push({ - type: stateChar, - start: i - 1, - reStart: re.length, - open: plTypes[stateChar].open, - close: plTypes[stateChar].close - }) - // negation is (?:(?!js)[^/]*) - re += stateChar === '!' ? '(?:(?!(?:' : '(?:' - this.debug('plType %j %j', stateChar, re) - stateChar = false - continue + var found = Object.keys(matchset) + var self = this + var n = found.length - case ')': - if (inClass || !patternListStack.length) { - re += '\\)' - continue - } + if (n === 0) + return cb() - clearStateChar() - hasMagic = true - var pl = patternListStack.pop() - // negation is (?:(?!js)[^/]*) - // The others are (?:) - re += pl.close - if (pl.type === '!') { - negativeLists.push(pl) - } - pl.reEnd = re.length - continue + var set = this.matches[index] = Object.create(null) + found.forEach(function (p, i) { + // If there's a problem with the stat, then it means that + // one or more of the links in the realpath couldn't be + // resolved. just return the abs value in that case. + p = self._makeAbs(p) + rp.realpath(p, self.realpathCache, function (er, real) { + if (!er) + set[real] = true + else if (er.syscall === 'stat') + set[p] = true + else + self.emit('error', er) // srsly wtf right here - case '|': - if (inClass || !patternListStack.length || escaping) { - re += '\\|' - escaping = false - continue - } + if (--n === 0) { + self.matches[index] = set + cb() + } + }) + }) +} - clearStateChar() - re += '|' - continue +Glob.prototype._mark = function (p) { + return common.mark(this, p) +} - // these are mostly the same in regexp and glob - case '[': - // swallow any state-tracking char before the [ - clearStateChar() +Glob.prototype._makeAbs = function (f) { + return common.makeAbs(this, f) +} - if (inClass) { - re += '\\' + c - continue - } +Glob.prototype.abort = function () { + this.aborted = true + this.emit('abort') +} - inClass = true - classStart = i - reClassStart = re.length - re += c - continue +Glob.prototype.pause = function () { + if (!this.paused) { + this.paused = true + this.emit('pause') + } +} - case ']': - // a right bracket shall lose its special - // meaning and represent itself in - // a bracket expression if it occurs - // first in the list. -- POSIX.2 2.8.3.2 - if (i === classStart + 1 || !inClass) { - re += '\\' + c - escaping = false - continue - } +Glob.prototype.resume = function () { + if (this.paused) { + this.emit('resume') + this.paused = false + if (this._emitQueue.length) { + var eq = this._emitQueue.slice(0) + this._emitQueue.length = 0 + for (var i = 0; i < eq.length; i ++) { + var e = eq[i] + this._emitMatch(e[0], e[1]) + } + } + if (this._processQueue.length) { + var pq = this._processQueue.slice(0) + this._processQueue.length = 0 + for (var i = 0; i < pq.length; i ++) { + var p = pq[i] + this._processing-- + this._process(p[0], p[1], p[2], p[3]) + } + } + } +} - // handle the case where we left a class open. - // "[z-a]" is valid, equivalent to "\[z-a\]" - if (inClass) { - // split where the last [ was, make sure we don't have - // an invalid re. if so, re-walk the contents of the - // would-be class to re-translate any characters that - // were passed through as-is - // TODO: It would probably be faster to determine this - // without a try/catch and a new RegExp, but it's tricky - // to do safely. For now, this is safe and works. - var cs = pattern.substring(classStart + 1, i) - try { - RegExp('[' + cs + ']') - } catch (er) { - // not a valid class! - var sp = this.parse(cs, SUBPARSE) - re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]' - hasMagic = hasMagic || sp[1] - inClass = false - continue - } - } +Glob.prototype._process = function (pattern, index, inGlobStar, cb) { + assert(this instanceof Glob) + assert(typeof cb === 'function') - // finish up the class. - hasMagic = true - inClass = false - re += c - continue + if (this.aborted) + return - default: - // swallow any state char that wasn't consumed - clearStateChar() + this._processing++ + if (this.paused) { + this._processQueue.push([pattern, index, inGlobStar, cb]) + return + } - if (escaping) { - // no need - escaping = false - } else if (reSpecials[c] - && !(c === '^' && inClass)) { - re += '\\' - } + //console.error('PROCESS %d', this._processing, pattern) - re += c + // Get the first [n] parts of pattern that are all strings. + var n = 0 + while (typeof pattern[n] === 'string') { + n ++ + } + // now n is the index of the first one that is *not* a string. - } // switch - } // for + // see if there's anything else + var prefix + switch (n) { + // if not, then this is rather simple + case pattern.length: + this._processSimple(pattern.join('/'), index, cb) + return - // handle the case where we left a class open. - // "[abc" is valid, equivalent to "\[abc" - if (inClass) { - // split where the last [ was, and escape it - // this is a huge pita. We now have to re-walk - // the contents of the would-be class to re-translate - // any characters that were passed through as-is - cs = pattern.substr(classStart + 1) - sp = this.parse(cs, SUBPARSE) - re = re.substr(0, reClassStart) + '\\[' + sp[0] - hasMagic = hasMagic || sp[1] - } + case 0: + // pattern *starts* with some non-trivial item. + // going to readdir(cwd), but not include the prefix in matches. + prefix = null + break - // handle the case where we had a +( thing at the *end* - // of the pattern. - // each pattern list stack adds 3 chars, and we need to go through - // and escape any | chars that were passed through as-is for the regexp. - // Go through and escape them, taking care not to double-escape any - // | chars that were already escaped. - for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) { - var tail = re.slice(pl.reStart + pl.open.length) - this.debug('setting tail', re, pl) - // maybe some even number of \, then maybe 1 \, followed by a | - tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, function (_, $1, $2) { - if (!$2) { - // the | isn't already escaped, so escape it. - $2 = '\\' - } + default: + // pattern has some string bits in the front. + // whatever it starts with, whether that's 'absolute' like /foo/bar, + // or 'relative' like '../baz' + prefix = pattern.slice(0, n).join('/') + break + } - // need to escape all those slashes *again*, without escaping the - // one that we need for escaping the | character. As it works out, - // escaping an even number of slashes can be done by simply repeating - // it exactly after itself. That's why this trick works. - // - // I am sorry that you have to see this. - return $1 + $1 + $2 + '|' - }) + var remain = pattern.slice(n) - this.debug('tail=%j\n %s', tail, tail, pl, re) - var t = pl.type === '*' ? star - : pl.type === '?' ? qmark - : '\\' + pl.type + // get the list of entries. + var read + if (prefix === null) + read = '.' + else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { + if (!prefix || !isAbsolute(prefix)) + prefix = '/' + prefix + read = prefix + } else + read = prefix - hasMagic = true - re = re.slice(0, pl.reStart) + t + '\\(' + tail - } + var abs = this._makeAbs(read) - // handle trailing things that only matter at the very end. - clearStateChar() - if (escaping) { - // trailing \\ - re += '\\\\' - } + //if ignored, skip _processing + if (childrenIgnored(this, read)) + return cb() - // only need to apply the nodot start if the re starts with - // something that could conceivably capture a dot - var addPatternStart = false - switch (re.charAt(0)) { - case '.': - case '[': - case '(': addPatternStart = true - } + var isGlobStar = remain[0] === minimatch.GLOBSTAR + if (isGlobStar) + this._processGlobStar(prefix, read, abs, remain, index, inGlobStar, cb) + else + this._processReaddir(prefix, read, abs, remain, index, inGlobStar, cb) +} - // Hack to work around lack of negative lookbehind in JS - // A pattern like: *.!(x).!(y|z) needs to ensure that a name - // like 'a.xyz.yz' doesn't match. So, the first negative - // lookahead, has to look ALL the way ahead, to the end of - // the pattern. - for (var n = negativeLists.length - 1; n > -1; n--) { - var nl = negativeLists[n] +Glob.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar, cb) { + var self = this + this._readdir(abs, inGlobStar, function (er, entries) { + return self._processReaddir2(prefix, read, abs, remain, index, inGlobStar, entries, cb) + }) +} - var nlBefore = re.slice(0, nl.reStart) - var nlFirst = re.slice(nl.reStart, nl.reEnd - 8) - var nlLast = re.slice(nl.reEnd - 8, nl.reEnd) - var nlAfter = re.slice(nl.reEnd) +Glob.prototype._processReaddir2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { - nlLast += nlAfter + // if the abs isn't a dir, then nothing can match! + if (!entries) + return cb() - // Handle nested stuff like *(*.js|!(*.json)), where open parens - // mean that we should *not* include the ) in the bit that is considered - // "after" the negated section. - var openParensBefore = nlBefore.split('(').length - 1 - var cleanAfter = nlAfter - for (i = 0; i < openParensBefore; i++) { - cleanAfter = cleanAfter.replace(/\)[+*?]?/, '') - } - nlAfter = cleanAfter + // It will only match dot entries if it starts with a dot, or if + // dot is set. Stuff like @(.foo|.bar) isn't allowed. + var pn = remain[0] + var negate = !!this.minimatch.negate + var rawGlob = pn._glob + var dotOk = this.dot || rawGlob.charAt(0) === '.' - var dollar = '' - if (nlAfter === '' && isSub !== SUBPARSE) { - dollar = '$' + var matchedEntries = [] + for (var i = 0; i < entries.length; i++) { + var e = entries[i] + if (e.charAt(0) !== '.' || dotOk) { + var m + if (negate && !prefix) { + m = !e.match(pn) + } else { + m = e.match(pn) + } + if (m) + matchedEntries.push(e) } - var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast - re = newRe - } - - // if the re is not "" at this point, then we need to make sure - // it doesn't match against an empty path part. - // Otherwise a/* will match a/, which it should not. - if (re !== '' && hasMagic) { - re = '(?=.)' + re } - if (addPatternStart) { - re = patternStart + re - } + //console.error('prd2', prefix, entries, remain[0]._glob, matchedEntries) - // parsing just a piece of a larger pattern. - if (isSub === SUBPARSE) { - return [re, hasMagic] - } + var len = matchedEntries.length + // If there are no matched entries, then nothing matches. + if (len === 0) + return cb() - // skip the regexp for non-magical patterns - // unescape anything in it, though, so that it'll be - // an exact match against a file etc. - if (!hasMagic) { - return globUnescape(pattern) - } + // if this is the last remaining pattern bit, then no need for + // an additional stat *unless* the user has specified mark or + // stat explicitly. We know they exist, since readdir returned + // them. - var flags = options.nocase ? 'i' : '' - try { - var regExp = new RegExp('^' + re + '$', flags) - } catch (er) { - // If it was an invalid regular expression, then it can't match - // anything. This trick looks for a character after the end of - // the string, which is of course impossible, except in multi-line - // mode, but it's not a /m regex. - return new RegExp('$.') - } + if (remain.length === 1 && !this.mark && !this.stat) { + if (!this.matches[index]) + this.matches[index] = Object.create(null) - regExp._glob = pattern - regExp._src = re + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + if (prefix) { + if (prefix !== '/') + e = prefix + '/' + e + else + e = prefix + e + } - return regExp -} + if (e.charAt(0) === '/' && !this.nomount) { + e = path.join(this.root, e) + } + this._emitMatch(index, e) + } + // This was the last one, and no stats were needed + return cb() + } -minimatch.makeRe = function (pattern, options) { - return new Minimatch(pattern, options || {}).makeRe() + // now test all matched entries as stand-ins for that part + // of the pattern. + remain.shift() + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + var newPattern + if (prefix) { + if (prefix !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + this._process([e].concat(remain), index, inGlobStar, cb) + } + cb() } -Minimatch.prototype.makeRe = makeRe -function makeRe () { - if (this.regexp || this.regexp === false) return this.regexp +Glob.prototype._emitMatch = function (index, e) { + if (this.aborted) + return - // at this point, this.set is a 2d array of partial - // pattern strings, or "**". - // - // It's better to use .match(). This function shouldn't - // be used, really, but it's pretty convenient sometimes, - // when you just want to work with a regex. - var set = this.set + if (isIgnored(this, e)) + return - if (!set.length) { - this.regexp = false - return this.regexp + if (this.paused) { + this._emitQueue.push([index, e]) + return } - var options = this.options - var twoStar = options.noglobstar ? star - : options.dot ? twoStarDot - : twoStarNoDot - var flags = options.nocase ? 'i' : '' + var abs = isAbsolute(e) ? e : this._makeAbs(e) - var re = set.map(function (pattern) { - return pattern.map(function (p) { - return (p === GLOBSTAR) ? twoStar - : (typeof p === 'string') ? regExpEscape(p) - : p._src - }).join('\\\/') - }).join('|') + if (this.mark) + e = this._mark(e) - // must match entire pattern - // ending in a * or ** will make it less strict. - re = '^(?:' + re + ')$' + if (this.absolute) + e = abs - // can match anything, as long as it's not this. - if (this.negate) re = '^(?!' + re + ').*$' + if (this.matches[index][e]) + return - try { - this.regexp = new RegExp(re, flags) - } catch (ex) { - this.regexp = false + if (this.nodir) { + var c = this.cache[abs] + if (c === 'DIR' || Array.isArray(c)) + return } - return this.regexp -} -minimatch.match = function (list, pattern, options) { - options = options || {} - var mm = new Minimatch(pattern, options) - list = list.filter(function (f) { - return mm.match(f) - }) - if (mm.options.nonull && !list.length) { - list.push(pattern) - } - return list + this.matches[index][e] = true + + var st = this.statCache[abs] + if (st) + this.emit('stat', e, st) + + this.emit('match', e) } -Minimatch.prototype.match = match -function match (f, partial) { - this.debug('match', f, this.pattern) - // short-circuit in the case of busted things. - // comments, etc. - if (this.comment) return false - if (this.empty) return f === '' +Glob.prototype._readdirInGlobStar = function (abs, cb) { + if (this.aborted) + return - if (f === '/' && partial) return true + // follow all symlinked directories forever + // just proceed as if this is a non-globstar situation + if (this.follow) + return this._readdir(abs, false, cb) - var options = this.options + var lstatkey = 'lstat\0' + abs + var self = this + var lstatcb = inflight(lstatkey, lstatcb_) - // windows: need to use /, not \ - if (path.sep !== '/') { - f = f.split(path.sep).join('/') - } + if (lstatcb) + fs.lstat(abs, lstatcb) - // treat the test path as a set of pathparts. - f = f.split(slashSplit) - this.debug(this.pattern, 'split', f) + function lstatcb_ (er, lstat) { + if (er && er.code === 'ENOENT') + return cb() - // just ONE of the pattern sets in this.set needs to match - // in order for it to be valid. If negating, then just one - // match means that we have failed. - // Either way, return on the first hit. - - var set = this.set - this.debug(this.pattern, 'set', set) - - // Find the basename of the path by looking for the last non-empty segment - var filename - var i - for (i = f.length - 1; i >= 0; i--) { - filename = f[i] - if (filename) break - } + var isSym = lstat && lstat.isSymbolicLink() + self.symlinks[abs] = isSym - for (i = 0; i < set.length; i++) { - var pattern = set[i] - var file = f - if (options.matchBase && pattern.length === 1) { - file = [filename] - } - var hit = this.matchOne(file, pattern, partial) - if (hit) { - if (options.flipNegate) return true - return !this.negate - } + // If it's not a symlink or a dir, then it's definitely a regular file. + // don't bother doing a readdir in that case. + if (!isSym && lstat && !lstat.isDirectory()) { + self.cache[abs] = 'FILE' + cb() + } else + self._readdir(abs, false, cb) } - - // didn't get any hits. this is success if it's a negative - // pattern, failure otherwise. - if (options.flipNegate) return false - return this.negate } -// set partial to true to test if, for example, -// "/a/b" matches the start of "/*/b/*/d" -// Partial means, if you run out of file before you run -// out of pattern, then that's fine, as long as all -// the parts match. -Minimatch.prototype.matchOne = function (file, pattern, partial) { - var options = this.options +Glob.prototype._readdir = function (abs, inGlobStar, cb) { + if (this.aborted) + return - this.debug('matchOne', - { 'this': this, file: file, pattern: pattern }) + cb = inflight('readdir\0'+abs+'\0'+inGlobStar, cb) + if (!cb) + return - this.debug('matchOne', file.length, pattern.length) + //console.error('RD %j %j', +inGlobStar, abs) + if (inGlobStar && !ownProp(this.symlinks, abs)) + return this._readdirInGlobStar(abs, cb) - for (var fi = 0, - pi = 0, - fl = file.length, - pl = pattern.length - ; (fi < fl) && (pi < pl) - ; fi++, pi++) { - this.debug('matchOne loop') - var p = pattern[pi] - var f = file[fi] + if (ownProp(this.cache, abs)) { + var c = this.cache[abs] + if (!c || c === 'FILE') + return cb() - this.debug(pattern, p, f) + if (Array.isArray(c)) + return cb(null, c) + } - // should be impossible. - // some invalid regexp stuff in the set. - if (p === false) return false + var self = this + fs.readdir(abs, readdirCb(this, abs, cb)) +} - if (p === GLOBSTAR) { - this.debug('GLOBSTAR', [pattern, p, f]) +function readdirCb (self, abs, cb) { + return function (er, entries) { + if (er) + self._readdirError(abs, er, cb) + else + self._readdirEntries(abs, entries, cb) + } +} - // "**" - // a/**/b/**/c would match the following: - // a/b/x/y/z/c - // a/x/y/z/b/c - // a/b/x/b/x/c - // a/b/c - // To do this, take the rest of the pattern after - // the **, and see if it would match the file remainder. - // If so, return success. - // If not, the ** "swallows" a segment, and try again. - // This is recursively awful. - // - // a/**/b/**/c matching a/b/x/y/z/c - // - a matches a - // - doublestar - // - matchOne(b/x/y/z/c, b/**/c) - // - b matches b - // - doublestar - // - matchOne(x/y/z/c, c) -> no - // - matchOne(y/z/c, c) -> no - // - matchOne(z/c, c) -> no - // - matchOne(c, c) yes, hit - var fr = fi - var pr = pi + 1 - if (pr === pl) { - this.debug('** at the end') - // a ** at the end will just swallow the rest. - // We have found a match. - // however, it will not swallow /.x, unless - // options.dot is set. - // . and .. are *never* matched by **, for explosively - // exponential reasons. - for (; fi < fl; fi++) { - if (file[fi] === '.' || file[fi] === '..' || - (!options.dot && file[fi].charAt(0) === '.')) return false - } - return true - } +Glob.prototype._readdirEntries = function (abs, entries, cb) { + if (this.aborted) + return - // ok, let's see if we can swallow whatever we can. - while (fr < fl) { - var swallowee = file[fr] + // if we haven't asked to stat everything, then just + // assume that everything in there exists, so we can avoid + // having to stat it a second time. + if (!this.mark && !this.stat) { + for (var i = 0; i < entries.length; i ++) { + var e = entries[i] + if (abs === '/') + e = abs + e + else + e = abs + '/' + e + this.cache[e] = true + } + } - this.debug('\nglobstar while', file, fr, pattern, pr, swallowee) + this.cache[abs] = entries + return cb(null, entries) +} - // XXX remove this slice. Just pass the start index. - if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { - this.debug('globstar found match!', fr, fl, swallowee) - // found a match. - return true - } else { - // can't swallow "." or ".." ever. - // can only swallow ".foo" when explicitly asked. - if (swallowee === '.' || swallowee === '..' || - (!options.dot && swallowee.charAt(0) === '.')) { - this.debug('dot detected!', file, fr, pattern, pr) - break - } +Glob.prototype._readdirError = function (f, er, cb) { + if (this.aborted) + return - // ** swallows a segment, and continue. - this.debug('globstar swallow a segment, and continue') - fr++ - } + // handle errors, and cache the information + switch (er.code) { + case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 + case 'ENOTDIR': // totally normal. means it *does* exist. + var abs = this._makeAbs(f) + this.cache[abs] = 'FILE' + if (abs === this.cwdAbs) { + var error = new Error(er.code + ' invalid cwd ' + this.cwd) + error.path = this.cwd + error.code = er.code + this.emit('error', error) + this.abort() } + break - // no match was found. - // However, in partial mode, we can't say this is necessarily over. - // If there's more *pattern* left, then - if (partial) { - // ran out of file - this.debug('\n>>> no match, partial?', file, fr, pattern, pr) - if (fr === fl) return true - } - return false - } + case 'ENOENT': // not terribly unusual + case 'ELOOP': + case 'ENAMETOOLONG': + case 'UNKNOWN': + this.cache[this._makeAbs(f)] = false + break - // something other than ** - // non-magic patterns just have to match exactly - // patterns with magic have been turned into regexps. - var hit - if (typeof p === 'string') { - if (options.nocase) { - hit = f.toLowerCase() === p.toLowerCase() - } else { - hit = f === p + default: // some unusual error. Treat as failure. + this.cache[this._makeAbs(f)] = false + if (this.strict) { + this.emit('error', er) + // If the error is handled, then we abort + // if not, we threw out of here + this.abort() } - this.debug('string match', p, f, hit) - } else { - hit = f.match(p) - this.debug('pattern match', p, f, hit) - } - - if (!hit) return false - } - - // Note: ending in / means that we'll get a final "" - // at the end of the pattern. This can only match a - // corresponding "" at the end of the file. - // If the file ends in /, then it can only match a - // a pattern that ends in /, unless the pattern just - // doesn't have any more for it. But, a/b/ should *not* - // match "a/b/*", even though "" matches against the - // [^/]*? pattern, except in partial mode, where it might - // simply not be reached yet. - // However, a/b/ should still satisfy a/* - - // now either we fell off the end of the pattern, or we're done. - if (fi === fl && pi === pl) { - // ran out of pattern and filename at the same time. - // an exact hit! - return true - } else if (fi === fl) { - // ran out of file, but still had pattern left. - // this is ok if we're doing the match as part of - // a glob fs traversal. - return partial - } else if (pi === pl) { - // ran out of pattern, still have file left. - // this is only acceptable if we're on the very last - // empty segment of a file with a trailing slash. - // a/* should match a/b/ - var emptyFileEnd = (fi === fl - 1) && (file[fi] === '') - return emptyFileEnd + if (!this.silent) + console.error('glob error', er) + break } - // should be unreachable. - throw new Error('wtf?') + return cb() } -// replace stuff like \* with * -function globUnescape (s) { - return s.replace(/\\(.)/g, '$1') +Glob.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar, cb) { + var self = this + this._readdir(abs, inGlobStar, function (er, entries) { + self._processGlobStar2(prefix, read, abs, remain, index, inGlobStar, entries, cb) + }) } -function regExpEscape (s) { - return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') -} +Glob.prototype._processGlobStar2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { + //console.error('pgs2', prefix, remain[0], entries) -/***/ }), -/* 61 */ -/***/ (function(module, exports, __webpack_require__) { + // no entries means not a dir, so it can never have matches + // foo.txt/** doesn't match foo.txt + if (!entries) + return cb() -var wrappy = __webpack_require__(123) -module.exports = wrappy(once) -module.exports.strict = wrappy(onceStrict) + // test without the globstar, and with every child both below + // and replacing the globstar. + var remainWithoutGlobStar = remain.slice(1) + var gspref = prefix ? [ prefix ] : [] + var noGlobStar = gspref.concat(remainWithoutGlobStar) -once.proto = once(function () { - Object.defineProperty(Function.prototype, 'once', { - value: function () { - return once(this) - }, - configurable: true - }) + // the noGlobStar pattern exits the inGlobStar state + this._process(noGlobStar, index, false, cb) - Object.defineProperty(Function.prototype, 'onceStrict', { - value: function () { - return onceStrict(this) - }, - configurable: true - }) -}) + var isSym = this.symlinks[abs] + var len = entries.length -function once (fn) { - var f = function () { - if (f.called) return f.value - f.called = true - return f.value = fn.apply(this, arguments) + // If it's a symlink, and we're in a globstar, then stop + if (isSym && inGlobStar) + return cb() + + for (var i = 0; i < len; i++) { + var e = entries[i] + if (e.charAt(0) === '.' && !this.dot) + continue + + // these two cases enter the inGlobStar state + var instead = gspref.concat(entries[i], remainWithoutGlobStar) + this._process(instead, index, true, cb) + + var below = gspref.concat(entries[i], remain) + this._process(below, index, true, cb) } - f.called = false - return f + + cb() } -function onceStrict (fn) { - var f = function () { - if (f.called) - throw new Error(f.onceError) - f.called = true - return f.value = fn.apply(this, arguments) - } - var name = fn.name || 'Function wrapped with `once`' - f.onceError = name + " shouldn't be called more than once" - f.called = false - return f +Glob.prototype._processSimple = function (prefix, index, cb) { + // XXX review this. Shouldn't it be doing the mounting etc + // before doing stat? kinda weird? + var self = this + this._stat(prefix, function (er, exists) { + self._processSimple2(prefix, index, er, exists, cb) + }) } +Glob.prototype._processSimple2 = function (prefix, index, er, exists, cb) { + //console.error('ps2', prefix, exists) -/***/ }), -/* 62 */, -/* 63 */ -/***/ (function(module, exports) { + if (!this.matches[index]) + this.matches[index] = Object.create(null) -module.exports = __webpack_require__(293); + // If it doesn't exist, then just mark the lack of results + if (!exists) + return cb() -/***/ }), -/* 64 */, -/* 65 */, -/* 66 */, -/* 67 */ -/***/ (function(module, exports) { + if (prefix && isAbsolute(prefix) && !this.nomount) { + var trail = /[\/\\]$/.test(prefix) + if (prefix.charAt(0) === '/') { + prefix = path.join(this.root, prefix) + } else { + prefix = path.resolve(this.root, prefix) + if (trail) + prefix += '/' + } + } -// 7.2.1 RequireObjectCoercible(argument) -module.exports = function (it) { - if (it == undefined) throw TypeError("Can't call method on " + it); - return it; -}; + if (process.platform === 'win32') + prefix = prefix.replace(/\\/g, '/') + // Mark this as a match + this._emitMatch(index, prefix) + cb() +} -/***/ }), -/* 68 */ -/***/ (function(module, exports, __webpack_require__) { +// Returns either 'DIR', 'FILE', or false +Glob.prototype._stat = function (f, cb) { + var abs = this._makeAbs(f) + var needDir = f.slice(-1) === '/' -var isObject = __webpack_require__(34); -var document = __webpack_require__(11).document; -// typeof document.createElement is 'object' in old IE -var is = isObject(document) && isObject(document.createElement); -module.exports = function (it) { - return is ? document.createElement(it) : {}; -}; + if (f.length > this.maxLength) + return cb() + if (!this.stat && ownProp(this.cache, abs)) { + var c = this.cache[abs] -/***/ }), -/* 69 */ -/***/ (function(module, exports) { + if (Array.isArray(c)) + c = 'DIR' -module.exports = true; + // It exists, but maybe not how we need it + if (!needDir || c === 'DIR') + return cb(null, c) + if (needDir && c === 'FILE') + return cb() -/***/ }), -/* 70 */ -/***/ (function(module, exports, __webpack_require__) { + // otherwise we have to stat, because maybe c=true + // if we know it exists, but not what it is. + } -"use strict"; + var exists + var stat = this.statCache[abs] + if (stat !== undefined) { + if (stat === false) + return cb(null, stat) + else { + var type = stat.isDirectory() ? 'DIR' : 'FILE' + if (needDir && type === 'FILE') + return cb() + else + return cb(null, type, stat) + } + } -// 25.4.1.5 NewPromiseCapability(C) -var aFunction = __webpack_require__(46); + var self = this + var statcb = inflight('stat\0' + abs, lstatcb_) + if (statcb) + fs.lstat(abs, statcb) -function PromiseCapability(C) { - var resolve, reject; - this.promise = new C(function ($$resolve, $$reject) { - if (resolve !== undefined || reject !== undefined) throw TypeError('Bad Promise constructor'); - resolve = $$resolve; - reject = $$reject; - }); - this.resolve = aFunction(resolve); - this.reject = aFunction(reject); + function lstatcb_ (er, lstat) { + if (lstat && lstat.isSymbolicLink()) { + // If it's a symlink, then treat it as the target, unless + // the target does not exist, then treat it as a file. + return fs.stat(abs, function (er, stat) { + if (er) + self._stat2(f, abs, null, lstat, cb) + else + self._stat2(f, abs, er, stat, cb) + }) + } else { + self._stat2(f, abs, er, lstat, cb) + } + } } -module.exports.f = function (C) { - return new PromiseCapability(C); -}; +Glob.prototype._stat2 = function (f, abs, er, stat, cb) { + if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) { + this.statCache[abs] = false + return cb() + } + var needDir = f.slice(-1) === '/' + this.statCache[abs] = stat -/***/ }), -/* 71 */ -/***/ (function(module, exports, __webpack_require__) { + if (abs.slice(-1) === '/' && stat && !stat.isDirectory()) + return cb(null, false, stat) -var def = __webpack_require__(50).f; -var has = __webpack_require__(49); -var TAG = __webpack_require__(13)('toStringTag'); + var c = true + if (stat) + c = stat.isDirectory() ? 'DIR' : 'FILE' + this.cache[abs] = this.cache[abs] || c -module.exports = function (it, tag, stat) { - if (it && !has(it = stat ? it : it.prototype, TAG)) def(it, TAG, { configurable: true, value: tag }); -}; + if (needDir && c === 'FILE') + return cb() + + return cb(null, c, stat) +} /***/ }), -/* 72 */ +/* 76 */ /***/ (function(module, exports, __webpack_require__) { -var shared = __webpack_require__(107)('keys'); -var uid = __webpack_require__(111); -module.exports = function (key) { - return shared[key] || (shared[key] = uid(key)); -}; +"use strict"; -/***/ }), -/* 73 */ -/***/ (function(module, exports) { +function posix(path) { + return path.charAt(0) === '/'; +} -// 7.1.4 ToInteger -var ceil = Math.ceil; -var floor = Math.floor; -module.exports = function (it) { - return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it); -}; +function win32(path) { + // https://github.com/nodejs/node/blob/b3fcc245fb25539909ef1d5eaa01dbf92e168633/lib/path.js#L56 + var splitDeviceRe = /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/; + var result = splitDeviceRe.exec(path); + var device = result[1] || ''; + var isUnc = Boolean(device && device.charAt(1) !== ':'); + // UNC paths are always absolute + return Boolean(result[2] || isUnc); +} -/***/ }), -/* 74 */ -/***/ (function(module, exports, __webpack_require__) { +module.exports = process.platform === 'win32' ? win32 : posix; +module.exports.posix = posix; +module.exports.win32 = win32; -// to indexed object, toObject with fallback for non-array-like ES3 strings -var IObject = __webpack_require__(131); -var defined = __webpack_require__(67); -module.exports = function (it) { - return IObject(defined(it)); -}; +/***/ }), +/* 77 */, +/* 78 */, +/* 79 */ +/***/ (function(module, exports) { + +module.exports = __webpack_require__(121); /***/ }), -/* 75 */ +/* 80 */, +/* 81 */ /***/ (function(module, exports, __webpack_require__) { -// Approach: -// -// 1. Get the minimatch set -// 2. For each pattern in the set, PROCESS(pattern, false) -// 3. Store matches per-set, then uniq them -// -// PROCESS(pattern, inGlobStar) -// Get the first [n] items from pattern that are all strings -// Join these together. This is PREFIX. -// If there is no more remaining, then stat(PREFIX) and -// add to matches if it succeeds. END. -// -// If inGlobStar and PREFIX is symlink and points to dir -// set ENTRIES = [] -// else readdir(PREFIX) as ENTRIES -// If fail, END -// -// with ENTRIES -// If pattern[n] is GLOBSTAR -// // handle the case where the globstar match is empty -// // by pruning it out, and testing the resulting pattern -// PROCESS(pattern[0..n] + pattern[n+1 .. $], false) -// // handle other cases. -// for ENTRY in ENTRIES (not dotfiles) -// // attach globstar + tail onto the entry -// // Mark that this entry is a globstar match -// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $], true) -// -// else // not globstar -// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot) -// Test ENTRY against pattern[n] -// If fails, continue -// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $]) -// -// Caveat: -// Cache all stats and readdirs results to minimize syscall. Since all -// we ever care about is existence and directory-ness, we can just keep -// `true` for files, and [children,...] for directories, or `false` for -// things that don't exist. - -module.exports = glob +"use strict"; -var fs = __webpack_require__(3) -var rp = __webpack_require__(114) -var minimatch = __webpack_require__(60) -var Minimatch = minimatch.Minimatch -var inherits = __webpack_require__(42) -var EE = __webpack_require__(54).EventEmitter -var path = __webpack_require__(0) -var assert = __webpack_require__(22) -var isAbsolute = __webpack_require__(76) -var globSync = __webpack_require__(218) -var common = __webpack_require__(115) -var alphasort = common.alphasort -var alphasorti = common.alphasorti -var setopts = common.setopts -var ownProp = common.ownProp -var inflight = __webpack_require__(223) -var util = __webpack_require__(2) -var childrenIgnored = common.childrenIgnored -var isIgnored = common.isIgnored -var once = __webpack_require__(61) +Object.defineProperty(exports, "__esModule", { + value: true +}); -function glob (pattern, options, cb) { - if (typeof options === 'function') cb = options, options = {} - if (!options) options = {} +exports.default = function (str, fileLoc = 'lockfile') { + str = (0, (_stripBom || _load_stripBom()).default)(str); + return hasMergeConflicts(str) ? parseWithConflict(str, fileLoc) : { type: 'success', object: parse(str, fileLoc) }; +}; - if (options.sync) { - if (cb) - throw new TypeError('callback provided to sync glob') - return globSync(pattern, options) - } +var _util; - return new Glob(pattern, options, cb) +function _load_util() { + return _util = _interopRequireDefault(__webpack_require__(2)); } -glob.sync = globSync -var GlobSync = glob.GlobSync = globSync.GlobSync +var _invariant; -// old api surface -glob.glob = glob +function _load_invariant() { + return _invariant = _interopRequireDefault(__webpack_require__(7)); +} -function extend (origin, add) { - if (add === null || typeof add !== 'object') { - return origin - } +var _stripBom; - var keys = Object.keys(add) - var i = keys.length - while (i--) { - origin[keys[i]] = add[keys[i]] - } - return origin +function _load_stripBom() { + return _stripBom = _interopRequireDefault(__webpack_require__(122)); } -glob.hasMagic = function (pattern, options_) { - var options = extend({}, options_) - options.noprocess = true +var _constants; - var g = new Glob(pattern, options) - var set = g.minimatch.set +function _load_constants() { + return _constants = __webpack_require__(6); +} - if (!pattern) - return false +var _errors; - if (set.length > 1) - return true +function _load_errors() { + return _errors = __webpack_require__(4); +} - for (var j = 0; j < set[0].length; j++) { - if (typeof set[0][j] !== 'string') - return true - } +var _map; - return false +function _load_map() { + return _map = _interopRequireDefault(__webpack_require__(20)); } -glob.Glob = Glob -inherits(Glob, EE) -function Glob (pattern, options, cb) { - if (typeof options === 'function') { - cb = options - options = null - } - - if (options && options.sync) { - if (cb) - throw new TypeError('callback provided to sync glob') - return new GlobSync(pattern, options) - } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - if (!(this instanceof Glob)) - return new Glob(pattern, options, cb) +/* eslint quotes: 0 */ - setopts(this, pattern, options) - this._didRealPath = false +const VERSION_REGEX = /^yarn lockfile v(\d+)$/; - // process each pattern in the minimatch set - var n = this.minimatch.set.length +const TOKEN_TYPES = { + boolean: 'BOOLEAN', + string: 'STRING', + identifier: 'IDENTIFIER', + eof: 'EOF', + colon: 'COLON', + newline: 'NEWLINE', + comment: 'COMMENT', + indent: 'INDENT', + invalid: 'INVALID', + number: 'NUMBER', + comma: 'COMMA' +}; - // The matches are stored as {: true,...} so that - // duplicates are automagically pruned. - // Later, we do an Object.keys() on these. - // Keep them as a list so we can fill in when nonull is set. - this.matches = new Array(n) +const VALID_PROP_VALUE_TOKENS = [TOKEN_TYPES.boolean, TOKEN_TYPES.string, TOKEN_TYPES.number]; - if (typeof cb === 'function') { - cb = once(cb) - this.on('error', cb) - this.on('end', function (matches) { - cb(null, matches) - }) - } +function isValidPropValueToken(token) { + return VALID_PROP_VALUE_TOKENS.indexOf(token.type) >= 0; +} - var self = this - this._processing = 0 +function* tokenise(input) { + let lastNewline = false; + let line = 1; + let col = 0; - this._emitQueue = [] - this._processQueue = [] - this.paused = false + function buildToken(type, value) { + return { line, col, type, value }; + } - if (this.noprocess) - return this + while (input.length) { + let chop = 0; - if (n === 0) - return done() + if (input[0] === '\n' || input[0] === '\r') { + chop++; + // If this is a \r\n line, ignore both chars but only add one new line + if (input[1] === '\n') { + chop++; + } + line++; + col = 0; + yield buildToken(TOKEN_TYPES.newline); + } else if (input[0] === '#') { + chop++; - var sync = true - for (var i = 0; i < n; i ++) { - this._process(this.minimatch.set[i], i, false, done) - } - sync = false + let val = ''; + while (input[chop] !== '\n') { + val += input[chop]; + chop++; + } + yield buildToken(TOKEN_TYPES.comment, val); + } else if (input[0] === ' ') { + if (lastNewline) { + let indent = ''; + for (let i = 0; input[i] === ' '; i++) { + indent += input[i]; + } - function done () { - --self._processing - if (self._processing <= 0) { - if (sync) { - process.nextTick(function () { - self._finish() - }) + if (indent.length % 2) { + throw new TypeError('Invalid number of spaces'); + } else { + chop = indent.length; + yield buildToken(TOKEN_TYPES.indent, indent.length / 2); + } } else { - self._finish() + chop++; } - } - } -} + } else if (input[0] === '"') { + let val = ''; -Glob.prototype._finish = function () { - assert(this instanceof Glob) - if (this.aborted) - return + for (let i = 0;; i++) { + const currentChar = input[i]; + val += currentChar; - if (this.realpath && !this._didRealpath) - return this._realpath() + if (i > 0 && currentChar === '"') { + const isEscaped = input[i - 1] === '\\' && input[i - 2] !== '\\'; + if (!isEscaped) { + break; + } + } + } - common.finish(this) - this.emit('end', this.found) -} + chop = val.length; -Glob.prototype._realpath = function () { - if (this._didRealpath) - return + try { + yield buildToken(TOKEN_TYPES.string, JSON.parse(val)); + } catch (err) { + if (err instanceof SyntaxError) { + yield buildToken(TOKEN_TYPES.invalid); + } else { + throw err; + } + } + } else if (/^[0-9]/.test(input)) { + let val = ''; + for (let i = 0; /^[0-9]$/.test(input[i]); i++) { + val += input[i]; + } + chop = val.length; - this._didRealpath = true + yield buildToken(TOKEN_TYPES.number, +val); + } else if (/^true/.test(input)) { + yield buildToken(TOKEN_TYPES.boolean, true); + chop = 4; + } else if (/^false/.test(input)) { + yield buildToken(TOKEN_TYPES.boolean, false); + chop = 5; + } else if (input[0] === ':') { + yield buildToken(TOKEN_TYPES.colon); + chop++; + } else if (input[0] === ',') { + yield buildToken(TOKEN_TYPES.comma); + chop++; + } else if (/^[a-zA-Z\/-]/g.test(input)) { + let name = ''; + for (let i = 0; i < input.length; i++) { + const char = input[i]; + if (char === ':' || char === ' ' || char === '\n' || char === '\r' || char === ',') { + break; + } else { + name += char; + } + } + chop = name.length; - var n = this.matches.length - if (n === 0) - return this._finish() + yield buildToken(TOKEN_TYPES.string, name); + } else { + yield buildToken(TOKEN_TYPES.invalid); + } - var self = this - for (var i = 0; i < this.matches.length; i++) - this._realpathSet(i, next) + if (!chop) { + // will trigger infinite recursion + yield buildToken(TOKEN_TYPES.invalid); + } - function next () { - if (--n === 0) - self._finish() + col += chop; + lastNewline = input[0] === '\n' || input[0] === '\r' && input[1] === '\n'; + input = input.slice(chop); } -} -Glob.prototype._realpathSet = function (index, cb) { - var matchset = this.matches[index] - if (!matchset) - return cb() + yield buildToken(TOKEN_TYPES.eof); +} - var found = Object.keys(matchset) - var self = this - var n = found.length +class Parser { + constructor(input, fileLoc = 'lockfile') { + this.comments = []; + this.tokens = tokenise(input); + this.fileLoc = fileLoc; + } - if (n === 0) - return cb() + onComment(token) { + const value = token.value; + (0, (_invariant || _load_invariant()).default)(typeof value === 'string', 'expected token value to be a string'); - var set = this.matches[index] = Object.create(null) - found.forEach(function (p, i) { - // If there's a problem with the stat, then it means that - // one or more of the links in the realpath couldn't be - // resolved. just return the abs value in that case. - p = self._makeAbs(p) - rp.realpath(p, self.realpathCache, function (er, real) { - if (!er) - set[real] = true - else if (er.syscall === 'stat') - set[p] = true - else - self.emit('error', er) // srsly wtf right here + const comment = value.trim(); - if (--n === 0) { - self.matches[index] = set - cb() + const versionMatch = comment.match(VERSION_REGEX); + if (versionMatch) { + const version = +versionMatch[1]; + if (version > (_constants || _load_constants()).LOCKFILE_VERSION) { + throw new (_errors || _load_errors()).MessageError(`Can't install from a lockfile of version ${version} as you're on an old yarn version that only supports ` + `versions up to ${(_constants || _load_constants()).LOCKFILE_VERSION}. Run \`$ yarn self-update\` to upgrade to the latest version.`); } - }) - }) -} - -Glob.prototype._mark = function (p) { - return common.mark(this, p) -} + } -Glob.prototype._makeAbs = function (f) { - return common.makeAbs(this, f) -} + this.comments.push(comment); + } -Glob.prototype.abort = function () { - this.aborted = true - this.emit('abort') -} + next() { + const item = this.tokens.next(); + (0, (_invariant || _load_invariant()).default)(item, 'expected a token'); -Glob.prototype.pause = function () { - if (!this.paused) { - this.paused = true - this.emit('pause') - } -} + const done = item.done, + value = item.value; -Glob.prototype.resume = function () { - if (this.paused) { - this.emit('resume') - this.paused = false - if (this._emitQueue.length) { - var eq = this._emitQueue.slice(0) - this._emitQueue.length = 0 - for (var i = 0; i < eq.length; i ++) { - var e = eq[i] - this._emitMatch(e[0], e[1]) - } - } - if (this._processQueue.length) { - var pq = this._processQueue.slice(0) - this._processQueue.length = 0 - for (var i = 0; i < pq.length; i ++) { - var p = pq[i] - this._processing-- - this._process(p[0], p[1], p[2], p[3]) - } + if (done || !value) { + throw new Error('No more tokens'); + } else if (value.type === TOKEN_TYPES.comment) { + this.onComment(value); + return this.next(); + } else { + return this.token = value; } } -} - -Glob.prototype._process = function (pattern, index, inGlobStar, cb) { - assert(this instanceof Glob) - assert(typeof cb === 'function') - if (this.aborted) - return - - this._processing++ - if (this.paused) { - this._processQueue.push([pattern, index, inGlobStar, cb]) - return + unexpected(msg = 'Unexpected token') { + throw new SyntaxError(`${msg} ${this.token.line}:${this.token.col} in ${this.fileLoc}`); } - //console.error('PROCESS %d', this._processing, pattern) + expect(tokType) { + if (this.token.type === tokType) { + this.next(); + } else { + this.unexpected(); + } + } - // Get the first [n] parts of pattern that are all strings. - var n = 0 - while (typeof pattern[n] === 'string') { - n ++ + eat(tokType) { + if (this.token.type === tokType) { + this.next(); + return true; + } else { + return false; + } } - // now n is the index of the first one that is *not* a string. - // see if there's anything else - var prefix - switch (n) { - // if not, then this is rather simple - case pattern.length: - this._processSimple(pattern.join('/'), index, cb) - return + parse(indent = 0) { + const obj = (0, (_map || _load_map()).default)(); - case 0: - // pattern *starts* with some non-trivial item. - // going to readdir(cwd), but not include the prefix in matches. - prefix = null - break + while (true) { + const propToken = this.token; - default: - // pattern has some string bits in the front. - // whatever it starts with, whether that's 'absolute' like /foo/bar, - // or 'relative' like '../baz' - prefix = pattern.slice(0, n).join('/') - break - } + if (propToken.type === TOKEN_TYPES.newline) { + const nextToken = this.next(); + if (!indent) { + // if we have 0 indentation then the next token doesn't matter + continue; + } - var remain = pattern.slice(n) + if (nextToken.type !== TOKEN_TYPES.indent) { + // if we have no indentation after a newline then we've gone down a level + break; + } - // get the list of entries. - var read - if (prefix === null) - read = '.' - else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { - if (!prefix || !isAbsolute(prefix)) - prefix = '/' + prefix - read = prefix - } else - read = prefix + if (nextToken.value === indent) { + // all is good, the indent is on our level + this.next(); + } else { + // the indentation is less than our level + break; + } + } else if (propToken.type === TOKEN_TYPES.indent) { + if (propToken.value === indent) { + this.next(); + } else { + break; + } + } else if (propToken.type === TOKEN_TYPES.eof) { + break; + } else if (propToken.type === TOKEN_TYPES.string) { + // property key + const key = propToken.value; + (0, (_invariant || _load_invariant()).default)(key, 'Expected a key'); - var abs = this._makeAbs(read) + const keys = [key]; + this.next(); - //if ignored, skip _processing - if (childrenIgnored(this, read)) - return cb() + // support multiple keys + while (this.token.type === TOKEN_TYPES.comma) { + this.next(); // skip comma - var isGlobStar = remain[0] === minimatch.GLOBSTAR - if (isGlobStar) - this._processGlobStar(prefix, read, abs, remain, index, inGlobStar, cb) - else - this._processReaddir(prefix, read, abs, remain, index, inGlobStar, cb) -} + const keyToken = this.token; + if (keyToken.type !== TOKEN_TYPES.string) { + this.unexpected('Expected string'); + } -Glob.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar, cb) { - var self = this - this._readdir(abs, inGlobStar, function (er, entries) { - return self._processReaddir2(prefix, read, abs, remain, index, inGlobStar, entries, cb) - }) -} + const key = keyToken.value; + (0, (_invariant || _load_invariant()).default)(key, 'Expected a key'); + keys.push(key); + this.next(); + } -Glob.prototype._processReaddir2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { + const valToken = this.token; - // if the abs isn't a dir, then nothing can match! - if (!entries) - return cb() + if (valToken.type === TOKEN_TYPES.colon) { + // object + this.next(); - // It will only match dot entries if it starts with a dot, or if - // dot is set. Stuff like @(.foo|.bar) isn't allowed. - var pn = remain[0] - var negate = !!this.minimatch.negate - var rawGlob = pn._glob - var dotOk = this.dot || rawGlob.charAt(0) === '.' + // parse object + const val = this.parse(indent + 1); - var matchedEntries = [] - for (var i = 0; i < entries.length; i++) { - var e = entries[i] - if (e.charAt(0) !== '.' || dotOk) { - var m - if (negate && !prefix) { - m = !e.match(pn) - } else { - m = e.match(pn) - } - if (m) - matchedEntries.push(e) - } - } + for (var _iterator = keys, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { + var _ref; - //console.error('prd2', prefix, entries, remain[0]._glob, matchedEntries) + if (_isArray) { + if (_i >= _iterator.length) break; + _ref = _iterator[_i++]; + } else { + _i = _iterator.next(); + if (_i.done) break; + _ref = _i.value; + } - var len = matchedEntries.length - // If there are no matched entries, then nothing matches. - if (len === 0) - return cb() + const key = _ref; - // if this is the last remaining pattern bit, then no need for - // an additional stat *unless* the user has specified mark or - // stat explicitly. We know they exist, since readdir returned - // them. + obj[key] = val; + } - if (remain.length === 1 && !this.mark && !this.stat) { - if (!this.matches[index]) - this.matches[index] = Object.create(null) + if (indent && this.token.type !== TOKEN_TYPES.indent) { + break; + } + } else if (isValidPropValueToken(valToken)) { + // plain value + for (var _iterator2 = keys, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) { + var _ref2; - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - if (prefix) { - if (prefix !== '/') - e = prefix + '/' + e - else - e = prefix + e - } + if (_isArray2) { + if (_i2 >= _iterator2.length) break; + _ref2 = _iterator2[_i2++]; + } else { + _i2 = _iterator2.next(); + if (_i2.done) break; + _ref2 = _i2.value; + } - if (e.charAt(0) === '/' && !this.nomount) { - e = path.join(this.root, e) + const key = _ref2; + + obj[key] = valToken.value; + } + + this.next(); + } else { + this.unexpected('Invalid value type'); + } + } else { + this.unexpected(`Unknown token: ${(_util || _load_util()).default.inspect(propToken)}`); } - this._emitMatch(index, e) } - // This was the last one, and no stats were needed - return cb() - } - // now test all matched entries as stand-ins for that part - // of the pattern. - remain.shift() - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - var newPattern - if (prefix) { - if (prefix !== '/') - e = prefix + '/' + e - else - e = prefix + e - } - this._process([e].concat(remain), index, inGlobStar, cb) + return obj; } - cb() } -Glob.prototype._emitMatch = function (index, e) { - if (this.aborted) - return - - if (isIgnored(this, e)) - return - - if (this.paused) { - this._emitQueue.push([index, e]) - return - } - - var abs = isAbsolute(e) ? e : this._makeAbs(e) - - if (this.mark) - e = this._mark(e) +const MERGE_CONFLICT_ANCESTOR = '|||||||'; +const MERGE_CONFLICT_END = '>>>>>>>'; +const MERGE_CONFLICT_SEP = '======='; +const MERGE_CONFLICT_START = '<<<<<<<'; - if (this.absolute) - e = abs +/** + * Extract the two versions of the lockfile from a merge conflict. + */ +function extractConflictVariants(str) { + const variants = [[], []]; + const lines = str.split(/\r?\n/g); + let skip = false; - if (this.matches[index][e]) - return + while (lines.length) { + const line = lines.shift(); + if (line.startsWith(MERGE_CONFLICT_START)) { + // get the first variant + while (lines.length) { + const conflictLine = lines.shift(); + if (conflictLine === MERGE_CONFLICT_SEP) { + skip = false; + break; + } else if (skip || conflictLine.startsWith(MERGE_CONFLICT_ANCESTOR)) { + skip = true; + continue; + } else { + variants[0].push(conflictLine); + } + } - if (this.nodir) { - var c = this.cache[abs] - if (c === 'DIR' || Array.isArray(c)) - return + // get the second variant + while (lines.length) { + const conflictLine = lines.shift(); + if (conflictLine.startsWith(MERGE_CONFLICT_END)) { + break; + } else { + variants[1].push(conflictLine); + } + } + } else { + variants[0].push(line); + variants[1].push(line); + } } - this.matches[index][e] = true + return [variants[0].join('\n'), variants[1].join('\n')]; +} - var st = this.statCache[abs] - if (st) - this.emit('stat', e, st) +/** + * Check if a lockfile has merge conflicts. + */ +function hasMergeConflicts(str) { + return str.includes(MERGE_CONFLICT_START) && str.includes(MERGE_CONFLICT_SEP) && str.includes(MERGE_CONFLICT_END); +} - this.emit('match', e) +/** + * Parse the lockfile. + */ +function parse(str, fileLoc) { + const parser = new Parser(str, fileLoc); + parser.next(); + return parser.parse(); } -Glob.prototype._readdirInGlobStar = function (abs, cb) { - if (this.aborted) - return +/** + * Parse and merge the two variants in a conflicted lockfile. + */ +function parseWithConflict(str, fileLoc) { + const variants = extractConflictVariants(str); + try { + return { type: 'merge', object: Object.assign({}, parse(variants[0], fileLoc), parse(variants[1], fileLoc)) }; + } catch (err) { + if (err instanceof SyntaxError) { + return { type: 'conflict', object: {} }; + } else { + throw err; + } + } +} - // follow all symlinked directories forever - // just proceed as if this is a non-globstar situation - if (this.follow) - return this._readdir(abs, false, cb) +/***/ }), +/* 82 */, +/* 83 */, +/* 84 */ +/***/ (function(module, exports, __webpack_require__) { - var lstatkey = 'lstat\0' + abs - var self = this - var lstatcb = inflight(lstatkey, lstatcb_) +"use strict"; - if (lstatcb) - fs.lstat(abs, lstatcb) - function lstatcb_ (er, lstat) { - if (er && er.code === 'ENOENT') - return cb() +Object.defineProperty(exports, "__esModule", { + value: true +}); - var isSym = lstat && lstat.isSymbolicLink() - self.symlinks[abs] = isSym +var _map; - // If it's not a symlink or a dir, then it's definitely a regular file. - // don't bother doing a readdir in that case. - if (!isSym && lstat && !lstat.isDirectory()) { - self.cache[abs] = 'FILE' - cb() - } else - self._readdir(abs, false, cb) - } +function _load_map() { + return _map = _interopRequireDefault(__webpack_require__(20)); } -Glob.prototype._readdir = function (abs, inGlobStar, cb) { - if (this.aborted) - return +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - cb = inflight('readdir\0'+abs+'\0'+inGlobStar, cb) - if (!cb) - return +const debug = __webpack_require__(212)('yarn'); - //console.error('RD %j %j', +inGlobStar, abs) - if (inGlobStar && !ownProp(this.symlinks, abs)) - return this._readdirInGlobStar(abs, cb) +class BlockingQueue { + constructor(alias, maxConcurrency = Infinity) { + this.concurrencyQueue = []; + this.maxConcurrency = maxConcurrency; + this.runningCount = 0; + this.warnedStuck = false; + this.alias = alias; + this.first = true; - if (ownProp(this.cache, abs)) { - var c = this.cache[abs] - if (!c || c === 'FILE') - return cb() + this.running = (0, (_map || _load_map()).default)(); + this.queue = (0, (_map || _load_map()).default)(); - if (Array.isArray(c)) - return cb(null, c) + this.stuckTick = this.stuckTick.bind(this); } - var self = this - fs.readdir(abs, readdirCb(this, abs, cb)) -} + stillActive() { + if (this.stuckTimer) { + clearTimeout(this.stuckTimer); + } -function readdirCb (self, abs, cb) { - return function (er, entries) { - if (er) - self._readdirError(abs, er, cb) - else - self._readdirEntries(abs, entries, cb) - } -} + this.stuckTimer = setTimeout(this.stuckTick, 5000); -Glob.prototype._readdirEntries = function (abs, entries, cb) { - if (this.aborted) - return + // We need to check the existence of unref because of https://github.com/facebook/jest/issues/4559 + // $FlowFixMe: Node's setInterval returns a Timeout, not a Number + this.stuckTimer.unref && this.stuckTimer.unref(); + } - // if we haven't asked to stat everything, then just - // assume that everything in there exists, so we can avoid - // having to stat it a second time. - if (!this.mark && !this.stat) { - for (var i = 0; i < entries.length; i ++) { - var e = entries[i] - if (abs === '/') - e = abs + e - else - e = abs + '/' + e - this.cache[e] = true + stuckTick() { + if (this.runningCount === 1) { + this.warnedStuck = true; + debug(`The ${JSON.stringify(this.alias)} blocking queue may be stuck. 5 seconds ` + `without any activity with 1 worker: ${Object.keys(this.running)[0]}`); } } - this.cache[abs] = entries - return cb(null, entries) -} - -Glob.prototype._readdirError = function (f, er, cb) { - if (this.aborted) - return - - // handle errors, and cache the information - switch (er.code) { - case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 - case 'ENOTDIR': // totally normal. means it *does* exist. - var abs = this._makeAbs(f) - this.cache[abs] = 'FILE' - if (abs === this.cwdAbs) { - var error = new Error(er.code + ' invalid cwd ' + this.cwd) - error.path = this.cwd - error.code = er.code - this.emit('error', error) - this.abort() - } - break + push(key, factory) { + if (this.first) { + this.first = false; + } else { + this.stillActive(); + } - case 'ENOENT': // not terribly unusual - case 'ELOOP': - case 'ENAMETOOLONG': - case 'UNKNOWN': - this.cache[this._makeAbs(f)] = false - break + return new Promise((resolve, reject) => { + // we're already running so push ourselves to the queue + const queue = this.queue[key] = this.queue[key] || []; + queue.push({ factory, resolve, reject }); - default: // some unusual error. Treat as failure. - this.cache[this._makeAbs(f)] = false - if (this.strict) { - this.emit('error', er) - // If the error is handled, then we abort - // if not, we threw out of here - this.abort() + if (!this.running[key]) { + this.shift(key); } - if (!this.silent) - console.error('glob error', er) - break + }); } - return cb() -} + shift(key) { + if (this.running[key]) { + delete this.running[key]; + this.runningCount--; -Glob.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar, cb) { - var self = this - this._readdir(abs, inGlobStar, function (er, entries) { - self._processGlobStar2(prefix, read, abs, remain, index, inGlobStar, entries, cb) - }) -} + if (this.stuckTimer) { + clearTimeout(this.stuckTimer); + this.stuckTimer = null; + } + if (this.warnedStuck) { + this.warnedStuck = false; + debug(`${JSON.stringify(this.alias)} blocking queue finally resolved. Nothing to worry about.`); + } + } -Glob.prototype._processGlobStar2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { - //console.error('pgs2', prefix, remain[0], entries) + const queue = this.queue[key]; + if (!queue) { + return; + } - // no entries means not a dir, so it can never have matches - // foo.txt/** doesn't match foo.txt - if (!entries) - return cb() + var _queue$shift = queue.shift(); - // test without the globstar, and with every child both below - // and replacing the globstar. - var remainWithoutGlobStar = remain.slice(1) - var gspref = prefix ? [ prefix ] : [] - var noGlobStar = gspref.concat(remainWithoutGlobStar) + const resolve = _queue$shift.resolve, + reject = _queue$shift.reject, + factory = _queue$shift.factory; - // the noGlobStar pattern exits the inGlobStar state - this._process(noGlobStar, index, false, cb) + if (!queue.length) { + delete this.queue[key]; + } - var isSym = this.symlinks[abs] - var len = entries.length + const next = () => { + this.shift(key); + this.shiftConcurrencyQueue(); + }; - // If it's a symlink, and we're in a globstar, then stop - if (isSym && inGlobStar) - return cb() + const run = () => { + this.running[key] = true; + this.runningCount++; - for (var i = 0; i < len; i++) { - var e = entries[i] - if (e.charAt(0) === '.' && !this.dot) - continue + factory().then(function (val) { + resolve(val); + next(); + return null; + }).catch(function (err) { + reject(err); + next(); + }); + }; - // these two cases enter the inGlobStar state - var instead = gspref.concat(entries[i], remainWithoutGlobStar) - this._process(instead, index, true, cb) + this.maybePushConcurrencyQueue(run); + } - var below = gspref.concat(entries[i], remain) - this._process(below, index, true, cb) + maybePushConcurrencyQueue(run) { + if (this.runningCount < this.maxConcurrency) { + run(); + } else { + this.concurrencyQueue.push(run); + } } - cb() + shiftConcurrencyQueue() { + if (this.runningCount < this.maxConcurrency) { + const fn = this.concurrencyQueue.shift(); + if (fn) { + fn(); + } + } + } } +exports.default = BlockingQueue; -Glob.prototype._processSimple = function (prefix, index, cb) { - // XXX review this. Shouldn't it be doing the mounting etc - // before doing stat? kinda weird? - var self = this - this._stat(prefix, function (er, exists) { - self._processSimple2(prefix, index, er, exists, cb) - }) -} -Glob.prototype._processSimple2 = function (prefix, index, er, exists, cb) { +/***/ }), +/* 85 */ +/***/ (function(module, exports) { - //console.error('ps2', prefix, exists) +module.exports = function (exec) { + try { + return !!exec(); + } catch (e) { + return true; + } +}; - if (!this.matches[index]) - this.matches[index] = Object.create(null) - // If it doesn't exist, then just mark the lack of results - if (!exists) - return cb() +/***/ }), +/* 86 */, +/* 87 */, +/* 88 */, +/* 89 */, +/* 90 */, +/* 91 */, +/* 92 */, +/* 93 */, +/* 94 */, +/* 95 */, +/* 96 */, +/* 97 */, +/* 98 */, +/* 99 */, +/* 100 */ +/***/ (function(module, exports, __webpack_require__) { - if (prefix && isAbsolute(prefix) && !this.nomount) { - var trail = /[\/\\]$/.test(prefix) - if (prefix.charAt(0) === '/') { - prefix = path.join(this.root, prefix) - } else { - prefix = path.resolve(this.root, prefix) - if (trail) - prefix += '/' - } - } +// getting tag from 19.1.3.6 Object.prototype.toString() +var cof = __webpack_require__(47); +var TAG = __webpack_require__(13)('toStringTag'); +// ES3 wrong here +var ARG = cof(function () { return arguments; }()) == 'Arguments'; - if (process.platform === 'win32') - prefix = prefix.replace(/\\/g, '/') +// fallback for IE11 Script Access Denied error +var tryGet = function (it, key) { + try { + return it[key]; + } catch (e) { /* empty */ } +}; - // Mark this as a match - this._emitMatch(index, prefix) - cb() -} +module.exports = function (it) { + var O, T, B; + return it === undefined ? 'Undefined' : it === null ? 'Null' + // @@toStringTag case + : typeof (T = tryGet(O = Object(it), TAG)) == 'string' ? T + // builtinTag case + : ARG ? cof(O) + // ES3 arguments fallback + : (B = cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B; +}; -// Returns either 'DIR', 'FILE', or false -Glob.prototype._stat = function (f, cb) { - var abs = this._makeAbs(f) - var needDir = f.slice(-1) === '/' - if (f.length > this.maxLength) - return cb() +/***/ }), +/* 101 */ +/***/ (function(module, exports) { - if (!this.stat && ownProp(this.cache, abs)) { - var c = this.cache[abs] +// IE 8- don't enum bug keys +module.exports = ( + 'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf' +).split(','); - if (Array.isArray(c)) - c = 'DIR' - // It exists, but maybe not how we need it - if (!needDir || c === 'DIR') - return cb(null, c) +/***/ }), +/* 102 */ +/***/ (function(module, exports, __webpack_require__) { - if (needDir && c === 'FILE') - return cb() +var document = __webpack_require__(11).document; +module.exports = document && document.documentElement; - // otherwise we have to stat, because maybe c=true - // if we know it exists, but not what it is. - } - var exists - var stat = this.statCache[abs] - if (stat !== undefined) { - if (stat === false) - return cb(null, stat) - else { - var type = stat.isDirectory() ? 'DIR' : 'FILE' - if (needDir && type === 'FILE') - return cb() - else - return cb(null, type, stat) - } - } +/***/ }), +/* 103 */ +/***/ (function(module, exports, __webpack_require__) { - var self = this - var statcb = inflight('stat\0' + abs, lstatcb_) - if (statcb) - fs.lstat(abs, statcb) +"use strict"; - function lstatcb_ (er, lstat) { - if (lstat && lstat.isSymbolicLink()) { - // If it's a symlink, then treat it as the target, unless - // the target does not exist, then treat it as a file. - return fs.stat(abs, function (er, stat) { - if (er) - self._stat2(f, abs, null, lstat, cb) - else - self._stat2(f, abs, er, stat, cb) - }) - } else { - self._stat2(f, abs, er, lstat, cb) +var LIBRARY = __webpack_require__(69); +var $export = __webpack_require__(41); +var redefine = __webpack_require__(197); +var hide = __webpack_require__(31); +var Iterators = __webpack_require__(35); +var $iterCreate = __webpack_require__(188); +var setToStringTag = __webpack_require__(71); +var getPrototypeOf = __webpack_require__(194); +var ITERATOR = __webpack_require__(13)('iterator'); +var BUGGY = !([].keys && 'next' in [].keys()); // Safari has buggy iterators w/o `next` +var FF_ITERATOR = '@@iterator'; +var KEYS = 'keys'; +var VALUES = 'values'; + +var returnThis = function () { return this; }; + +module.exports = function (Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED) { + $iterCreate(Constructor, NAME, next); + var getMethod = function (kind) { + if (!BUGGY && kind in proto) return proto[kind]; + switch (kind) { + case KEYS: return function keys() { return new Constructor(this, kind); }; + case VALUES: return function values() { return new Constructor(this, kind); }; + } return function entries() { return new Constructor(this, kind); }; + }; + var TAG = NAME + ' Iterator'; + var DEF_VALUES = DEFAULT == VALUES; + var VALUES_BUG = false; + var proto = Base.prototype; + var $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT]; + var $default = $native || getMethod(DEFAULT); + var $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined; + var $anyNative = NAME == 'Array' ? proto.entries || $native : $native; + var methods, key, IteratorPrototype; + // Fix native + if ($anyNative) { + IteratorPrototype = getPrototypeOf($anyNative.call(new Base())); + if (IteratorPrototype !== Object.prototype && IteratorPrototype.next) { + // Set @@toStringTag to native iterators + setToStringTag(IteratorPrototype, TAG, true); + // fix for some old engines + if (!LIBRARY && typeof IteratorPrototype[ITERATOR] != 'function') hide(IteratorPrototype, ITERATOR, returnThis); } } -} - -Glob.prototype._stat2 = function (f, abs, er, stat, cb) { - if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) { - this.statCache[abs] = false - return cb() + // fix Array#{values, @@iterator}.name in V8 / FF + if (DEF_VALUES && $native && $native.name !== VALUES) { + VALUES_BUG = true; + $default = function values() { return $native.call(this); }; } + // Define iterator + if ((!LIBRARY || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])) { + hide(proto, ITERATOR, $default); + } + // Plug for library + Iterators[NAME] = $default; + Iterators[TAG] = returnThis; + if (DEFAULT) { + methods = { + values: DEF_VALUES ? $default : getMethod(VALUES), + keys: IS_SET ? $default : getMethod(KEYS), + entries: $entries + }; + if (FORCED) for (key in methods) { + if (!(key in proto)) redefine(proto, key, methods[key]); + } else $export($export.P + $export.F * (BUGGY || VALUES_BUG), NAME, methods); + } + return methods; +}; - var needDir = f.slice(-1) === '/' - this.statCache[abs] = stat - - if (abs.slice(-1) === '/' && stat && !stat.isDirectory()) - return cb(null, false, stat) - - var c = true - if (stat) - c = stat.isDirectory() ? 'DIR' : 'FILE' - this.cache[abs] = this.cache[abs] || c - if (needDir && c === 'FILE') - return cb() +/***/ }), +/* 104 */ +/***/ (function(module, exports) { - return cb(null, c, stat) -} +module.exports = function (exec) { + try { + return { e: false, v: exec() }; + } catch (e) { + return { e: true, v: e }; + } +}; /***/ }), -/* 76 */ +/* 105 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; - - -function posix(path) { - return path.charAt(0) === '/'; -} - -function win32(path) { - // https://github.com/nodejs/node/blob/b3fcc245fb25539909ef1d5eaa01dbf92e168633/lib/path.js#L56 - var splitDeviceRe = /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/; - var result = splitDeviceRe.exec(path); - var device = result[1] || ''; - var isUnc = Boolean(device && device.charAt(1) !== ':'); - - // UNC paths are always absolute - return Boolean(result[2] || isUnc); -} +var anObject = __webpack_require__(27); +var isObject = __webpack_require__(34); +var newPromiseCapability = __webpack_require__(70); -module.exports = process.platform === 'win32' ? win32 : posix; -module.exports.posix = posix; -module.exports.win32 = win32; +module.exports = function (C, x) { + anObject(C); + if (isObject(x) && x.constructor === C) return x; + var promiseCapability = newPromiseCapability.f(C); + var resolve = promiseCapability.resolve; + resolve(x); + return promiseCapability.promise; +}; /***/ }), -/* 77 */, -/* 78 */, -/* 79 */ +/* 106 */ /***/ (function(module, exports) { -module.exports = __webpack_require__(121); +module.exports = function (bitmap, value) { + return { + enumerable: !(bitmap & 1), + configurable: !(bitmap & 2), + writable: !(bitmap & 4), + value: value + }; +}; + /***/ }), -/* 80 */, -/* 81 */ +/* 107 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; - +var core = __webpack_require__(23); +var global = __webpack_require__(11); +var SHARED = '__core-js_shared__'; +var store = global[SHARED] || (global[SHARED] = {}); -Object.defineProperty(exports, "__esModule", { - value: true +(module.exports = function (key, value) { + return store[key] || (store[key] = value !== undefined ? value : {}); +})('versions', []).push({ + version: core.version, + mode: __webpack_require__(69) ? 'pure' : 'global', + copyright: '© 2018 Denis Pushkarev (zloirock.ru)' }); -exports.default = function (str, fileLoc = 'lockfile') { - str = (0, (_stripBom || _load_stripBom()).default)(str); - return hasMergeConflicts(str) ? parseWithConflict(str, fileLoc) : { type: 'success', object: parse(str, fileLoc) }; + +/***/ }), +/* 108 */ +/***/ (function(module, exports, __webpack_require__) { + +// 7.3.20 SpeciesConstructor(O, defaultConstructor) +var anObject = __webpack_require__(27); +var aFunction = __webpack_require__(46); +var SPECIES = __webpack_require__(13)('species'); +module.exports = function (O, D) { + var C = anObject(O).constructor; + var S; + return C === undefined || (S = anObject(C)[SPECIES]) == undefined ? D : aFunction(S); }; -var _util; -function _load_util() { - return _util = _interopRequireDefault(__webpack_require__(2)); +/***/ }), +/* 109 */ +/***/ (function(module, exports, __webpack_require__) { + +var ctx = __webpack_require__(48); +var invoke = __webpack_require__(185); +var html = __webpack_require__(102); +var cel = __webpack_require__(68); +var global = __webpack_require__(11); +var process = global.process; +var setTask = global.setImmediate; +var clearTask = global.clearImmediate; +var MessageChannel = global.MessageChannel; +var Dispatch = global.Dispatch; +var counter = 0; +var queue = {}; +var ONREADYSTATECHANGE = 'onreadystatechange'; +var defer, channel, port; +var run = function () { + var id = +this; + // eslint-disable-next-line no-prototype-builtins + if (queue.hasOwnProperty(id)) { + var fn = queue[id]; + delete queue[id]; + fn(); + } +}; +var listener = function (event) { + run.call(event.data); +}; +// Node.js 0.9+ & IE10+ has setImmediate, otherwise: +if (!setTask || !clearTask) { + setTask = function setImmediate(fn) { + var args = []; + var i = 1; + while (arguments.length > i) args.push(arguments[i++]); + queue[++counter] = function () { + // eslint-disable-next-line no-new-func + invoke(typeof fn == 'function' ? fn : Function(fn), args); + }; + defer(counter); + return counter; + }; + clearTask = function clearImmediate(id) { + delete queue[id]; + }; + // Node.js 0.8- + if (__webpack_require__(47)(process) == 'process') { + defer = function (id) { + process.nextTick(ctx(run, id, 1)); + }; + // Sphere (JS game engine) Dispatch API + } else if (Dispatch && Dispatch.now) { + defer = function (id) { + Dispatch.now(ctx(run, id, 1)); + }; + // Browsers with MessageChannel, includes WebWorkers + } else if (MessageChannel) { + channel = new MessageChannel(); + port = channel.port2; + channel.port1.onmessage = listener; + defer = ctx(port.postMessage, port, 1); + // Browsers with postMessage, skip WebWorkers + // IE8 has postMessage, but it's sync & typeof its postMessage is 'object' + } else if (global.addEventListener && typeof postMessage == 'function' && !global.importScripts) { + defer = function (id) { + global.postMessage(id + '', '*'); + }; + global.addEventListener('message', listener, false); + // IE8- + } else if (ONREADYSTATECHANGE in cel('script')) { + defer = function (id) { + html.appendChild(cel('script'))[ONREADYSTATECHANGE] = function () { + html.removeChild(this); + run.call(id); + }; + }; + // Rest old browsers + } else { + defer = function (id) { + setTimeout(ctx(run, id, 1), 0); + }; + } } +module.exports = { + set: setTask, + clear: clearTask +}; -var _invariant; -function _load_invariant() { - return _invariant = _interopRequireDefault(__webpack_require__(7)); -} +/***/ }), +/* 110 */ +/***/ (function(module, exports, __webpack_require__) { -var _stripBom; +// 7.1.15 ToLength +var toInteger = __webpack_require__(73); +var min = Math.min; +module.exports = function (it) { + return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991 +}; -function _load_stripBom() { - return _stripBom = _interopRequireDefault(__webpack_require__(122)); -} -var _constants; +/***/ }), +/* 111 */ +/***/ (function(module, exports) { -function _load_constants() { - return _constants = __webpack_require__(6); -} +var id = 0; +var px = Math.random(); +module.exports = function (key) { + return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36)); +}; -var _errors; -function _load_errors() { - return _errors = __webpack_require__(4); -} +/***/ }), +/* 112 */ +/***/ (function(module, exports, __webpack_require__) { -var _map; -function _load_map() { - return _map = _interopRequireDefault(__webpack_require__(20)); -} +/** + * This is the common logic for both the Node.js and web browser + * implementations of `debug()`. + * + * Expose `debug()` as the module. + */ -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +exports = module.exports = createDebug.debug = createDebug['default'] = createDebug; +exports.coerce = coerce; +exports.disable = disable; +exports.enable = enable; +exports.enabled = enabled; +exports.humanize = __webpack_require__(229); -/* eslint quotes: 0 */ +/** + * Active `debug` instances. + */ +exports.instances = []; -const VERSION_REGEX = /^yarn lockfile v(\d+)$/; +/** + * The currently active debug mode names, and names to skip. + */ -const TOKEN_TYPES = { - boolean: 'BOOLEAN', - string: 'STRING', - identifier: 'IDENTIFIER', - eof: 'EOF', - colon: 'COLON', - newline: 'NEWLINE', - comment: 'COMMENT', - indent: 'INDENT', - invalid: 'INVALID', - number: 'NUMBER', - comma: 'COMMA' -}; +exports.names = []; +exports.skips = []; -const VALID_PROP_VALUE_TOKENS = [TOKEN_TYPES.boolean, TOKEN_TYPES.string, TOKEN_TYPES.number]; +/** + * 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". + */ -function isValidPropValueToken(token) { - return VALID_PROP_VALUE_TOKENS.indexOf(token.type) >= 0; -} +exports.formatters = {}; -function* tokenise(input) { - let lastNewline = false; - let line = 1; - let col = 0; +/** + * Select a color. + * @param {String} namespace + * @return {Number} + * @api private + */ - function buildToken(type, value) { - return { line, col, type, value }; +function selectColor(namespace) { + var hash = 0, i; + + for (i in namespace) { + hash = ((hash << 5) - hash) + namespace.charCodeAt(i); + hash |= 0; // Convert to 32bit integer } - while (input.length) { - let chop = 0; + return exports.colors[Math.abs(hash) % exports.colors.length]; +} - if (input[0] === '\n' || input[0] === '\r') { - chop++; - // If this is a \r\n line, ignore both chars but only add one new line - if (input[1] === '\n') { - chop++; - } - line++; - col = 0; - yield buildToken(TOKEN_TYPES.newline); - } else if (input[0] === '#') { - chop++; +/** + * Create a debugger with the given `namespace`. + * + * @param {String} namespace + * @return {Function} + * @api public + */ - let val = ''; - while (input[chop] !== '\n') { - val += input[chop]; - chop++; - } - yield buildToken(TOKEN_TYPES.comment, val); - } else if (input[0] === ' ') { - if (lastNewline) { - let indent = ''; - for (let i = 0; input[i] === ' '; i++) { - indent += input[i]; - } +function createDebug(namespace) { - if (indent.length % 2) { - throw new TypeError('Invalid number of spaces'); - } else { - chop = indent.length; - yield buildToken(TOKEN_TYPES.indent, indent.length / 2); - } - } else { - chop++; - } - } else if (input[0] === '"') { - let val = ''; + var prevTime; - for (let i = 0;; i++) { - const currentChar = input[i]; - val += currentChar; + function debug() { + // disabled? + if (!debug.enabled) return; - if (i > 0 && currentChar === '"') { - const isEscaped = input[i - 1] === '\\' && input[i - 2] !== '\\'; - if (!isEscaped) { - break; - } - } - } + var self = debug; - chop = val.length; + // set `diff` timestamp + var curr = +new Date(); + var ms = curr - (prevTime || curr); + self.diff = ms; + self.prev = prevTime; + self.curr = curr; + prevTime = curr; - try { - yield buildToken(TOKEN_TYPES.string, JSON.parse(val)); - } catch (err) { - if (err instanceof SyntaxError) { - yield buildToken(TOKEN_TYPES.invalid); - } else { - throw err; - } - } - } else if (/^[0-9]/.test(input)) { - let val = ''; - for (let i = 0; /^[0-9]$/.test(input[i]); i++) { - val += input[i]; - } - chop = val.length; + // turn the `arguments` into a proper Array + var args = new Array(arguments.length); + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i]; + } - yield buildToken(TOKEN_TYPES.number, +val); - } else if (/^true/.test(input)) { - yield buildToken(TOKEN_TYPES.boolean, true); - chop = 4; - } else if (/^false/.test(input)) { - yield buildToken(TOKEN_TYPES.boolean, false); - chop = 5; - } else if (input[0] === ':') { - yield buildToken(TOKEN_TYPES.colon); - chop++; - } else if (input[0] === ',') { - yield buildToken(TOKEN_TYPES.comma); - chop++; - } else if (/^[a-zA-Z\/-]/g.test(input)) { - let name = ''; - for (let i = 0; i < input.length; i++) { - const char = input[i]; - if (char === ':' || char === ' ' || char === '\n' || char === '\r' || char === ',') { - break; - } else { - name += char; - } - } - chop = name.length; + args[0] = exports.coerce(args[0]); - yield buildToken(TOKEN_TYPES.string, name); - } else { - yield buildToken(TOKEN_TYPES.invalid); + if ('string' !== typeof args[0]) { + // anything else let's inspect with %O + args.unshift('%O'); } - if (!chop) { - // will trigger infinite recursion - yield buildToken(TOKEN_TYPES.invalid); - } + // apply any `formatters` transformations + var index = 0; + args[0] = args[0].replace(/%([a-zA-Z%])/g, function(match, format) { + // if we encounter an escaped % then don't increase the array index + if (match === '%%') return match; + index++; + var formatter = exports.formatters[format]; + if ('function' === typeof formatter) { + var val = args[index]; + match = formatter.call(self, val); - col += chop; - lastNewline = input[0] === '\n' || input[0] === '\r' && input[1] === '\n'; - input = input.slice(chop); - } + // now we need to remove `args[index]` since it's inlined in the `format` + args.splice(index, 1); + index--; + } + return match; + }); - yield buildToken(TOKEN_TYPES.eof); -} + // apply env-specific formatting (colors, etc.) + exports.formatArgs.call(self, args); -class Parser { - constructor(input, fileLoc = 'lockfile') { - this.comments = []; - this.tokens = tokenise(input); - this.fileLoc = fileLoc; + var logFn = debug.log || exports.log || console.log.bind(console); + logFn.apply(self, args); } - onComment(token) { - const value = token.value; - (0, (_invariant || _load_invariant()).default)(typeof value === 'string', 'expected token value to be a string'); + debug.namespace = namespace; + debug.enabled = exports.enabled(namespace); + debug.useColors = exports.useColors(); + debug.color = selectColor(namespace); + debug.destroy = destroy; - const comment = value.trim(); + // env-specific initialization logic for debug instances + if ('function' === typeof exports.init) { + exports.init(debug); + } - const versionMatch = comment.match(VERSION_REGEX); - if (versionMatch) { - const version = +versionMatch[1]; - if (version > (_constants || _load_constants()).LOCKFILE_VERSION) { - throw new (_errors || _load_errors()).MessageError(`Can't install from a lockfile of version ${version} as you're on an old yarn version that only supports ` + `versions up to ${(_constants || _load_constants()).LOCKFILE_VERSION}. Run \`$ yarn self-update\` to upgrade to the latest version.`); - } - } + exports.instances.push(debug); - this.comments.push(comment); + return debug; +} + +function destroy () { + var index = exports.instances.indexOf(this); + if (index !== -1) { + exports.instances.splice(index, 1); + return true; + } else { + return false; } +} - next() { - const item = this.tokens.next(); - (0, (_invariant || _load_invariant()).default)(item, 'expected a token'); +/** + * Enables a debug mode by namespaces. This can include modes + * separated by a colon and wildcards. + * + * @param {String} namespaces + * @api public + */ - const done = item.done, - value = item.value; +function enable(namespaces) { + exports.save(namespaces); - if (done || !value) { - throw new Error('No more tokens'); - } else if (value.type === TOKEN_TYPES.comment) { - this.onComment(value); - return this.next(); + exports.names = []; + exports.skips = []; + + var i; + var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/); + var len = split.length; + + for (i = 0; i < len; i++) { + if (!split[i]) continue; // ignore empty strings + namespaces = split[i].replace(/\*/g, '.*?'); + if (namespaces[0] === '-') { + exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); } else { - return this.token = value; + exports.names.push(new RegExp('^' + namespaces + '$')); } } - unexpected(msg = 'Unexpected token') { - throw new SyntaxError(`${msg} ${this.token.line}:${this.token.col} in ${this.fileLoc}`); + for (i = 0; i < exports.instances.length; i++) { + var instance = exports.instances[i]; + instance.enabled = exports.enabled(instance.namespace); } +} - expect(tokType) { - if (this.token.type === tokType) { - this.next(); - } else { - this.unexpected(); +/** + * Disable debug output. + * + * @api public + */ + +function disable() { + exports.enable(''); +} + +/** + * 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; + } + var i, len; + for (i = 0, len = exports.skips.length; i < len; i++) { + if (exports.skips[i].test(name)) { + return false; } } - - eat(tokType) { - if (this.token.type === tokType) { - this.next(); + for (i = 0, len = exports.names.length; i < len; i++) { + if (exports.names[i].test(name)) { return true; - } else { - return false; } } + return false; +} - parse(indent = 0) { - const obj = (0, (_map || _load_map()).default)(); +/** + * Coerce `val`. + * + * @param {Mixed} val + * @return {Mixed} + * @api private + */ - while (true) { - const propToken = this.token; +function coerce(val) { + if (val instanceof Error) return val.stack || val.message; + return val; +} - if (propToken.type === TOKEN_TYPES.newline) { - const nextToken = this.next(); - if (!indent) { - // if we have 0 indentation then the next token doesn't matter - continue; - } - if (nextToken.type !== TOKEN_TYPES.indent) { - // if we have no indentation after a newline then we've gone down a level - break; - } +/***/ }), +/* 113 */, +/* 114 */ +/***/ (function(module, exports, __webpack_require__) { - if (nextToken.value === indent) { - // all is good, the indent is on our level - this.next(); - } else { - // the indentation is less than our level - break; - } - } else if (propToken.type === TOKEN_TYPES.indent) { - if (propToken.value === indent) { - this.next(); - } else { - break; - } - } else if (propToken.type === TOKEN_TYPES.eof) { - break; - } else if (propToken.type === TOKEN_TYPES.string) { - // property key - const key = propToken.value; - (0, (_invariant || _load_invariant()).default)(key, 'Expected a key'); +module.exports = realpath +realpath.realpath = realpath +realpath.sync = realpathSync +realpath.realpathSync = realpathSync +realpath.monkeypatch = monkeypatch +realpath.unmonkeypatch = unmonkeypatch - const keys = [key]; - this.next(); +var fs = __webpack_require__(3) +var origRealpath = fs.realpath +var origRealpathSync = fs.realpathSync - // support multiple keys - while (this.token.type === TOKEN_TYPES.comma) { - this.next(); // skip comma +var version = process.version +var ok = /^v[0-5]\./.test(version) +var old = __webpack_require__(217) - const keyToken = this.token; - if (keyToken.type !== TOKEN_TYPES.string) { - this.unexpected('Expected string'); - } +function newError (er) { + return er && er.syscall === 'realpath' && ( + er.code === 'ELOOP' || + er.code === 'ENOMEM' || + er.code === 'ENAMETOOLONG' + ) +} - const key = keyToken.value; - (0, (_invariant || _load_invariant()).default)(key, 'Expected a key'); - keys.push(key); - this.next(); - } +function realpath (p, cache, cb) { + if (ok) { + return origRealpath(p, cache, cb) + } - const valToken = this.token; + if (typeof cache === 'function') { + cb = cache + cache = null + } + origRealpath(p, cache, function (er, result) { + if (newError(er)) { + old.realpath(p, cache, cb) + } else { + cb(er, result) + } + }) +} - if (valToken.type === TOKEN_TYPES.colon) { - // object - this.next(); +function realpathSync (p, cache) { + if (ok) { + return origRealpathSync(p, cache) + } - // parse object - const val = this.parse(indent + 1); + try { + return origRealpathSync(p, cache) + } catch (er) { + if (newError(er)) { + return old.realpathSync(p, cache) + } else { + throw er + } + } +} - for (var _iterator = keys, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { - var _ref; +function monkeypatch () { + fs.realpath = realpath + fs.realpathSync = realpathSync +} - if (_isArray) { - if (_i >= _iterator.length) break; - _ref = _iterator[_i++]; - } else { - _i = _iterator.next(); - if (_i.done) break; - _ref = _i.value; - } +function unmonkeypatch () { + fs.realpath = origRealpath + fs.realpathSync = origRealpathSync +} - const key = _ref; - obj[key] = val; - } +/***/ }), +/* 115 */ +/***/ (function(module, exports, __webpack_require__) { - if (indent && this.token.type !== TOKEN_TYPES.indent) { - break; - } - } else if (isValidPropValueToken(valToken)) { - // plain value - for (var _iterator2 = keys, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) { - var _ref2; +exports.alphasort = alphasort +exports.alphasorti = alphasorti +exports.setopts = setopts +exports.ownProp = ownProp +exports.makeAbs = makeAbs +exports.finish = finish +exports.mark = mark +exports.isIgnored = isIgnored +exports.childrenIgnored = childrenIgnored - if (_isArray2) { - if (_i2 >= _iterator2.length) break; - _ref2 = _iterator2[_i2++]; - } else { - _i2 = _iterator2.next(); - if (_i2.done) break; - _ref2 = _i2.value; - } +function ownProp (obj, field) { + return Object.prototype.hasOwnProperty.call(obj, field) +} - const key = _ref2; +var path = __webpack_require__(0) +var minimatch = __webpack_require__(60) +var isAbsolute = __webpack_require__(76) +var Minimatch = minimatch.Minimatch - obj[key] = valToken.value; - } +function alphasorti (a, b) { + return a.toLowerCase().localeCompare(b.toLowerCase()) +} - this.next(); - } else { - this.unexpected('Invalid value type'); - } - } else { - this.unexpected(`Unknown token: ${(_util || _load_util()).default.inspect(propToken)}`); - } - } +function alphasort (a, b) { + return a.localeCompare(b) +} - return obj; +function setupIgnores (self, options) { + self.ignore = options.ignore || [] + + if (!Array.isArray(self.ignore)) + self.ignore = [self.ignore] + + if (self.ignore.length) { + self.ignore = self.ignore.map(ignoreMap) } } -const MERGE_CONFLICT_ANCESTOR = '|||||||'; -const MERGE_CONFLICT_END = '>>>>>>>'; -const MERGE_CONFLICT_SEP = '======='; -const MERGE_CONFLICT_START = '<<<<<<<'; +// ignore patterns are always in dot:true mode. +function ignoreMap (pattern) { + var gmatcher = null + if (pattern.slice(-3) === '/**') { + var gpattern = pattern.replace(/(\/\*\*)+$/, '') + gmatcher = new Minimatch(gpattern, { dot: true }) + } -/** - * Extract the two versions of the lockfile from a merge conflict. - */ -function extractConflictVariants(str) { - const variants = [[], []]; - const lines = str.split(/\r?\n/g); - let skip = false; + return { + matcher: new Minimatch(pattern, { dot: true }), + gmatcher: gmatcher + } +} - while (lines.length) { - const line = lines.shift(); - if (line.startsWith(MERGE_CONFLICT_START)) { - // get the first variant - while (lines.length) { - const conflictLine = lines.shift(); - if (conflictLine === MERGE_CONFLICT_SEP) { - skip = false; - break; - } else if (skip || conflictLine.startsWith(MERGE_CONFLICT_ANCESTOR)) { - skip = true; - continue; - } else { - variants[0].push(conflictLine); - } - } +function setopts (self, pattern, options) { + if (!options) + options = {} - // get the second variant - while (lines.length) { - const conflictLine = lines.shift(); - if (conflictLine.startsWith(MERGE_CONFLICT_END)) { - break; - } else { - variants[1].push(conflictLine); - } - } - } else { - variants[0].push(line); - variants[1].push(line); + // base-matching: just use globstar for that. + if (options.matchBase && -1 === pattern.indexOf("/")) { + if (options.noglobstar) { + throw new Error("base matching requires globstar") } + pattern = "**/" + pattern } - return [variants[0].join('\n'), variants[1].join('\n')]; -} + self.silent = !!options.silent + self.pattern = pattern + self.strict = options.strict !== false + self.realpath = !!options.realpath + self.realpathCache = options.realpathCache || Object.create(null) + self.follow = !!options.follow + self.dot = !!options.dot + self.mark = !!options.mark + self.nodir = !!options.nodir + if (self.nodir) + self.mark = true + self.sync = !!options.sync + self.nounique = !!options.nounique + self.nonull = !!options.nonull + self.nosort = !!options.nosort + self.nocase = !!options.nocase + self.stat = !!options.stat + self.noprocess = !!options.noprocess + self.absolute = !!options.absolute -/** - * Check if a lockfile has merge conflicts. - */ -function hasMergeConflicts(str) { - return str.includes(MERGE_CONFLICT_START) && str.includes(MERGE_CONFLICT_SEP) && str.includes(MERGE_CONFLICT_END); -} + self.maxLength = options.maxLength || Infinity + self.cache = options.cache || Object.create(null) + self.statCache = options.statCache || Object.create(null) + self.symlinks = options.symlinks || Object.create(null) -/** - * Parse the lockfile. - */ -function parse(str, fileLoc) { - const parser = new Parser(str, fileLoc); - parser.next(); - return parser.parse(); -} + setupIgnores(self, options) -/** - * Parse and merge the two variants in a conflicted lockfile. - */ -function parseWithConflict(str, fileLoc) { - const variants = extractConflictVariants(str); - try { - return { type: 'merge', object: Object.assign({}, parse(variants[0], fileLoc), parse(variants[1], fileLoc)) }; - } catch (err) { - if (err instanceof SyntaxError) { - return { type: 'conflict', object: {} }; - } else { - throw err; - } + self.changedCwd = false + var cwd = process.cwd() + if (!ownProp(options, "cwd")) + self.cwd = cwd + else { + self.cwd = path.resolve(options.cwd) + self.changedCwd = self.cwd !== cwd } -} - -/***/ }), -/* 82 */, -/* 83 */, -/* 84 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; + self.root = options.root || path.resolve(self.cwd, "/") + self.root = path.resolve(self.root) + if (process.platform === "win32") + self.root = self.root.replace(/\\/g, "/") -Object.defineProperty(exports, "__esModule", { - value: true -}); + // TODO: is an absolute `cwd` supposed to be resolved against `root`? + // e.g. { cwd: '/test', root: __dirname } === path.join(__dirname, '/test') + self.cwdAbs = isAbsolute(self.cwd) ? self.cwd : makeAbs(self, self.cwd) + if (process.platform === "win32") + self.cwdAbs = self.cwdAbs.replace(/\\/g, "/") + self.nomount = !!options.nomount -var _map; + // disable comments and negation in Minimatch. + // Note that they are not supported in Glob itself anyway. + options.nonegate = true + options.nocomment = true -function _load_map() { - return _map = _interopRequireDefault(__webpack_require__(20)); + self.minimatch = new Minimatch(pattern, options) + self.options = self.minimatch.options } -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +function finish (self) { + var nou = self.nounique + var all = nou ? [] : Object.create(null) -const debug = __webpack_require__(212)('yarn'); + for (var i = 0, l = self.matches.length; i < l; i ++) { + var matches = self.matches[i] + if (!matches || Object.keys(matches).length === 0) { + if (self.nonull) { + // do like the shell, and spit out the literal glob + var literal = self.minimatch.globSet[i] + if (nou) + all.push(literal) + else + all[literal] = true + } + } else { + // had matches + var m = Object.keys(matches) + if (nou) + all.push.apply(all, m) + else + m.forEach(function (m) { + all[m] = true + }) + } + } -class BlockingQueue { - constructor(alias, maxConcurrency = Infinity) { - this.concurrencyQueue = []; - this.maxConcurrency = maxConcurrency; - this.runningCount = 0; - this.warnedStuck = false; - this.alias = alias; - this.first = true; + if (!nou) + all = Object.keys(all) - this.running = (0, (_map || _load_map()).default)(); - this.queue = (0, (_map || _load_map()).default)(); + if (!self.nosort) + all = all.sort(self.nocase ? alphasorti : alphasort) - this.stuckTick = this.stuckTick.bind(this); + // at *some* point we statted all of these + if (self.mark) { + for (var i = 0; i < all.length; i++) { + all[i] = self._mark(all[i]) + } + if (self.nodir) { + all = all.filter(function (e) { + var notDir = !(/\/$/.test(e)) + var c = self.cache[e] || self.cache[makeAbs(self, e)] + if (notDir && c) + notDir = c !== 'DIR' && !Array.isArray(c) + return notDir + }) + } } - stillActive() { - if (this.stuckTimer) { - clearTimeout(this.stuckTimer); - } + if (self.ignore.length) + all = all.filter(function(m) { + return !isIgnored(self, m) + }) - this.stuckTimer = setTimeout(this.stuckTick, 5000); + self.found = all +} - // We need to check the existence of unref because of https://github.com/facebook/jest/issues/4559 - // $FlowFixMe: Node's setInterval returns a Timeout, not a Number - this.stuckTimer.unref && this.stuckTimer.unref(); - } +function mark (self, p) { + var abs = makeAbs(self, p) + var c = self.cache[abs] + var m = p + if (c) { + var isDir = c === 'DIR' || Array.isArray(c) + var slash = p.slice(-1) === '/' - stuckTick() { - if (this.runningCount === 1) { - this.warnedStuck = true; - debug(`The ${JSON.stringify(this.alias)} blocking queue may be stuck. 5 seconds ` + `without any activity with 1 worker: ${Object.keys(this.running)[0]}`); - } - } + if (isDir && !slash) + m += '/' + else if (!isDir && slash) + m = m.slice(0, -1) - push(key, factory) { - if (this.first) { - this.first = false; - } else { - this.stillActive(); + if (m !== p) { + var mabs = makeAbs(self, m) + self.statCache[mabs] = self.statCache[abs] + self.cache[mabs] = self.cache[abs] } + } - return new Promise((resolve, reject) => { - // we're already running so push ourselves to the queue - const queue = this.queue[key] = this.queue[key] || []; - queue.push({ factory, resolve, reject }); + return m +} - if (!this.running[key]) { - this.shift(key); - } - }); +// lotta situps... +function makeAbs (self, f) { + var abs = f + if (f.charAt(0) === '/') { + abs = path.join(self.root, f) + } else if (isAbsolute(f) || f === '') { + abs = f + } else if (self.changedCwd) { + abs = path.resolve(self.cwd, f) + } else { + abs = path.resolve(f) } - shift(key) { - if (this.running[key]) { - delete this.running[key]; - this.runningCount--; + if (process.platform === 'win32') + abs = abs.replace(/\\/g, '/') - if (this.stuckTimer) { - clearTimeout(this.stuckTimer); - this.stuckTimer = null; - } + return abs +} - if (this.warnedStuck) { - this.warnedStuck = false; - debug(`${JSON.stringify(this.alias)} blocking queue finally resolved. Nothing to worry about.`); - } - } - const queue = this.queue[key]; - if (!queue) { - return; - } +// Return true, if pattern ends with globstar '**', for the accompanying parent directory. +// Ex:- If node_modules/** is the pattern, add 'node_modules' to ignore list along with it's contents +function isIgnored (self, path) { + if (!self.ignore.length) + return false - var _queue$shift = queue.shift(); + return self.ignore.some(function(item) { + return item.matcher.match(path) || !!(item.gmatcher && item.gmatcher.match(path)) + }) +} - const resolve = _queue$shift.resolve, - reject = _queue$shift.reject, - factory = _queue$shift.factory; +function childrenIgnored (self, path) { + if (!self.ignore.length) + return false - if (!queue.length) { - delete this.queue[key]; - } + return self.ignore.some(function(item) { + return !!(item.gmatcher && item.gmatcher.match(path)) + }) +} - const next = () => { - this.shift(key); - this.shiftConcurrencyQueue(); - }; - const run = () => { - this.running[key] = true; - this.runningCount++; +/***/ }), +/* 116 */ +/***/ (function(module, exports, __webpack_require__) { - factory().then(function (val) { - resolve(val); - next(); - return null; - }).catch(function (err) { - reject(err); - next(); - }); - }; +var path = __webpack_require__(0); +var fs = __webpack_require__(3); +var _0777 = parseInt('0777', 8); - this.maybePushConcurrencyQueue(run); - } +module.exports = mkdirP.mkdirp = mkdirP.mkdirP = mkdirP; - maybePushConcurrencyQueue(run) { - if (this.runningCount < this.maxConcurrency) { - run(); - } else { - this.concurrencyQueue.push(run); +function mkdirP (p, opts, f, made) { + if (typeof opts === 'function') { + f = opts; + opts = {}; } - } - - shiftConcurrencyQueue() { - if (this.runningCount < this.maxConcurrency) { - const fn = this.concurrencyQueue.shift(); - if (fn) { - fn(); - } + else if (!opts || typeof opts !== 'object') { + opts = { mode: opts }; } - } + + var mode = opts.mode; + var xfs = opts.fs || fs; + + if (mode === undefined) { + mode = _0777 & (~process.umask()); + } + if (!made) made = null; + + var cb = f || function () {}; + p = path.resolve(p); + + xfs.mkdir(p, mode, function (er) { + if (!er) { + made = made || p; + return cb(null, made); + } + switch (er.code) { + case 'ENOENT': + mkdirP(path.dirname(p), opts, function (er, made) { + if (er) cb(er, made); + else mkdirP(p, opts, cb, made); + }); + break; + + // In the case of any other error, just see if there's a dir + // there already. If so, then hooray! If not, then something + // is borked. + default: + xfs.stat(p, function (er2, stat) { + // if the stat fails, then that's super weird. + // let the original error be the failure reason. + if (er2 || !stat.isDirectory()) cb(er, made) + else cb(null, made); + }); + break; + } + }); } -exports.default = BlockingQueue; -/***/ }), -/* 85 */ -/***/ (function(module, exports) { +mkdirP.sync = function sync (p, opts, made) { + if (!opts || typeof opts !== 'object') { + opts = { mode: opts }; + } + + var mode = opts.mode; + var xfs = opts.fs || fs; + + if (mode === undefined) { + mode = _0777 & (~process.umask()); + } + if (!made) made = null; -module.exports = function (exec) { - try { - return !!exec(); - } catch (e) { - return true; - } + p = path.resolve(p); + + try { + xfs.mkdirSync(p, mode); + made = made || p; + } + catch (err0) { + switch (err0.code) { + case 'ENOENT' : + made = sync(path.dirname(p), opts, made); + sync(p, opts, made); + break; + + // In the case of any other error, just see if there's a dir + // there already. If so, then hooray! If not, then something + // is borked. + default: + var stat; + try { + stat = xfs.statSync(p); + } + catch (err1) { + throw err0; + } + if (!stat.isDirectory()) throw err0; + break; + } + } + + return made; }; /***/ }), -/* 86 */, -/* 87 */, -/* 88 */, -/* 89 */, -/* 90 */, -/* 91 */, -/* 92 */, -/* 93 */, -/* 94 */, -/* 95 */, -/* 96 */, -/* 97 */, -/* 98 */, -/* 99 */, -/* 100 */ +/* 117 */, +/* 118 */, +/* 119 */, +/* 120 */, +/* 121 */, +/* 122 */ /***/ (function(module, exports, __webpack_require__) { -// getting tag from 19.1.3.6 Object.prototype.toString() -var cof = __webpack_require__(47); -var TAG = __webpack_require__(13)('toStringTag'); -// ES3 wrong here -var ARG = cof(function () { return arguments; }()) == 'Arguments'; +"use strict"; -// fallback for IE11 Script Access Denied error -var tryGet = function (it, key) { - try { - return it[key]; - } catch (e) { /* empty */ } -}; +module.exports = x => { + if (typeof x !== 'string') { + throw new TypeError('Expected a string, got ' + typeof x); + } -module.exports = function (it) { - var O, T, B; - return it === undefined ? 'Undefined' : it === null ? 'Null' - // @@toStringTag case - : typeof (T = tryGet(O = Object(it), TAG)) == 'string' ? T - // builtinTag case - : ARG ? cof(O) - // ES3 arguments fallback - : (B = cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B; + // Catches EFBBBF (UTF-8 BOM) because the buffer-to-string + // conversion translates it to FEFF (UTF-16 BOM) + if (x.charCodeAt(0) === 0xFEFF) { + return x.slice(1); + } + + return x; }; /***/ }), -/* 101 */ +/* 123 */ /***/ (function(module, exports) { -// IE 8- don't enum bug keys -module.exports = ( - 'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf' -).split(','); - - -/***/ }), -/* 102 */ -/***/ (function(module, exports, __webpack_require__) { - -var document = __webpack_require__(11).document; -module.exports = document && document.documentElement; +// Returns a wrapper function that returns a wrapped callback +// The wrapper function should do some stuff, and return a +// presumably different callback function. +// This makes sure that own properties are retained, so that +// decorations and such are not lost along the way. +module.exports = wrappy +function wrappy (fn, cb) { + if (fn && cb) return wrappy(fn)(cb) + if (typeof fn !== 'function') + throw new TypeError('need wrapper function') -/***/ }), -/* 103 */ -/***/ (function(module, exports, __webpack_require__) { + Object.keys(fn).forEach(function (k) { + wrapper[k] = fn[k] + }) -"use strict"; + return wrapper -var LIBRARY = __webpack_require__(69); -var $export = __webpack_require__(41); -var redefine = __webpack_require__(197); -var hide = __webpack_require__(31); -var Iterators = __webpack_require__(35); -var $iterCreate = __webpack_require__(188); -var setToStringTag = __webpack_require__(71); -var getPrototypeOf = __webpack_require__(194); -var ITERATOR = __webpack_require__(13)('iterator'); -var BUGGY = !([].keys && 'next' in [].keys()); // Safari has buggy iterators w/o `next` -var FF_ITERATOR = '@@iterator'; -var KEYS = 'keys'; -var VALUES = 'values'; - -var returnThis = function () { return this; }; - -module.exports = function (Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED) { - $iterCreate(Constructor, NAME, next); - var getMethod = function (kind) { - if (!BUGGY && kind in proto) return proto[kind]; - switch (kind) { - case KEYS: return function keys() { return new Constructor(this, kind); }; - case VALUES: return function values() { return new Constructor(this, kind); }; - } return function entries() { return new Constructor(this, kind); }; - }; - var TAG = NAME + ' Iterator'; - var DEF_VALUES = DEFAULT == VALUES; - var VALUES_BUG = false; - var proto = Base.prototype; - var $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT]; - var $default = $native || getMethod(DEFAULT); - var $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined; - var $anyNative = NAME == 'Array' ? proto.entries || $native : $native; - var methods, key, IteratorPrototype; - // Fix native - if ($anyNative) { - IteratorPrototype = getPrototypeOf($anyNative.call(new Base())); - if (IteratorPrototype !== Object.prototype && IteratorPrototype.next) { - // Set @@toStringTag to native iterators - setToStringTag(IteratorPrototype, TAG, true); - // fix for some old engines - if (!LIBRARY && typeof IteratorPrototype[ITERATOR] != 'function') hide(IteratorPrototype, ITERATOR, returnThis); + function wrapper() { + var args = new Array(arguments.length) + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i] } + var ret = fn.apply(this, args) + var cb = args[args.length-1] + if (typeof ret === 'function' && ret !== cb) { + Object.keys(cb).forEach(function (k) { + ret[k] = cb[k] + }) + } + return ret } - // fix Array#{values, @@iterator}.name in V8 / FF - if (DEF_VALUES && $native && $native.name !== VALUES) { - VALUES_BUG = true; - $default = function values() { return $native.call(this); }; - } - // Define iterator - if ((!LIBRARY || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])) { - hide(proto, ITERATOR, $default); - } - // Plug for library - Iterators[NAME] = $default; - Iterators[TAG] = returnThis; - if (DEFAULT) { - methods = { - values: DEF_VALUES ? $default : getMethod(VALUES), - keys: IS_SET ? $default : getMethod(KEYS), - entries: $entries - }; - if (FORCED) for (key in methods) { - if (!(key in proto)) redefine(proto, key, methods[key]); - } else $export($export.P + $export.F * (BUGGY || VALUES_BUG), NAME, methods); - } - return methods; -}; - - -/***/ }), -/* 104 */ -/***/ (function(module, exports) { - -module.exports = function (exec) { - try { - return { e: false, v: exec() }; - } catch (e) { - return { e: true, v: e }; - } -}; +} /***/ }), -/* 105 */ +/* 124 */, +/* 125 */, +/* 126 */, +/* 127 */, +/* 128 */, +/* 129 */, +/* 130 */, +/* 131 */ /***/ (function(module, exports, __webpack_require__) { -var anObject = __webpack_require__(27); -var isObject = __webpack_require__(34); -var newPromiseCapability = __webpack_require__(70); - -module.exports = function (C, x) { - anObject(C); - if (isObject(x) && x.constructor === C) return x; - var promiseCapability = newPromiseCapability.f(C); - var resolve = promiseCapability.resolve; - resolve(x); - return promiseCapability.promise; -}; - - -/***/ }), -/* 106 */ -/***/ (function(module, exports) { - -module.exports = function (bitmap, value) { - return { - enumerable: !(bitmap & 1), - configurable: !(bitmap & 2), - writable: !(bitmap & 4), - value: value - }; +// fallback for non-array-like ES3 and non-enumerable old V8 strings +var cof = __webpack_require__(47); +// eslint-disable-next-line no-prototype-builtins +module.exports = Object('z').propertyIsEnumerable(0) ? Object : function (it) { + return cof(it) == 'String' ? it.split('') : Object(it); }; /***/ }), -/* 107 */ -/***/ (function(module, exports, __webpack_require__) { - -var core = __webpack_require__(23); -var global = __webpack_require__(11); -var SHARED = '__core-js_shared__'; -var store = global[SHARED] || (global[SHARED] = {}); - -(module.exports = function (key, value) { - return store[key] || (store[key] = value !== undefined ? value : {}); -})('versions', []).push({ - version: core.version, - mode: __webpack_require__(69) ? 'pure' : 'global', - copyright: '© 2018 Denis Pushkarev (zloirock.ru)' -}); - - -/***/ }), -/* 108 */ +/* 132 */ /***/ (function(module, exports, __webpack_require__) { -// 7.3.20 SpeciesConstructor(O, defaultConstructor) -var anObject = __webpack_require__(27); -var aFunction = __webpack_require__(46); -var SPECIES = __webpack_require__(13)('species'); -module.exports = function (O, D) { - var C = anObject(O).constructor; - var S; - return C === undefined || (S = anObject(C)[SPECIES]) == undefined ? D : aFunction(S); -}; - - -/***/ }), -/* 109 */ -/***/ (function(module, exports, __webpack_require__) { +// 19.1.2.14 / 15.2.3.14 Object.keys(O) +var $keys = __webpack_require__(195); +var enumBugKeys = __webpack_require__(101); -var ctx = __webpack_require__(48); -var invoke = __webpack_require__(185); -var html = __webpack_require__(102); -var cel = __webpack_require__(68); -var global = __webpack_require__(11); -var process = global.process; -var setTask = global.setImmediate; -var clearTask = global.clearImmediate; -var MessageChannel = global.MessageChannel; -var Dispatch = global.Dispatch; -var counter = 0; -var queue = {}; -var ONREADYSTATECHANGE = 'onreadystatechange'; -var defer, channel, port; -var run = function () { - var id = +this; - // eslint-disable-next-line no-prototype-builtins - if (queue.hasOwnProperty(id)) { - var fn = queue[id]; - delete queue[id]; - fn(); - } -}; -var listener = function (event) { - run.call(event.data); -}; -// Node.js 0.9+ & IE10+ has setImmediate, otherwise: -if (!setTask || !clearTask) { - setTask = function setImmediate(fn) { - var args = []; - var i = 1; - while (arguments.length > i) args.push(arguments[i++]); - queue[++counter] = function () { - // eslint-disable-next-line no-new-func - invoke(typeof fn == 'function' ? fn : Function(fn), args); - }; - defer(counter); - return counter; - }; - clearTask = function clearImmediate(id) { - delete queue[id]; - }; - // Node.js 0.8- - if (__webpack_require__(47)(process) == 'process') { - defer = function (id) { - process.nextTick(ctx(run, id, 1)); - }; - // Sphere (JS game engine) Dispatch API - } else if (Dispatch && Dispatch.now) { - defer = function (id) { - Dispatch.now(ctx(run, id, 1)); - }; - // Browsers with MessageChannel, includes WebWorkers - } else if (MessageChannel) { - channel = new MessageChannel(); - port = channel.port2; - channel.port1.onmessage = listener; - defer = ctx(port.postMessage, port, 1); - // Browsers with postMessage, skip WebWorkers - // IE8 has postMessage, but it's sync & typeof its postMessage is 'object' - } else if (global.addEventListener && typeof postMessage == 'function' && !global.importScripts) { - defer = function (id) { - global.postMessage(id + '', '*'); - }; - global.addEventListener('message', listener, false); - // IE8- - } else if (ONREADYSTATECHANGE in cel('script')) { - defer = function (id) { - html.appendChild(cel('script'))[ONREADYSTATECHANGE] = function () { - html.removeChild(this); - run.call(id); - }; - }; - // Rest old browsers - } else { - defer = function (id) { - setTimeout(ctx(run, id, 1), 0); - }; - } -} -module.exports = { - set: setTask, - clear: clearTask +module.exports = Object.keys || function keys(O) { + return $keys(O, enumBugKeys); }; /***/ }), -/* 110 */ +/* 133 */ /***/ (function(module, exports, __webpack_require__) { -// 7.1.15 ToLength -var toInteger = __webpack_require__(73); -var min = Math.min; +// 7.1.13 ToObject(argument) +var defined = __webpack_require__(67); module.exports = function (it) { - return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991 + return Object(defined(it)); }; /***/ }), -/* 111 */ +/* 134 */, +/* 135 */, +/* 136 */, +/* 137 */, +/* 138 */, +/* 139 */, +/* 140 */, +/* 141 */, +/* 142 */, +/* 143 */, +/* 144 */, +/* 145 */ /***/ (function(module, exports) { -var id = 0; -var px = Math.random(); -module.exports = function (key) { - return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36)); -}; - +module.exports = {"name":"yarn","installationMethod":"unknown","version":"1.10.0-0","license":"BSD-2-Clause","preferGlobal":true,"description":"📦🐈 Fast, reliable, and secure dependency management.","dependencies":{"@zkochan/cmd-shim":"^2.2.4","babel-runtime":"^6.26.0","bytes":"^3.0.0","camelcase":"^4.0.0","chalk":"^2.1.0","commander":"^2.9.0","death":"^1.0.0","debug":"^3.0.0","deep-equal":"^1.0.1","detect-indent":"^5.0.0","dnscache":"^1.0.1","glob":"^7.1.1","gunzip-maybe":"^1.4.0","hash-for-dep":"^1.2.3","imports-loader":"^0.8.0","ini":"^1.3.4","inquirer":"^3.0.1","invariant":"^2.2.0","is-builtin-module":"^2.0.0","is-ci":"^1.0.10","is-webpack-bundle":"^1.0.0","leven":"^2.0.0","loud-rejection":"^1.2.0","micromatch":"^2.3.11","mkdirp":"^0.5.1","node-emoji":"^1.6.1","normalize-url":"^2.0.0","npm-logical-tree":"^1.2.1","object-path":"^0.11.2","proper-lockfile":"^2.0.0","puka":"^1.0.0","read":"^1.0.7","request":"^2.87.0","request-capture-har":"^1.2.2","rimraf":"^2.5.0","semver":"^5.1.0","ssri":"^5.3.0","strip-ansi":"^4.0.0","strip-bom":"^3.0.0","tar-fs":"^1.16.0","tar-stream":"^1.6.1","uuid":"^3.0.1","v8-compile-cache":"^2.0.0","validate-npm-package-license":"^3.0.3","yn":"^2.0.0"},"devDependencies":{"babel-core":"^6.26.0","babel-eslint":"^7.2.3","babel-loader":"^6.2.5","babel-plugin-array-includes":"^2.0.3","babel-plugin-transform-builtin-extend":"^1.1.2","babel-plugin-transform-inline-imports-commonjs":"^1.0.0","babel-plugin-transform-runtime":"^6.4.3","babel-preset-env":"^1.6.0","babel-preset-flow":"^6.23.0","babel-preset-stage-0":"^6.0.0","babylon":"^6.5.0","commitizen":"^2.9.6","cz-conventional-changelog":"^2.0.0","eslint":"^4.3.0","eslint-config-fb-strict":"^22.0.0","eslint-plugin-babel":"^5.0.0","eslint-plugin-flowtype":"^2.35.0","eslint-plugin-jasmine":"^2.6.2","eslint-plugin-jest":"^21.0.0","eslint-plugin-jsx-a11y":"^6.0.2","eslint-plugin-prefer-object-spread":"^1.2.1","eslint-plugin-prettier":"^2.1.2","eslint-plugin-react":"^7.1.0","eslint-plugin-relay":"^0.0.24","eslint-plugin-yarn-internal":"file:scripts/eslint-rules","execa":"^0.10.0","flow-bin":"^0.66.0","git-release-notes":"^3.0.0","gulp":"^3.9.0","gulp-babel":"^7.0.0","gulp-if":"^2.0.1","gulp-newer":"^1.0.0","gulp-plumber":"^1.0.1","gulp-sourcemaps":"^2.2.0","gulp-util":"^3.0.7","gulp-watch":"^5.0.0","jest":"^22.4.4","jsinspect":"^0.12.6","minimatch":"^3.0.4","mock-stdin":"^0.3.0","prettier":"^1.5.2","temp":"^0.8.3","webpack":"^2.1.0-beta.25","yargs":"^6.3.0"},"resolutions":{"sshpk":"^1.14.2"},"engines":{"node":">=4.0.0"},"repository":"yarnpkg/yarn","bin":{"yarn":"./bin/yarn.js","yarnpkg":"./bin/yarn.js"},"scripts":{"build":"gulp build","build-bundle":"node ./scripts/build-webpack.js","build-chocolatey":"powershell ./scripts/build-chocolatey.ps1","build-deb":"./scripts/build-deb.sh","build-dist":"bash ./scripts/build-dist.sh","build-win-installer":"scripts\\build-windows-installer.bat","changelog":"git-release-notes $(git describe --tags --abbrev=0 $(git describe --tags --abbrev=0)^)..$(git describe --tags --abbrev=0) scripts/changelog.md","dupe-check":"yarn jsinspect ./src","lint":"eslint . && flow check","pkg-tests":"yarn --cwd packages/pkg-tests jest yarn.test.js","prettier":"eslint src __tests__ --fix","release-branch":"./scripts/release-branch.sh","test":"yarn lint && yarn test-only","test-only":"node --max_old_space_size=4096 node_modules/jest/bin/jest.js --verbose","test-only-debug":"node --inspect-brk --max_old_space_size=4096 node_modules/jest/bin/jest.js --runInBand --verbose","test-coverage":"node --max_old_space_size=4096 node_modules/jest/bin/jest.js --coverage --verbose","watch":"gulp watch","commit":"git-cz"},"jest":{"collectCoverageFrom":["src/**/*.js"],"testEnvironment":"node","modulePathIgnorePatterns":["__tests__/fixtures/","packages/pkg-tests/pkg-tests-fixtures","dist/"],"testPathIgnorePatterns":["__tests__/(fixtures|__mocks__)/","updates/","_(temp|mock|install|init|helpers).js$","packages/pkg-tests"]},"config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}}} /***/ }), -/* 112 */ +/* 146 */, +/* 147 */, +/* 148 */, +/* 149 */, +/* 150 */ /***/ (function(module, exports, __webpack_require__) { +"use strict"; -/** - * This is the common logic for both the Node.js and web browser - * implementations of `debug()`. - * - * Expose `debug()` as the module. - */ -exports = module.exports = createDebug.debug = createDebug['default'] = createDebug; -exports.coerce = coerce; -exports.disable = disable; -exports.enable = enable; -exports.enabled = enabled; -exports.humanize = __webpack_require__(229); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = stringify; -/** - * Active `debug` instances. - */ -exports.instances = []; +var _misc; -/** - * The currently active debug mode names, and names to skip. - */ +function _load_misc() { + return _misc = __webpack_require__(12); +} -exports.names = []; -exports.skips = []; +var _constants; -/** - * 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". - */ +function _load_constants() { + return _constants = __webpack_require__(6); +} -exports.formatters = {}; +var _package; -/** - * Select a color. - * @param {String} namespace - * @return {Number} - * @api private - */ +function _load_package() { + return _package = __webpack_require__(145); +} -function selectColor(namespace) { - var hash = 0, i; +const NODE_VERSION = process.version; - for (i in namespace) { - hash = ((hash << 5) - hash) + namespace.charCodeAt(i); - hash |= 0; // Convert to 32bit integer - } +function shouldWrapKey(str) { + return str.indexOf('true') === 0 || str.indexOf('false') === 0 || /[:\s\n\\",\[\]]/g.test(str) || /^[0-9]/g.test(str) || !/^[a-zA-Z]/g.test(str); +} - return exports.colors[Math.abs(hash) % exports.colors.length]; +function maybeWrap(str) { + if (typeof str === 'boolean' || typeof str === 'number' || shouldWrapKey(str)) { + return JSON.stringify(str); + } else { + return str; + } } -/** - * Create a debugger with the given `namespace`. - * - * @param {String} namespace - * @return {Function} - * @api public - */ +const priorities = { + name: 1, + version: 2, + uid: 3, + resolved: 4, + integrity: 5, + registry: 6, + dependencies: 7 +}; -function createDebug(namespace) { +function priorityThenAlphaSort(a, b) { + if (priorities[a] || priorities[b]) { + return (priorities[a] || 100) > (priorities[b] || 100) ? 1 : -1; + } else { + return (0, (_misc || _load_misc()).sortAlpha)(a, b); + } +} - var prevTime; +function _stringify(obj, options) { + if (typeof obj !== 'object') { + throw new TypeError(); + } - function debug() { - // disabled? - if (!debug.enabled) return; + const indent = options.indent; + const lines = []; - var self = debug; + // Sorting order needs to be consistent between runs, we run native sort by name because there are no + // problems with it being unstable because there are no to keys the same + // However priorities can be duplicated and native sort can shuffle things from run to run + const keys = Object.keys(obj).sort(priorityThenAlphaSort); - // set `diff` timestamp - var curr = +new Date(); - var ms = curr - (prevTime || curr); - self.diff = ms; - self.prev = prevTime; - self.curr = curr; - prevTime = curr; + let addedKeys = []; - // turn the `arguments` into a proper Array - var args = new Array(arguments.length); - for (var i = 0; i < args.length; i++) { - args[i] = arguments[i]; + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + const val = obj[key]; + if (val == null || addedKeys.indexOf(key) >= 0) { + continue; } - args[0] = exports.coerce(args[0]); + const valKeys = [key]; - if ('string' !== typeof args[0]) { - // anything else let's inspect with %O - args.unshift('%O'); + // get all keys that have the same value equality, we only want this for objects + if (typeof val === 'object') { + for (let j = i + 1; j < keys.length; j++) { + const key = keys[j]; + if (val === obj[key]) { + valKeys.push(key); + } + } } - // apply any `formatters` transformations - var index = 0; - args[0] = args[0].replace(/%([a-zA-Z%])/g, function(match, format) { - // if we encounter an escaped % then don't increase the array index - if (match === '%%') return match; - index++; - var formatter = exports.formatters[format]; - if ('function' === typeof formatter) { - var 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; - }); + const keyLine = valKeys.sort((_misc || _load_misc()).sortAlpha).map(maybeWrap).join(', '); - // apply env-specific formatting (colors, etc.) - exports.formatArgs.call(self, args); + if (typeof val === 'string' || typeof val === 'boolean' || typeof val === 'number') { + lines.push(`${keyLine} ${maybeWrap(val)}`); + } else if (typeof val === 'object') { + lines.push(`${keyLine}:\n${_stringify(val, { indent: indent + ' ' })}` + (options.topLevel ? '\n' : '')); + } else { + throw new TypeError(); + } - var logFn = debug.log || exports.log || console.log.bind(console); - logFn.apply(self, args); + addedKeys = addedKeys.concat(valKeys); } - debug.namespace = namespace; - debug.enabled = exports.enabled(namespace); - debug.useColors = exports.useColors(); - debug.color = selectColor(namespace); - debug.destroy = destroy; + return indent + lines.join(`\n${indent}`); +} - // env-specific initialization logic for debug instances - if ('function' === typeof exports.init) { - exports.init(debug); +function stringify(obj, noHeader, enableVersions) { + const val = _stringify(obj, { + indent: '', + topLevel: true + }); + if (noHeader) { + return val; } - exports.instances.push(debug); + const lines = []; + lines.push('# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.'); + lines.push(`# yarn lockfile v${(_constants || _load_constants()).LOCKFILE_VERSION}`); + if (enableVersions) { + lines.push(`# yarn v${(_package || _load_package()).version}`); + lines.push(`# node ${NODE_VERSION}`); + } + lines.push('\n'); + lines.push(val); - return debug; + return lines.join('\n'); } -function destroy () { - var index = exports.instances.indexOf(this); - if (index !== -1) { - exports.instances.splice(index, 1); - return true; - } else { - return false; - } -} +/***/ }), +/* 151 */, +/* 152 */, +/* 153 */, +/* 154 */, +/* 155 */, +/* 156 */, +/* 157 */, +/* 158 */, +/* 159 */, +/* 160 */, +/* 161 */, +/* 162 */, +/* 163 */, +/* 164 */ +/***/ (function(module, exports, __webpack_require__) { -/** - * Enables a debug mode by namespaces. This can include modes - * separated by a colon and wildcards. - * - * @param {String} namespaces - * @api public - */ +"use strict"; -function enable(namespaces) { - exports.save(namespaces); - exports.names = []; - exports.skips = []; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.fileDatesEqual = exports.copyFile = exports.unlink = undefined; - var i; - var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/); - var len = split.length; +var _asyncToGenerator2; - for (i = 0; i < len; i++) { - if (!split[i]) continue; // ignore empty strings - namespaces = split[i].replace(/\*/g, '.*?'); - if (namespaces[0] === '-') { - exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); - } else { - exports.names.push(new RegExp('^' + namespaces + '$')); +function _load_asyncToGenerator() { + return _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(1)); +} + +// We want to preserve file timestamps when copying a file, since yarn uses them to decide if a file has +// changed compared to the cache. +// There are some OS specific cases here: +// * On linux, fs.copyFile does not preserve timestamps, but does on OSX and Win. +// * On windows, you must open a file with write permissions to call `fs.futimes`. +// * On OSX you can open with read permissions and still call `fs.futimes`. +let fixTimes = (() => { + var _ref3 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (fd, dest, data) { + const doOpen = fd === undefined; + let openfd = fd ? fd : -1; + + if (disableTimestampCorrection === undefined) { + // if timestamps match already, no correction is needed. + // the need to correct timestamps varies based on OS and node versions. + const destStat = yield lstat(dest); + disableTimestampCorrection = fileDatesEqual(destStat.mtime, data.mtime); } - } - for (i = 0; i < exports.instances.length; i++) { - var instance = exports.instances[i]; - instance.enabled = exports.enabled(instance.namespace); - } + if (disableTimestampCorrection) { + return; + } + + if (doOpen) { + try { + openfd = yield open(dest, 'a', data.mode); + } catch (er) { + // file is likely read-only + try { + openfd = yield open(dest, 'r', data.mode); + } catch (err) { + // We can't even open this file for reading. + return; + } + } + } + + try { + if (openfd) { + yield futimes(openfd, data.atime, data.mtime); + } + } catch (er) { + // If `futimes` throws an exception, we probably have a case of a read-only file on Windows. + // In this case we can just return. The incorrect timestamp will just cause that file to be recopied + // on subsequent installs, which will effect yarn performance but not break anything. + } finally { + if (doOpen && openfd) { + yield close(openfd); + } + } + }); + + return function fixTimes(_x7, _x8, _x9) { + return _ref3.apply(this, arguments); + }; +})(); + +// Compare file timestamps. +// Some versions of Node on windows zero the milliseconds when utime is used. + + +var _fs; + +function _load_fs() { + return _fs = _interopRequireDefault(__webpack_require__(3)); } -/** - * Disable debug output. - * - * @api public - */ +var _promise; -function disable() { - exports.enable(''); +function _load_promise() { + return _promise = __webpack_require__(40); } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// This module serves as a wrapper for file operations that are inconsistant across node and OS versions. + +let disableTimestampCorrection = undefined; // OS dependent. will be detected on first file copy. + +const readFileBuffer = (0, (_promise || _load_promise()).promisify)((_fs || _load_fs()).default.readFile); +const close = (0, (_promise || _load_promise()).promisify)((_fs || _load_fs()).default.close); +const lstat = (0, (_promise || _load_promise()).promisify)((_fs || _load_fs()).default.lstat); +const open = (0, (_promise || _load_promise()).promisify)((_fs || _load_fs()).default.open); +const futimes = (0, (_promise || _load_promise()).promisify)((_fs || _load_fs()).default.futimes); + +const write = (0, (_promise || _load_promise()).promisify)((_fs || _load_fs()).default.write); + +const unlink = exports.unlink = (0, (_promise || _load_promise()).promisify)(__webpack_require__(233)); + /** - * Returns true if the given mode name is enabled, false otherwise. - * - * @param {String} name - * @return {Boolean} - * @api public + * Unlinks the destination to force a recreation. This is needed on case-insensitive file systems + * to force the correct naming when the filename has changed only in character-casing. (Jest -> jest). */ +const copyFile = exports.copyFile = (() => { + var _ref = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (data, cleanup) { + try { + yield unlink(data.dest); + yield copyFilePoly(data.src, data.dest, 0, data); + } finally { + if (cleanup) { + cleanup(); + } + } + }); -function enabled(name) { - if (name[name.length - 1] === '*') { - return true; + return function copyFile(_x, _x2) { + return _ref.apply(this, arguments); + }; +})(); + +// Node 8.5.0 introduced `fs.copyFile` which is much faster, so use that when available. +// Otherwise we fall back to reading and writing files as buffers. +const copyFilePoly = (src, dest, flags, data) => { + if ((_fs || _load_fs()).default.copyFile) { + return new Promise((resolve, reject) => (_fs || _load_fs()).default.copyFile(src, dest, flags, err => { + if (err) { + reject(err); + } else { + fixTimes(undefined, dest, data).then(() => resolve()).catch(ex => reject(ex)); + } + })); + } else { + return copyWithBuffer(src, dest, flags, data); } - var i, len; - for (i = 0, len = exports.skips.length; i < len; i++) { - if (exports.skips[i].test(name)) { - return false; +}; + +const copyWithBuffer = (() => { + var _ref2 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (src, dest, flags, data) { + // Use open -> write -> futimes -> close sequence to avoid opening the file twice: + // one with writeFile and one with utimes + const fd = yield open(dest, 'w', data.mode); + try { + const buffer = yield readFileBuffer(src); + yield write(fd, buffer, 0, buffer.length); + yield fixTimes(fd, dest, data); + } finally { + yield close(fd); } + }); + + return function copyWithBuffer(_x3, _x4, _x5, _x6) { + return _ref2.apply(this, arguments); + }; +})();const fileDatesEqual = exports.fileDatesEqual = (a, b) => { + const aTime = a.getTime(); + const bTime = b.getTime(); + + if (process.platform !== 'win32') { + return aTime === bTime; } - for (i = 0, len = exports.names.length; i < len; i++) { - if (exports.names[i].test(name)) { - return true; - } + + // See https://github.com/nodejs/node/pull/12607 + // Submillisecond times from stat and utimes are truncated on Windows, + // causing a file with mtime 8.0079998 and 8.0081144 to become 8.007 and 8.008 + // and making it impossible to update these files to their correct timestamps. + if (Math.abs(aTime - bTime) <= 1) { + return true; } - return false; -} -/** - * Coerce `val`. - * - * @param {Mixed} val - * @return {Mixed} - * @api private - */ + const aTimeSec = Math.floor(aTime / 1000); + const bTimeSec = Math.floor(bTime / 1000); -function coerce(val) { - if (val instanceof Error) return val.stack || val.message; - return val; -} + // See https://github.com/nodejs/node/issues/2069 + // Some versions of Node on windows zero the milliseconds when utime is used + // So if any of the time has a milliseconds part of zero we suspect that the + // bug is present and compare only seconds. + if (aTime - aTimeSec * 1000 === 0 || bTime - bTimeSec * 1000 === 0) { + return aTimeSec === bTimeSec; + } + return aTime === bTime; +}; /***/ }), -/* 113 */, -/* 114 */ +/* 165 */, +/* 166 */, +/* 167 */, +/* 168 */, +/* 169 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = realpath -realpath.realpath = realpath -realpath.sync = realpathSync -realpath.realpathSync = realpathSync -realpath.monkeypatch = monkeypatch -realpath.unmonkeypatch = unmonkeypatch +"use strict"; -var fs = __webpack_require__(3) -var origRealpath = fs.realpath -var origRealpathSync = fs.realpathSync -var version = process.version -var ok = /^v[0-5]\./.test(version) -var old = __webpack_require__(217) +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.isFakeRoot = isFakeRoot; +exports.isRootUser = isRootUser; +function getUid() { + if (process.platform !== 'win32' && process.getuid) { + return process.getuid(); + } + return null; +} -function newError (er) { - return er && er.syscall === 'realpath' && ( - er.code === 'ELOOP' || - er.code === 'ENOMEM' || - er.code === 'ENAMETOOLONG' - ) +exports.default = isRootUser(getUid()) && !isFakeRoot(); +function isFakeRoot() { + return Boolean(process.env.FAKEROOTKEY); } -function realpath (p, cache, cb) { - if (ok) { - return origRealpath(p, cache, cb) - } +function isRootUser(uid) { + return uid === 0; +} - if (typeof cache === 'function') { - cb = cache - cache = null +/***/ }), +/* 170 */, +/* 171 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getDataDir = getDataDir; +exports.getCacheDir = getCacheDir; +exports.getConfigDir = getConfigDir; +const path = __webpack_require__(0); +const userHome = __webpack_require__(45).default; + +const FALLBACK_CONFIG_DIR = path.join(userHome, '.config', 'yarn'); +const FALLBACK_CACHE_DIR = path.join(userHome, '.cache', 'yarn'); + +function getDataDir() { + if (process.platform === 'win32') { + const WIN32_APPDATA_DIR = getLocalAppDataDir(); + return WIN32_APPDATA_DIR == null ? FALLBACK_CONFIG_DIR : path.join(WIN32_APPDATA_DIR, 'Data'); + } else if (process.env.XDG_DATA_HOME) { + return path.join(process.env.XDG_DATA_HOME, 'yarn'); + } else { + // This could arguably be ~/Library/Application Support/Yarn on Macs, + // but that feels unintuitive for a cli tool + + // Instead, use our prior fallback. Some day this could be + // path.join(userHome, '.local', 'share', 'yarn') + // or return path.join(WIN32_APPDATA_DIR, 'Data') on win32 + return FALLBACK_CONFIG_DIR; } - origRealpath(p, cache, function (er, result) { - if (newError(er)) { - old.realpath(p, cache, cb) - } else { - cb(er, result) - } - }) } -function realpathSync (p, cache) { - if (ok) { - return origRealpathSync(p, cache) +function getCacheDir() { + if (process.platform === 'win32') { + // process.env.TEMP also exists, but most apps put caches here + return path.join(getLocalAppDataDir() || path.join(userHome, 'AppData', 'Local', 'Yarn'), 'Cache'); + } else if (process.env.XDG_CACHE_HOME) { + return path.join(process.env.XDG_CACHE_HOME, 'yarn'); + } else if (process.platform === 'darwin') { + return path.join(userHome, 'Library', 'Caches', 'Yarn'); + } else { + return FALLBACK_CACHE_DIR; } +} - try { - return origRealpathSync(p, cache) - } catch (er) { - if (newError(er)) { - return old.realpathSync(p, cache) - } else { - throw er - } +function getConfigDir() { + if (process.platform === 'win32') { + // Use our prior fallback. Some day this could be + // return path.join(WIN32_APPDATA_DIR, 'Config') + const WIN32_APPDATA_DIR = getLocalAppDataDir(); + return WIN32_APPDATA_DIR == null ? FALLBACK_CONFIG_DIR : path.join(WIN32_APPDATA_DIR, 'Config'); + } else if (process.env.XDG_CONFIG_HOME) { + return path.join(process.env.XDG_CONFIG_HOME, 'yarn'); + } else { + return FALLBACK_CONFIG_DIR; } } -function monkeypatch () { - fs.realpath = realpath - fs.realpathSync = realpathSync +function getLocalAppDataDir() { + return process.env.LOCALAPPDATA ? path.join(process.env.LOCALAPPDATA, 'Yarn') : null; } -function unmonkeypatch () { - fs.realpath = origRealpath - fs.realpathSync = origRealpathSync -} +/***/ }), +/* 172 */, +/* 173 */ +/***/ (function(module, exports, __webpack_require__) { +module.exports = { "default": __webpack_require__(179), __esModule: true }; /***/ }), -/* 115 */ +/* 174 */ /***/ (function(module, exports, __webpack_require__) { -exports.alphasort = alphasort -exports.alphasorti = alphasorti -exports.setopts = setopts -exports.ownProp = ownProp -exports.makeAbs = makeAbs -exports.finish = finish -exports.mark = mark -exports.isIgnored = isIgnored -exports.childrenIgnored = childrenIgnored +"use strict"; -function ownProp (obj, field) { - return Object.prototype.hasOwnProperty.call(obj, field) -} +module.exports = balanced; +function balanced(a, b, str) { + if (a instanceof RegExp) a = maybeMatch(a, str); + if (b instanceof RegExp) b = maybeMatch(b, str); -var path = __webpack_require__(0) -var minimatch = __webpack_require__(60) -var isAbsolute = __webpack_require__(76) -var Minimatch = minimatch.Minimatch + var r = range(a, b, str); -function alphasorti (a, b) { - return a.toLowerCase().localeCompare(b.toLowerCase()) + return r && { + start: r[0], + end: r[1], + pre: str.slice(0, r[0]), + body: str.slice(r[0] + a.length, r[1]), + post: str.slice(r[1] + b.length) + }; } -function alphasort (a, b) { - return a.localeCompare(b) +function maybeMatch(reg, str) { + var m = str.match(reg); + return m ? m[0] : null; } -function setupIgnores (self, options) { - self.ignore = options.ignore || [] - - if (!Array.isArray(self.ignore)) - self.ignore = [self.ignore] +balanced.range = range; +function range(a, b, str) { + var begs, beg, left, right, result; + var ai = str.indexOf(a); + var bi = str.indexOf(b, ai + 1); + var i = ai; - if (self.ignore.length) { - self.ignore = self.ignore.map(ignoreMap) - } -} + if (ai >= 0 && bi > 0) { + begs = []; + left = str.length; -// ignore patterns are always in dot:true mode. -function ignoreMap (pattern) { - var gmatcher = null - if (pattern.slice(-3) === '/**') { - var gpattern = pattern.replace(/(\/\*\*)+$/, '') - gmatcher = new Minimatch(gpattern, { dot: true }) - } + while (i >= 0 && !result) { + if (i == ai) { + begs.push(i); + ai = str.indexOf(a, i + 1); + } else if (begs.length == 1) { + result = [ begs.pop(), bi ]; + } else { + beg = begs.pop(); + if (beg < left) { + left = beg; + right = bi; + } - return { - matcher: new Minimatch(pattern, { dot: true }), - gmatcher: gmatcher - } -} + bi = str.indexOf(b, i + 1); + } -function setopts (self, pattern, options) { - if (!options) - options = {} + i = ai < bi && ai >= 0 ? ai : bi; + } - // base-matching: just use globstar for that. - if (options.matchBase && -1 === pattern.indexOf("/")) { - if (options.noglobstar) { - throw new Error("base matching requires globstar") + if (begs.length) { + result = [ left, right ]; } - pattern = "**/" + pattern } - self.silent = !!options.silent - self.pattern = pattern - self.strict = options.strict !== false - self.realpath = !!options.realpath - self.realpathCache = options.realpathCache || Object.create(null) - self.follow = !!options.follow - self.dot = !!options.dot - self.mark = !!options.mark - self.nodir = !!options.nodir - if (self.nodir) - self.mark = true - self.sync = !!options.sync - self.nounique = !!options.nounique - self.nonull = !!options.nonull - self.nosort = !!options.nosort - self.nocase = !!options.nocase - self.stat = !!options.stat - self.noprocess = !!options.noprocess - self.absolute = !!options.absolute - - self.maxLength = options.maxLength || Infinity - self.cache = options.cache || Object.create(null) - self.statCache = options.statCache || Object.create(null) - self.symlinks = options.symlinks || Object.create(null) + return result; +} - setupIgnores(self, options) - self.changedCwd = false - var cwd = process.cwd() - if (!ownProp(options, "cwd")) - self.cwd = cwd - else { - self.cwd = path.resolve(options.cwd) - self.changedCwd = self.cwd !== cwd - } +/***/ }), +/* 175 */ +/***/ (function(module, exports, __webpack_require__) { - self.root = options.root || path.resolve(self.cwd, "/") - self.root = path.resolve(self.root) - if (process.platform === "win32") - self.root = self.root.replace(/\\/g, "/") +var concatMap = __webpack_require__(178); +var balanced = __webpack_require__(174); - // TODO: is an absolute `cwd` supposed to be resolved against `root`? - // e.g. { cwd: '/test', root: __dirname } === path.join(__dirname, '/test') - self.cwdAbs = isAbsolute(self.cwd) ? self.cwd : makeAbs(self, self.cwd) - if (process.platform === "win32") - self.cwdAbs = self.cwdAbs.replace(/\\/g, "/") - self.nomount = !!options.nomount +module.exports = expandTop; - // disable comments and negation in Minimatch. - // Note that they are not supported in Glob itself anyway. - options.nonegate = true - options.nocomment = true +var escSlash = '\0SLASH'+Math.random()+'\0'; +var escOpen = '\0OPEN'+Math.random()+'\0'; +var escClose = '\0CLOSE'+Math.random()+'\0'; +var escComma = '\0COMMA'+Math.random()+'\0'; +var escPeriod = '\0PERIOD'+Math.random()+'\0'; - self.minimatch = new Minimatch(pattern, options) - self.options = self.minimatch.options +function numeric(str) { + return parseInt(str, 10) == str + ? parseInt(str, 10) + : str.charCodeAt(0); } -function finish (self) { - var nou = self.nounique - var all = nou ? [] : Object.create(null) - - for (var i = 0, l = self.matches.length; i < l; i ++) { - var matches = self.matches[i] - if (!matches || Object.keys(matches).length === 0) { - if (self.nonull) { - // do like the shell, and spit out the literal glob - var literal = self.minimatch.globSet[i] - if (nou) - all.push(literal) - else - all[literal] = true - } - } else { - // had matches - var m = Object.keys(matches) - if (nou) - all.push.apply(all, m) - else - m.forEach(function (m) { - all[m] = true - }) - } - } - - if (!nou) - all = Object.keys(all) - - if (!self.nosort) - all = all.sort(self.nocase ? alphasorti : alphasort) - - // at *some* point we statted all of these - if (self.mark) { - for (var i = 0; i < all.length; i++) { - all[i] = self._mark(all[i]) - } - if (self.nodir) { - all = all.filter(function (e) { - var notDir = !(/\/$/.test(e)) - var c = self.cache[e] || self.cache[makeAbs(self, e)] - if (notDir && c) - notDir = c !== 'DIR' && !Array.isArray(c) - return notDir - }) - } - } - - if (self.ignore.length) - all = all.filter(function(m) { - return !isIgnored(self, m) - }) +function escapeBraces(str) { + return str.split('\\\\').join(escSlash) + .split('\\{').join(escOpen) + .split('\\}').join(escClose) + .split('\\,').join(escComma) + .split('\\.').join(escPeriod); +} - self.found = all +function unescapeBraces(str) { + return str.split(escSlash).join('\\') + .split(escOpen).join('{') + .split(escClose).join('}') + .split(escComma).join(',') + .split(escPeriod).join('.'); } -function mark (self, p) { - var abs = makeAbs(self, p) - var c = self.cache[abs] - var m = p - if (c) { - var isDir = c === 'DIR' || Array.isArray(c) - var slash = p.slice(-1) === '/' - if (isDir && !slash) - m += '/' - else if (!isDir && slash) - m = m.slice(0, -1) +// Basically just str.split(","), but handling cases +// where we have nested braced sections, which should be +// treated as individual members, like {a,{b,c},d} +function parseCommaParts(str) { + if (!str) + return ['']; - if (m !== p) { - var mabs = makeAbs(self, m) - self.statCache[mabs] = self.statCache[abs] - self.cache[mabs] = self.cache[abs] - } - } + var parts = []; + var m = balanced('{', '}', str); - return m -} + if (!m) + return str.split(','); -// lotta situps... -function makeAbs (self, f) { - var abs = f - if (f.charAt(0) === '/') { - abs = path.join(self.root, f) - } else if (isAbsolute(f) || f === '') { - abs = f - } else if (self.changedCwd) { - abs = path.resolve(self.cwd, f) - } else { - abs = path.resolve(f) + var pre = m.pre; + var body = m.body; + var post = m.post; + var p = pre.split(','); + + p[p.length-1] += '{' + body + '}'; + var postParts = parseCommaParts(post); + if (post.length) { + p[p.length-1] += postParts.shift(); + p.push.apply(p, postParts); } - if (process.platform === 'win32') - abs = abs.replace(/\\/g, '/') + parts.push.apply(parts, p); - return abs + return parts; } +function expandTop(str) { + if (!str) + return []; -// Return true, if pattern ends with globstar '**', for the accompanying parent directory. -// Ex:- If node_modules/** is the pattern, add 'node_modules' to ignore list along with it's contents -function isIgnored (self, path) { - if (!self.ignore.length) - return false + // I don't know why Bash 4.3 does this, but it does. + // Anything starting with {} will have the first two bytes preserved + // but *only* at the top level, so {},a}b will not expand to anything, + // but a{},b}c will be expanded to [a}c,abc]. + // One could argue that this is a bug in Bash, but since the goal of + // this module is to match Bash's rules, we escape a leading {} + if (str.substr(0, 2) === '{}') { + str = '\\{\\}' + str.substr(2); + } - return self.ignore.some(function(item) { - return item.matcher.match(path) || !!(item.gmatcher && item.gmatcher.match(path)) - }) + return expand(escapeBraces(str), true).map(unescapeBraces); } -function childrenIgnored (self, path) { - if (!self.ignore.length) - return false - - return self.ignore.some(function(item) { - return !!(item.gmatcher && item.gmatcher.match(path)) - }) +function identity(e) { + return e; } +function embrace(str) { + return '{' + str + '}'; +} +function isPadded(el) { + return /^-?0\d/.test(el); +} -/***/ }), -/* 116 */ -/***/ (function(module, exports, __webpack_require__) { +function lte(i, y) { + return i <= y; +} +function gte(i, y) { + return i >= y; +} -var path = __webpack_require__(0); -var fs = __webpack_require__(3); -var _0777 = parseInt('0777', 8); +function expand(str, isTop) { + var expansions = []; -module.exports = mkdirP.mkdirp = mkdirP.mkdirP = mkdirP; + var m = balanced('{', '}', str); + if (!m || /\$$/.test(m.pre)) return [str]; -function mkdirP (p, opts, f, made) { - if (typeof opts === 'function') { - f = opts; - opts = {}; - } - else if (!opts || typeof opts !== 'object') { - opts = { mode: opts }; + var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); + var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); + var isSequence = isNumericSequence || isAlphaSequence; + var isOptions = m.body.indexOf(',') >= 0; + if (!isSequence && !isOptions) { + // {a},b} + if (m.post.match(/,.*\}/)) { + str = m.pre + '{' + m.body + escClose + m.post; + return expand(str); } - - var mode = opts.mode; - var xfs = opts.fs || fs; - - if (mode === undefined) { - mode = _0777 & (~process.umask()); + return [str]; + } + + var n; + if (isSequence) { + n = m.body.split(/\.\./); + } else { + n = parseCommaParts(m.body); + if (n.length === 1) { + // x{{a,b}}y ==> x{a}y x{b}y + n = expand(n[0], false).map(embrace); + if (n.length === 1) { + var post = m.post.length + ? expand(m.post, false) + : ['']; + return post.map(function(p) { + return m.pre + n[0] + p; + }); + } } - if (!made) made = null; - - var cb = f || function () {}; - p = path.resolve(p); - - xfs.mkdir(p, mode, function (er) { - if (!er) { - made = made || p; - return cb(null, made); - } - switch (er.code) { - case 'ENOENT': - mkdirP(path.dirname(p), opts, function (er, made) { - if (er) cb(er, made); - else mkdirP(p, opts, cb, made); - }); - break; + } - // In the case of any other error, just see if there's a dir - // there already. If so, then hooray! If not, then something - // is borked. - default: - xfs.stat(p, function (er2, stat) { - // if the stat fails, then that's super weird. - // let the original error be the failure reason. - if (er2 || !stat.isDirectory()) cb(er, made) - else cb(null, made); - }); - break; - } - }); -} + // at this point, n is the parts, and we know it's not a comma set + // with a single entry. -mkdirP.sync = function sync (p, opts, made) { - if (!opts || typeof opts !== 'object') { - opts = { mode: opts }; - } - - var mode = opts.mode; - var xfs = opts.fs || fs; - - if (mode === undefined) { - mode = _0777 & (~process.umask()); - } - if (!made) made = null; + // no need to expand pre, since it is guaranteed to be free of brace-sets + var pre = m.pre; + var post = m.post.length + ? expand(m.post, false) + : ['']; - p = path.resolve(p); + var N; - try { - xfs.mkdirSync(p, mode); - made = made || p; + if (isSequence) { + var x = numeric(n[0]); + var y = numeric(n[1]); + var width = Math.max(n[0].length, n[1].length) + var incr = n.length == 3 + ? Math.abs(numeric(n[2])) + : 1; + var test = lte; + var reverse = y < x; + if (reverse) { + incr *= -1; + test = gte; } - catch (err0) { - switch (err0.code) { - case 'ENOENT' : - made = sync(path.dirname(p), opts, made); - sync(p, opts, made); - break; + var pad = n.some(isPadded); - // In the case of any other error, just see if there's a dir - // there already. If so, then hooray! If not, then something - // is borked. - default: - var stat; - try { - stat = xfs.statSync(p); - } - catch (err1) { - throw err0; - } - if (!stat.isDirectory()) throw err0; - break; + N = []; + + for (var i = x; test(i, y); i += incr) { + var c; + if (isAlphaSequence) { + c = String.fromCharCode(i); + if (c === '\\') + c = ''; + } else { + c = String(i); + if (pad) { + var need = width - c.length; + if (need > 0) { + var z = new Array(need + 1).join('0'); + if (i < 0) + c = '-' + z + c.slice(1); + else + c = z + c; + } } + } + N.push(c); } + } else { + N = concatMap(n, function(el) { return expand(el, false) }); + } + + for (var j = 0; j < N.length; j++) { + for (var k = 0; k < post.length; k++) { + var expansion = pre + N[j] + post[k]; + if (!isTop || isSequence || expansion) + expansions.push(expansion); + } + } + + return expansions; +} - return made; -}; /***/ }), -/* 117 */, -/* 118 */, -/* 119 */, -/* 120 */, -/* 121 */, -/* 122 */ +/* 176 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -module.exports = x => { - if (typeof x !== 'string') { - throw new TypeError('Expected a string, got ' + typeof x); - } - - // Catches EFBBBF (UTF-8 BOM) because the buffer-to-string - // conversion translates it to FEFF (UTF-16 BOM) - if (x.charCodeAt(0) === 0xFEFF) { - return x.slice(1); - } - return x; -}; +function preserveCamelCase(str) { + let isLastCharLower = false; + let isLastCharUpper = false; + let isLastLastCharUpper = false; + for (let i = 0; i < str.length; i++) { + const c = str[i]; -/***/ }), -/* 123 */ -/***/ (function(module, exports) { + if (isLastCharLower && /[a-zA-Z]/.test(c) && c.toUpperCase() === c) { + str = str.substr(0, i) + '-' + str.substr(i); + isLastCharLower = false; + isLastLastCharUpper = isLastCharUpper; + isLastCharUpper = true; + i++; + } else if (isLastCharUpper && isLastLastCharUpper && /[a-zA-Z]/.test(c) && c.toLowerCase() === c) { + str = str.substr(0, i - 1) + '-' + str.substr(i - 1); + isLastLastCharUpper = isLastCharUpper; + isLastCharUpper = false; + isLastCharLower = true; + } else { + isLastCharLower = c.toLowerCase() === c; + isLastLastCharUpper = isLastCharUpper; + isLastCharUpper = c.toUpperCase() === c; + } + } -// Returns a wrapper function that returns a wrapped callback -// The wrapper function should do some stuff, and return a -// presumably different callback function. -// This makes sure that own properties are retained, so that -// decorations and such are not lost along the way. -module.exports = wrappy -function wrappy (fn, cb) { - if (fn && cb) return wrappy(fn)(cb) + return str; +} - if (typeof fn !== 'function') - throw new TypeError('need wrapper function') +module.exports = function (str) { + if (arguments.length > 1) { + str = Array.from(arguments) + .map(x => x.trim()) + .filter(x => x.length) + .join('-'); + } else { + str = str.trim(); + } - Object.keys(fn).forEach(function (k) { - wrapper[k] = fn[k] - }) + if (str.length === 0) { + return ''; + } - return wrapper + if (str.length === 1) { + return str.toLowerCase(); + } - function wrapper() { - var args = new Array(arguments.length) - for (var i = 0; i < args.length; i++) { - args[i] = arguments[i] - } - var ret = fn.apply(this, args) - var cb = args[args.length-1] - if (typeof ret === 'function' && ret !== cb) { - Object.keys(cb).forEach(function (k) { - ret[k] = cb[k] - }) - } - return ret - } -} + if (/^[a-z0-9]+$/.test(str)) { + return str; + } + const hasUpperCase = str !== str.toLowerCase(); -/***/ }), -/* 124 */, -/* 125 */, -/* 126 */, -/* 127 */, -/* 128 */, -/* 129 */, -/* 130 */, -/* 131 */ -/***/ (function(module, exports, __webpack_require__) { + if (hasUpperCase) { + str = preserveCamelCase(str); + } -// fallback for non-array-like ES3 and non-enumerable old V8 strings -var cof = __webpack_require__(47); -// eslint-disable-next-line no-prototype-builtins -module.exports = Object('z').propertyIsEnumerable(0) ? Object : function (it) { - return cof(it) == 'String' ? it.split('') : Object(it); + return str + .replace(/^[_.\- ]+/, '') + .toLowerCase() + .replace(/[_.\- ]+(\w|$)/g, (m, p1) => p1.toUpperCase()); }; /***/ }), -/* 132 */ -/***/ (function(module, exports, __webpack_require__) { +/* 177 */, +/* 178 */ +/***/ (function(module, exports) { -// 19.1.2.14 / 15.2.3.14 Object.keys(O) -var $keys = __webpack_require__(195); -var enumBugKeys = __webpack_require__(101); +module.exports = function (xs, fn) { + var res = []; + for (var i = 0; i < xs.length; i++) { + var x = fn(xs[i], i); + if (isArray(x)) res.push.apply(res, x); + else res.push(x); + } + return res; +}; -module.exports = Object.keys || function keys(O) { - return $keys(O, enumBugKeys); +var isArray = Array.isArray || function (xs) { + return Object.prototype.toString.call(xs) === '[object Array]'; }; /***/ }), -/* 133 */ +/* 179 */ /***/ (function(module, exports, __webpack_require__) { -// 7.1.13 ToObject(argument) -var defined = __webpack_require__(67); -module.exports = function (it) { - return Object(defined(it)); -}; +__webpack_require__(205); +__webpack_require__(207); +__webpack_require__(210); +__webpack_require__(206); +__webpack_require__(208); +__webpack_require__(209); +module.exports = __webpack_require__(23).Promise; /***/ }), -/* 134 */, -/* 135 */, -/* 136 */, -/* 137 */, -/* 138 */, -/* 139 */, -/* 140 */, -/* 141 */, -/* 142 */, -/* 143 */, -/* 144 */, -/* 145 */ +/* 180 */ /***/ (function(module, exports) { -module.exports = {"name":"yarn","installationMethod":"unknown","version":"1.10.0-0","license":"BSD-2-Clause","preferGlobal":true,"description":"📦🐈 Fast, reliable, and secure dependency management.","dependencies":{"@zkochan/cmd-shim":"^2.2.4","babel-runtime":"^6.26.0","bytes":"^3.0.0","camelcase":"^4.0.0","chalk":"^2.1.0","commander":"^2.9.0","death":"^1.0.0","debug":"^3.0.0","deep-equal":"^1.0.1","detect-indent":"^5.0.0","dnscache":"^1.0.1","glob":"^7.1.1","gunzip-maybe":"^1.4.0","hash-for-dep":"^1.2.3","imports-loader":"^0.8.0","ini":"^1.3.4","inquirer":"^3.0.1","invariant":"^2.2.0","is-builtin-module":"^2.0.0","is-ci":"^1.0.10","is-webpack-bundle":"^1.0.0","leven":"^2.0.0","loud-rejection":"^1.2.0","micromatch":"^2.3.11","mkdirp":"^0.5.1","node-emoji":"^1.6.1","normalize-url":"^2.0.0","npm-logical-tree":"^1.2.1","object-path":"^0.11.2","proper-lockfile":"^2.0.0","puka":"^1.0.0","read":"^1.0.7","request":"^2.87.0","request-capture-har":"^1.2.2","rimraf":"^2.5.0","semver":"^5.1.0","ssri":"^5.3.0","strip-ansi":"^4.0.0","strip-bom":"^3.0.0","tar-fs":"^1.16.0","tar-stream":"^1.6.1","uuid":"^3.0.1","v8-compile-cache":"^2.0.0","validate-npm-package-license":"^3.0.3","yn":"^2.0.0"},"devDependencies":{"babel-core":"^6.26.0","babel-eslint":"^7.2.3","babel-loader":"^6.2.5","babel-plugin-array-includes":"^2.0.3","babel-plugin-transform-builtin-extend":"^1.1.2","babel-plugin-transform-inline-imports-commonjs":"^1.0.0","babel-plugin-transform-runtime":"^6.4.3","babel-preset-env":"^1.6.0","babel-preset-flow":"^6.23.0","babel-preset-stage-0":"^6.0.0","babylon":"^6.5.0","commitizen":"^2.9.6","cz-conventional-changelog":"^2.0.0","eslint":"^4.3.0","eslint-config-fb-strict":"^22.0.0","eslint-plugin-babel":"^5.0.0","eslint-plugin-flowtype":"^2.35.0","eslint-plugin-jasmine":"^2.6.2","eslint-plugin-jest":"^21.0.0","eslint-plugin-jsx-a11y":"^6.0.2","eslint-plugin-prefer-object-spread":"^1.2.1","eslint-plugin-prettier":"^2.1.2","eslint-plugin-react":"^7.1.0","eslint-plugin-relay":"^0.0.24","eslint-plugin-yarn-internal":"file:scripts/eslint-rules","execa":"^0.10.0","flow-bin":"^0.66.0","git-release-notes":"^3.0.0","gulp":"^3.9.0","gulp-babel":"^7.0.0","gulp-if":"^2.0.1","gulp-newer":"^1.0.0","gulp-plumber":"^1.0.1","gulp-sourcemaps":"^2.2.0","gulp-util":"^3.0.7","gulp-watch":"^5.0.0","jest":"^22.4.4","jsinspect":"^0.12.6","minimatch":"^3.0.4","mock-stdin":"^0.3.0","prettier":"^1.5.2","temp":"^0.8.3","webpack":"^2.1.0-beta.25","yargs":"^6.3.0"},"resolutions":{"sshpk":"^1.14.2"},"engines":{"node":">=4.0.0"},"repository":"yarnpkg/yarn","bin":{"yarn":"./bin/yarn.js","yarnpkg":"./bin/yarn.js"},"scripts":{"build":"gulp build","build-bundle":"node ./scripts/build-webpack.js","build-chocolatey":"powershell ./scripts/build-chocolatey.ps1","build-deb":"./scripts/build-deb.sh","build-dist":"bash ./scripts/build-dist.sh","build-win-installer":"scripts\\build-windows-installer.bat","changelog":"git-release-notes $(git describe --tags --abbrev=0 $(git describe --tags --abbrev=0)^)..$(git describe --tags --abbrev=0) scripts/changelog.md","dupe-check":"yarn jsinspect ./src","lint":"eslint . && flow check","pkg-tests":"yarn --cwd packages/pkg-tests jest yarn.test.js","prettier":"eslint src __tests__ --fix","release-branch":"./scripts/release-branch.sh","test":"yarn lint && yarn test-only","test-only":"node --max_old_space_size=4096 node_modules/jest/bin/jest.js --verbose","test-only-debug":"node --inspect-brk --max_old_space_size=4096 node_modules/jest/bin/jest.js --runInBand --verbose","test-coverage":"node --max_old_space_size=4096 node_modules/jest/bin/jest.js --coverage --verbose","watch":"gulp watch","commit":"git-cz"},"jest":{"collectCoverageFrom":["src/**/*.js"],"testEnvironment":"node","modulePathIgnorePatterns":["__tests__/fixtures/","packages/pkg-tests/pkg-tests-fixtures","dist/"],"testPathIgnorePatterns":["__tests__/(fixtures|__mocks__)/","updates/","_(temp|mock|install|init|helpers).js$","packages/pkg-tests"]},"config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}}} +module.exports = function () { /* empty */ }; + /***/ }), -/* 146 */, -/* 147 */, -/* 148 */, -/* 149 */, -/* 150 */ -/***/ (function(module, exports, __webpack_require__) { +/* 181 */ +/***/ (function(module, exports) { -"use strict"; +module.exports = function (it, Constructor, name, forbiddenField) { + if (!(it instanceof Constructor) || (forbiddenField !== undefined && forbiddenField in it)) { + throw TypeError(name + ': incorrect invocation!'); + } return it; +}; -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = stringify; +/***/ }), +/* 182 */ +/***/ (function(module, exports, __webpack_require__) { -var _misc; +// false -> Array#indexOf +// true -> Array#includes +var toIObject = __webpack_require__(74); +var toLength = __webpack_require__(110); +var toAbsoluteIndex = __webpack_require__(200); +module.exports = function (IS_INCLUDES) { + return function ($this, el, fromIndex) { + var O = toIObject($this); + var length = toLength(O.length); + var index = toAbsoluteIndex(fromIndex, length); + var value; + // Array#includes uses SameValueZero equality algorithm + // eslint-disable-next-line no-self-compare + if (IS_INCLUDES && el != el) while (length > index) { + value = O[index++]; + // eslint-disable-next-line no-self-compare + if (value != value) return true; + // Array#indexOf ignores holes, Array#includes - not + } else for (;length > index; index++) if (IS_INCLUDES || index in O) { + if (O[index] === el) return IS_INCLUDES || index || 0; + } return !IS_INCLUDES && -1; + }; +}; -function _load_misc() { - return _misc = __webpack_require__(12); -} -var _constants; +/***/ }), +/* 183 */ +/***/ (function(module, exports, __webpack_require__) { -function _load_constants() { - return _constants = __webpack_require__(6); -} +var ctx = __webpack_require__(48); +var call = __webpack_require__(187); +var isArrayIter = __webpack_require__(186); +var anObject = __webpack_require__(27); +var toLength = __webpack_require__(110); +var getIterFn = __webpack_require__(203); +var BREAK = {}; +var RETURN = {}; +var exports = module.exports = function (iterable, entries, fn, that, ITERATOR) { + var iterFn = ITERATOR ? function () { return iterable; } : getIterFn(iterable); + var f = ctx(fn, that, entries ? 2 : 1); + var index = 0; + var length, step, iterator, result; + if (typeof iterFn != 'function') throw TypeError(iterable + ' is not iterable!'); + // fast case for arrays with default iterator + if (isArrayIter(iterFn)) for (length = toLength(iterable.length); length > index; index++) { + result = entries ? f(anObject(step = iterable[index])[0], step[1]) : f(iterable[index]); + if (result === BREAK || result === RETURN) return result; + } else for (iterator = iterFn.call(iterable); !(step = iterator.next()).done;) { + result = call(iterator, f, step.value, entries); + if (result === BREAK || result === RETURN) return result; + } +}; +exports.BREAK = BREAK; +exports.RETURN = RETURN; -var _package; -function _load_package() { - return _package = __webpack_require__(145); -} +/***/ }), +/* 184 */ +/***/ (function(module, exports, __webpack_require__) { -const NODE_VERSION = process.version; +module.exports = !__webpack_require__(33) && !__webpack_require__(85)(function () { + return Object.defineProperty(__webpack_require__(68)('div'), 'a', { get: function () { return 7; } }).a != 7; +}); -function shouldWrapKey(str) { - return str.indexOf('true') === 0 || str.indexOf('false') === 0 || /[:\s\n\\",\[\]]/g.test(str) || /^[0-9]/g.test(str) || !/^[a-zA-Z]/g.test(str); -} -function maybeWrap(str) { - if (typeof str === 'boolean' || typeof str === 'number' || shouldWrapKey(str)) { - return JSON.stringify(str); - } else { - return str; - } -} +/***/ }), +/* 185 */ +/***/ (function(module, exports) { -const priorities = { - name: 1, - version: 2, - uid: 3, - resolved: 4, - integrity: 5, - registry: 6, - dependencies: 7 +// fast apply, http://jsperf.lnkit.com/fast-apply/5 +module.exports = function (fn, args, that) { + var un = that === undefined; + switch (args.length) { + case 0: return un ? fn() + : fn.call(that); + case 1: return un ? fn(args[0]) + : fn.call(that, args[0]); + case 2: return un ? fn(args[0], args[1]) + : fn.call(that, args[0], args[1]); + case 3: return un ? fn(args[0], args[1], args[2]) + : fn.call(that, args[0], args[1], args[2]); + case 4: return un ? fn(args[0], args[1], args[2], args[3]) + : fn.call(that, args[0], args[1], args[2], args[3]); + } return fn.apply(that, args); }; -function priorityThenAlphaSort(a, b) { - if (priorities[a] || priorities[b]) { - return (priorities[a] || 100) > (priorities[b] || 100) ? 1 : -1; - } else { - return (0, (_misc || _load_misc()).sortAlpha)(a, b); - } -} - -function _stringify(obj, options) { - if (typeof obj !== 'object') { - throw new TypeError(); - } - const indent = options.indent; - const lines = []; +/***/ }), +/* 186 */ +/***/ (function(module, exports, __webpack_require__) { - // Sorting order needs to be consistent between runs, we run native sort by name because there are no - // problems with it being unstable because there are no to keys the same - // However priorities can be duplicated and native sort can shuffle things from run to run - const keys = Object.keys(obj).sort(priorityThenAlphaSort); +// check on default Array iterator +var Iterators = __webpack_require__(35); +var ITERATOR = __webpack_require__(13)('iterator'); +var ArrayProto = Array.prototype; - let addedKeys = []; +module.exports = function (it) { + return it !== undefined && (Iterators.Array === it || ArrayProto[ITERATOR] === it); +}; - for (let i = 0; i < keys.length; i++) { - const key = keys[i]; - const val = obj[key]; - if (val == null || addedKeys.indexOf(key) >= 0) { - continue; - } - const valKeys = [key]; +/***/ }), +/* 187 */ +/***/ (function(module, exports, __webpack_require__) { - // get all keys that have the same value equality, we only want this for objects - if (typeof val === 'object') { - for (let j = i + 1; j < keys.length; j++) { - const key = keys[j]; - if (val === obj[key]) { - valKeys.push(key); - } - } - } +// call something on iterator step with safe closing on error +var anObject = __webpack_require__(27); +module.exports = function (iterator, fn, value, entries) { + try { + return entries ? fn(anObject(value)[0], value[1]) : fn(value); + // 7.4.6 IteratorClose(iterator, completion) + } catch (e) { + var ret = iterator['return']; + if (ret !== undefined) anObject(ret.call(iterator)); + throw e; + } +}; - const keyLine = valKeys.sort((_misc || _load_misc()).sortAlpha).map(maybeWrap).join(', '); - if (typeof val === 'string' || typeof val === 'boolean' || typeof val === 'number') { - lines.push(`${keyLine} ${maybeWrap(val)}`); - } else if (typeof val === 'object') { - lines.push(`${keyLine}:\n${_stringify(val, { indent: indent + ' ' })}` + (options.topLevel ? '\n' : '')); - } else { - throw new TypeError(); - } +/***/ }), +/* 188 */ +/***/ (function(module, exports, __webpack_require__) { - addedKeys = addedKeys.concat(valKeys); - } +"use strict"; - return indent + lines.join(`\n${indent}`); -} +var create = __webpack_require__(192); +var descriptor = __webpack_require__(106); +var setToStringTag = __webpack_require__(71); +var IteratorPrototype = {}; -function stringify(obj, noHeader, enableVersions) { - const val = _stringify(obj, { - indent: '', - topLevel: true - }); - if (noHeader) { - return val; - } +// 25.1.2.1.1 %IteratorPrototype%[@@iterator]() +__webpack_require__(31)(IteratorPrototype, __webpack_require__(13)('iterator'), function () { return this; }); - const lines = []; - lines.push('# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.'); - lines.push(`# yarn lockfile v${(_constants || _load_constants()).LOCKFILE_VERSION}`); - if (enableVersions) { - lines.push(`# yarn v${(_package || _load_package()).version}`); - lines.push(`# node ${NODE_VERSION}`); - } - lines.push('\n'); - lines.push(val); +module.exports = function (Constructor, NAME, next) { + Constructor.prototype = create(IteratorPrototype, { next: descriptor(1, next) }); + setToStringTag(Constructor, NAME + ' Iterator'); +}; - return lines.join('\n'); -} /***/ }), -/* 151 */, -/* 152 */, -/* 153 */, -/* 154 */, -/* 155 */, -/* 156 */, -/* 157 */, -/* 158 */, -/* 159 */, -/* 160 */, -/* 161 */, -/* 162 */, -/* 163 */, -/* 164 */ +/* 189 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; +var ITERATOR = __webpack_require__(13)('iterator'); +var SAFE_CLOSING = false; +try { + var riter = [7][ITERATOR](); + riter['return'] = function () { SAFE_CLOSING = true; }; + // eslint-disable-next-line no-throw-literal + Array.from(riter, function () { throw 2; }); +} catch (e) { /* empty */ } -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.fileDatesEqual = exports.copyFile = exports.unlink = undefined; +module.exports = function (exec, skipClosing) { + if (!skipClosing && !SAFE_CLOSING) return false; + var safe = false; + try { + var arr = [7]; + var iter = arr[ITERATOR](); + iter.next = function () { return { done: safe = true }; }; + arr[ITERATOR] = function () { return iter; }; + exec(arr); + } catch (e) { /* empty */ } + return safe; +}; -var _asyncToGenerator2; -function _load_asyncToGenerator() { - return _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(1)); -} +/***/ }), +/* 190 */ +/***/ (function(module, exports) { -// We want to preserve file timestamps when copying a file, since yarn uses them to decide if a file has -// changed compared to the cache. -// There are some OS specific cases here: -// * On linux, fs.copyFile does not preserve timestamps, but does on OSX and Win. -// * On windows, you must open a file with write permissions to call `fs.futimes`. -// * On OSX you can open with read permissions and still call `fs.futimes`. -let fixTimes = (() => { - var _ref3 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (fd, dest, data) { - const doOpen = fd === undefined; - let openfd = fd ? fd : -1; +module.exports = function (done, value) { + return { value: value, done: !!done }; +}; - if (disableTimestampCorrection === undefined) { - // if timestamps match already, no correction is needed. - // the need to correct timestamps varies based on OS and node versions. - const destStat = yield lstat(dest); - disableTimestampCorrection = fileDatesEqual(destStat.mtime, data.mtime); - } - if (disableTimestampCorrection) { - return; - } +/***/ }), +/* 191 */ +/***/ (function(module, exports, __webpack_require__) { - if (doOpen) { +var global = __webpack_require__(11); +var macrotask = __webpack_require__(109).set; +var Observer = global.MutationObserver || global.WebKitMutationObserver; +var process = global.process; +var Promise = global.Promise; +var isNode = __webpack_require__(47)(process) == 'process'; + +module.exports = function () { + var head, last, notify; + + var flush = function () { + var parent, fn; + if (isNode && (parent = process.domain)) parent.exit(); + while (head) { + fn = head.fn; + head = head.next; try { - openfd = yield open(dest, 'a', data.mode); - } catch (er) { - // file is likely read-only - try { - openfd = yield open(dest, 'r', data.mode); - } catch (err) { - // We can't even open this file for reading. - return; - } + fn(); + } catch (e) { + if (head) notify(); + else last = undefined; + throw e; } - } + } last = undefined; + if (parent) parent.enter(); + }; - try { - if (openfd) { - yield futimes(openfd, data.atime, data.mtime); - } - } catch (er) { - // If `futimes` throws an exception, we probably have a case of a read-only file on Windows. - // In this case we can just return. The incorrect timestamp will just cause that file to be recopied - // on subsequent installs, which will effect yarn performance but not break anything. - } finally { - if (doOpen && openfd) { - yield close(openfd); - } - } - }); + // Node.js + if (isNode) { + notify = function () { + process.nextTick(flush); + }; + // browsers with MutationObserver, except iOS Safari - https://github.com/zloirock/core-js/issues/339 + } else if (Observer && !(global.navigator && global.navigator.standalone)) { + var toggle = true; + var node = document.createTextNode(''); + new Observer(flush).observe(node, { characterData: true }); // eslint-disable-line no-new + notify = function () { + node.data = toggle = !toggle; + }; + // environments with maybe non-completely correct, but existent Promise + } else if (Promise && Promise.resolve) { + // Promise.resolve without an argument throws an error in LG WebOS 2 + var promise = Promise.resolve(undefined); + notify = function () { + promise.then(flush); + }; + // for other environments - macrotask based on: + // - setImmediate + // - MessageChannel + // - window.postMessag + // - onreadystatechange + // - setTimeout + } else { + notify = function () { + // strange IE + webpack dev server bug - use .call(global) + macrotask.call(global, flush); + }; + } - return function fixTimes(_x7, _x8, _x9) { - return _ref3.apply(this, arguments); + return function (fn) { + var task = { fn: fn, next: undefined }; + if (last) last.next = task; + if (!head) { + head = task; + notify(); + } last = task; }; -})(); +}; -// Compare file timestamps. -// Some versions of Node on windows zero the milliseconds when utime is used. +/***/ }), +/* 192 */ +/***/ (function(module, exports, __webpack_require__) { -var _fs; +// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties]) +var anObject = __webpack_require__(27); +var dPs = __webpack_require__(193); +var enumBugKeys = __webpack_require__(101); +var IE_PROTO = __webpack_require__(72)('IE_PROTO'); +var Empty = function () { /* empty */ }; +var PROTOTYPE = 'prototype'; -function _load_fs() { - return _fs = _interopRequireDefault(__webpack_require__(3)); -} +// Create object with fake `null` prototype: use iframe Object with cleared prototype +var createDict = function () { + // Thrash, waste and sodomy: IE GC bug + var iframe = __webpack_require__(68)('iframe'); + var i = enumBugKeys.length; + var lt = '<'; + var gt = '>'; + var iframeDocument; + iframe.style.display = 'none'; + __webpack_require__(102).appendChild(iframe); + iframe.src = 'javascript:'; // eslint-disable-line no-script-url + // createDict = iframe.contentWindow.Object; + // html.removeChild(iframe); + iframeDocument = iframe.contentWindow.document; + iframeDocument.open(); + iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt); + iframeDocument.close(); + createDict = iframeDocument.F; + while (i--) delete createDict[PROTOTYPE][enumBugKeys[i]]; + return createDict(); +}; -var _promise; +module.exports = Object.create || function create(O, Properties) { + var result; + if (O !== null) { + Empty[PROTOTYPE] = anObject(O); + result = new Empty(); + Empty[PROTOTYPE] = null; + // add "__proto__" for Object.getPrototypeOf polyfill + result[IE_PROTO] = O; + } else result = createDict(); + return Properties === undefined ? result : dPs(result, Properties); +}; -function _load_promise() { - return _promise = __webpack_require__(40); -} -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +/***/ }), +/* 193 */ +/***/ (function(module, exports, __webpack_require__) { -// This module serves as a wrapper for file operations that are inconsistant across node and OS versions. +var dP = __webpack_require__(50); +var anObject = __webpack_require__(27); +var getKeys = __webpack_require__(132); -let disableTimestampCorrection = undefined; // OS dependent. will be detected on first file copy. +module.exports = __webpack_require__(33) ? Object.defineProperties : function defineProperties(O, Properties) { + anObject(O); + var keys = getKeys(Properties); + var length = keys.length; + var i = 0; + var P; + while (length > i) dP.f(O, P = keys[i++], Properties[P]); + return O; +}; -const readFileBuffer = (0, (_promise || _load_promise()).promisify)((_fs || _load_fs()).default.readFile); -const close = (0, (_promise || _load_promise()).promisify)((_fs || _load_fs()).default.close); -const lstat = (0, (_promise || _load_promise()).promisify)((_fs || _load_fs()).default.lstat); -const open = (0, (_promise || _load_promise()).promisify)((_fs || _load_fs()).default.open); -const futimes = (0, (_promise || _load_promise()).promisify)((_fs || _load_fs()).default.futimes); -const write = (0, (_promise || _load_promise()).promisify)((_fs || _load_fs()).default.write); +/***/ }), +/* 194 */ +/***/ (function(module, exports, __webpack_require__) { -const unlink = exports.unlink = (0, (_promise || _load_promise()).promisify)(__webpack_require__(233)); +// 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O) +var has = __webpack_require__(49); +var toObject = __webpack_require__(133); +var IE_PROTO = __webpack_require__(72)('IE_PROTO'); +var ObjectProto = Object.prototype; -/** - * Unlinks the destination to force a recreation. This is needed on case-insensitive file systems - * to force the correct naming when the filename has changed only in character-casing. (Jest -> jest). - */ -const copyFile = exports.copyFile = (() => { - var _ref = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (data, cleanup) { - try { - yield unlink(data.dest); - yield copyFilePoly(data.src, data.dest, 0, data); - } finally { - if (cleanup) { - cleanup(); - } - } - }); +module.exports = Object.getPrototypeOf || function (O) { + O = toObject(O); + if (has(O, IE_PROTO)) return O[IE_PROTO]; + if (typeof O.constructor == 'function' && O instanceof O.constructor) { + return O.constructor.prototype; + } return O instanceof Object ? ObjectProto : null; +}; - return function copyFile(_x, _x2) { - return _ref.apply(this, arguments); - }; -})(); - -// Node 8.5.0 introduced `fs.copyFile` which is much faster, so use that when available. -// Otherwise we fall back to reading and writing files as buffers. -const copyFilePoly = (src, dest, flags, data) => { - if ((_fs || _load_fs()).default.copyFile) { - return new Promise((resolve, reject) => (_fs || _load_fs()).default.copyFile(src, dest, flags, err => { - if (err) { - reject(err); - } else { - fixTimes(undefined, dest, data).then(() => resolve()).catch(ex => reject(ex)); - } - })); - } else { - return copyWithBuffer(src, dest, flags, data); - } -}; - -const copyWithBuffer = (() => { - var _ref2 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (src, dest, flags, data) { - // Use open -> write -> futimes -> close sequence to avoid opening the file twice: - // one with writeFile and one with utimes - const fd = yield open(dest, 'w', data.mode); - try { - const buffer = yield readFileBuffer(src); - yield write(fd, buffer, 0, buffer.length); - yield fixTimes(fd, dest, data); - } finally { - yield close(fd); - } - }); - - return function copyWithBuffer(_x3, _x4, _x5, _x6) { - return _ref2.apply(this, arguments); - }; -})();const fileDatesEqual = exports.fileDatesEqual = (a, b) => { - const aTime = a.getTime(); - const bTime = b.getTime(); - - if (process.platform !== 'win32') { - return aTime === bTime; - } - - // See https://github.com/nodejs/node/pull/12607 - // Submillisecond times from stat and utimes are truncated on Windows, - // causing a file with mtime 8.0079998 and 8.0081144 to become 8.007 and 8.008 - // and making it impossible to update these files to their correct timestamps. - if (Math.abs(aTime - bTime) <= 1) { - return true; - } - - const aTimeSec = Math.floor(aTime / 1000); - const bTimeSec = Math.floor(bTime / 1000); - - // See https://github.com/nodejs/node/issues/2069 - // Some versions of Node on windows zero the milliseconds when utime is used - // So if any of the time has a milliseconds part of zero we suspect that the - // bug is present and compare only seconds. - if (aTime - aTimeSec * 1000 === 0 || bTime - bTimeSec * 1000 === 0) { - return aTimeSec === bTimeSec; - } - - return aTime === bTime; -}; /***/ }), -/* 165 */, -/* 166 */, -/* 167 */, -/* 168 */, -/* 169 */ +/* 195 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; - +var has = __webpack_require__(49); +var toIObject = __webpack_require__(74); +var arrayIndexOf = __webpack_require__(182)(false); +var IE_PROTO = __webpack_require__(72)('IE_PROTO'); -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.isFakeRoot = isFakeRoot; -exports.isRootUser = isRootUser; -function getUid() { - if (process.platform !== 'win32' && process.getuid) { - return process.getuid(); +module.exports = function (object, names) { + var O = toIObject(object); + var i = 0; + var result = []; + var key; + for (key in O) if (key != IE_PROTO) has(O, key) && result.push(key); + // Don't enum bug & hidden keys + while (names.length > i) if (has(O, key = names[i++])) { + ~arrayIndexOf(result, key) || result.push(key); } - return null; -} - -exports.default = isRootUser(getUid()) && !isFakeRoot(); -function isFakeRoot() { - return Boolean(process.env.FAKEROOTKEY); -} + return result; +}; -function isRootUser(uid) { - return uid === 0; -} /***/ }), -/* 170 */, -/* 171 */ +/* 196 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.getDataDir = getDataDir; -exports.getCacheDir = getCacheDir; -exports.getConfigDir = getConfigDir; -const path = __webpack_require__(0); -const userHome = __webpack_require__(45).default; - -const FALLBACK_CONFIG_DIR = path.join(userHome, '.config', 'yarn'); -const FALLBACK_CACHE_DIR = path.join(userHome, '.cache', 'yarn'); - -function getDataDir() { - if (process.platform === 'win32') { - const WIN32_APPDATA_DIR = getLocalAppDataDir(); - return WIN32_APPDATA_DIR == null ? FALLBACK_CONFIG_DIR : path.join(WIN32_APPDATA_DIR, 'Data'); - } else if (process.env.XDG_DATA_HOME) { - return path.join(process.env.XDG_DATA_HOME, 'yarn'); - } else { - // This could arguably be ~/Library/Application Support/Yarn on Macs, - // but that feels unintuitive for a cli tool - - // Instead, use our prior fallback. Some day this could be - // path.join(userHome, '.local', 'share', 'yarn') - // or return path.join(WIN32_APPDATA_DIR, 'Data') on win32 - return FALLBACK_CONFIG_DIR; - } -} - -function getCacheDir() { - if (process.platform === 'win32') { - // process.env.TEMP also exists, but most apps put caches here - return path.join(getLocalAppDataDir() || path.join(userHome, 'AppData', 'Local', 'Yarn'), 'Cache'); - } else if (process.env.XDG_CACHE_HOME) { - return path.join(process.env.XDG_CACHE_HOME, 'yarn'); - } else if (process.platform === 'darwin') { - return path.join(userHome, 'Library', 'Caches', 'Yarn'); - } else { - return FALLBACK_CACHE_DIR; - } -} - -function getConfigDir() { - if (process.platform === 'win32') { - // Use our prior fallback. Some day this could be - // return path.join(WIN32_APPDATA_DIR, 'Config') - const WIN32_APPDATA_DIR = getLocalAppDataDir(); - return WIN32_APPDATA_DIR == null ? FALLBACK_CONFIG_DIR : path.join(WIN32_APPDATA_DIR, 'Config'); - } else if (process.env.XDG_CONFIG_HOME) { - return path.join(process.env.XDG_CONFIG_HOME, 'yarn'); - } else { - return FALLBACK_CONFIG_DIR; - } -} +var hide = __webpack_require__(31); +module.exports = function (target, src, safe) { + for (var key in src) { + if (safe && target[key]) target[key] = src[key]; + else hide(target, key, src[key]); + } return target; +}; -function getLocalAppDataDir() { - return process.env.LOCALAPPDATA ? path.join(process.env.LOCALAPPDATA, 'Yarn') : null; -} /***/ }), -/* 172 */, -/* 173 */ +/* 197 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = { "default": __webpack_require__(179), __esModule: true }; +module.exports = __webpack_require__(31); + /***/ }), -/* 174 */ +/* 198 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -module.exports = balanced; -function balanced(a, b, str) { - if (a instanceof RegExp) a = maybeMatch(a, str); - if (b instanceof RegExp) b = maybeMatch(b, str); - - var r = range(a, b, str); - - return r && { - start: r[0], - end: r[1], - pre: str.slice(0, r[0]), - body: str.slice(r[0] + a.length, r[1]), - post: str.slice(r[1] + b.length) - }; -} - -function maybeMatch(reg, str) { - var m = str.match(reg); - return m ? m[0] : null; -} - -balanced.range = range; -function range(a, b, str) { - var begs, beg, left, right, result; - var ai = str.indexOf(a); - var bi = str.indexOf(b, ai + 1); - var i = ai; - - if (ai >= 0 && bi > 0) { - begs = []; - left = str.length; - - while (i >= 0 && !result) { - if (i == ai) { - begs.push(i); - ai = str.indexOf(a, i + 1); - } else if (begs.length == 1) { - result = [ begs.pop(), bi ]; - } else { - beg = begs.pop(); - if (beg < left) { - left = beg; - right = bi; - } +var global = __webpack_require__(11); +var core = __webpack_require__(23); +var dP = __webpack_require__(50); +var DESCRIPTORS = __webpack_require__(33); +var SPECIES = __webpack_require__(13)('species'); - bi = str.indexOf(b, i + 1); - } +module.exports = function (KEY) { + var C = typeof core[KEY] == 'function' ? core[KEY] : global[KEY]; + if (DESCRIPTORS && C && !C[SPECIES]) dP.f(C, SPECIES, { + configurable: true, + get: function () { return this; } + }); +}; - i = ai < bi && ai >= 0 ? ai : bi; - } - if (begs.length) { - result = [ left, right ]; - } - } +/***/ }), +/* 199 */ +/***/ (function(module, exports, __webpack_require__) { - return result; -} +var toInteger = __webpack_require__(73); +var defined = __webpack_require__(67); +// true -> String#at +// false -> String#codePointAt +module.exports = function (TO_STRING) { + return function (that, pos) { + var s = String(defined(that)); + var i = toInteger(pos); + var l = s.length; + var a, b; + if (i < 0 || i >= l) return TO_STRING ? '' : undefined; + a = s.charCodeAt(i); + return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff + ? TO_STRING ? s.charAt(i) : a + : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000; + }; +}; /***/ }), -/* 175 */ +/* 200 */ /***/ (function(module, exports, __webpack_require__) { -var concatMap = __webpack_require__(178); -var balanced = __webpack_require__(174); +var toInteger = __webpack_require__(73); +var max = Math.max; +var min = Math.min; +module.exports = function (index, length) { + index = toInteger(index); + return index < 0 ? max(index + length, 0) : min(index, length); +}; -module.exports = expandTop; -var escSlash = '\0SLASH'+Math.random()+'\0'; -var escOpen = '\0OPEN'+Math.random()+'\0'; -var escClose = '\0CLOSE'+Math.random()+'\0'; -var escComma = '\0COMMA'+Math.random()+'\0'; -var escPeriod = '\0PERIOD'+Math.random()+'\0'; +/***/ }), +/* 201 */ +/***/ (function(module, exports, __webpack_require__) { -function numeric(str) { - return parseInt(str, 10) == str - ? parseInt(str, 10) - : str.charCodeAt(0); -} +// 7.1.1 ToPrimitive(input [, PreferredType]) +var isObject = __webpack_require__(34); +// instead of the ES6 spec version, we didn't implement @@toPrimitive case +// and the second argument - flag - preferred type is a string +module.exports = function (it, S) { + if (!isObject(it)) return it; + var fn, val; + if (S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val; + if (typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it))) return val; + if (!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val; + throw TypeError("Can't convert object to primitive value"); +}; -function escapeBraces(str) { - return str.split('\\\\').join(escSlash) - .split('\\{').join(escOpen) - .split('\\}').join(escClose) - .split('\\,').join(escComma) - .split('\\.').join(escPeriod); -} -function unescapeBraces(str) { - return str.split(escSlash).join('\\') - .split(escOpen).join('{') - .split(escClose).join('}') - .split(escComma).join(',') - .split(escPeriod).join('.'); -} +/***/ }), +/* 202 */ +/***/ (function(module, exports, __webpack_require__) { +var global = __webpack_require__(11); +var navigator = global.navigator; -// Basically just str.split(","), but handling cases -// where we have nested braced sections, which should be -// treated as individual members, like {a,{b,c},d} -function parseCommaParts(str) { - if (!str) - return ['']; +module.exports = navigator && navigator.userAgent || ''; - var parts = []; - var m = balanced('{', '}', str); - if (!m) - return str.split(','); +/***/ }), +/* 203 */ +/***/ (function(module, exports, __webpack_require__) { - var pre = m.pre; - var body = m.body; - var post = m.post; - var p = pre.split(','); +var classof = __webpack_require__(100); +var ITERATOR = __webpack_require__(13)('iterator'); +var Iterators = __webpack_require__(35); +module.exports = __webpack_require__(23).getIteratorMethod = function (it) { + if (it != undefined) return it[ITERATOR] + || it['@@iterator'] + || Iterators[classof(it)]; +}; - p[p.length-1] += '{' + body + '}'; - var postParts = parseCommaParts(post); - if (post.length) { - p[p.length-1] += postParts.shift(); - p.push.apply(p, postParts); - } - parts.push.apply(parts, p); +/***/ }), +/* 204 */ +/***/ (function(module, exports, __webpack_require__) { - return parts; -} +"use strict"; -function expandTop(str) { - if (!str) - return []; +var addToUnscopables = __webpack_require__(180); +var step = __webpack_require__(190); +var Iterators = __webpack_require__(35); +var toIObject = __webpack_require__(74); - // I don't know why Bash 4.3 does this, but it does. - // Anything starting with {} will have the first two bytes preserved - // but *only* at the top level, so {},a}b will not expand to anything, - // but a{},b}c will be expanded to [a}c,abc]. - // One could argue that this is a bug in Bash, but since the goal of - // this module is to match Bash's rules, we escape a leading {} - if (str.substr(0, 2) === '{}') { - str = '\\{\\}' + str.substr(2); +// 22.1.3.4 Array.prototype.entries() +// 22.1.3.13 Array.prototype.keys() +// 22.1.3.29 Array.prototype.values() +// 22.1.3.30 Array.prototype[@@iterator]() +module.exports = __webpack_require__(103)(Array, 'Array', function (iterated, kind) { + this._t = toIObject(iterated); // target + this._i = 0; // next index + this._k = kind; // kind +// 22.1.5.2.1 %ArrayIteratorPrototype%.next() +}, function () { + var O = this._t; + var kind = this._k; + var index = this._i++; + if (!O || index >= O.length) { + this._t = undefined; + return step(1); } + if (kind == 'keys') return step(0, index); + if (kind == 'values') return step(0, O[index]); + return step(0, [index, O[index]]); +}, 'values'); - return expand(escapeBraces(str), true).map(unescapeBraces); -} - -function identity(e) { - return e; -} +// argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7) +Iterators.Arguments = Iterators.Array; -function embrace(str) { - return '{' + str + '}'; -} -function isPadded(el) { - return /^-?0\d/.test(el); -} +addToUnscopables('keys'); +addToUnscopables('values'); +addToUnscopables('entries'); -function lte(i, y) { - return i <= y; -} -function gte(i, y) { - return i >= y; -} -function expand(str, isTop) { - var expansions = []; +/***/ }), +/* 205 */ +/***/ (function(module, exports) { - var m = balanced('{', '}', str); - if (!m || /\$$/.test(m.pre)) return [str]; - var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); - var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); - var isSequence = isNumericSequence || isAlphaSequence; - var isOptions = m.body.indexOf(',') >= 0; - if (!isSequence && !isOptions) { - // {a},b} - if (m.post.match(/,.*\}/)) { - str = m.pre + '{' + m.body + escClose + m.post; - return expand(str); - } - return [str]; - } - var n; - if (isSequence) { - n = m.body.split(/\.\./); - } else { - n = parseCommaParts(m.body); - if (n.length === 1) { - // x{{a,b}}y ==> x{a}y x{b}y - n = expand(n[0], false).map(embrace); - if (n.length === 1) { - var post = m.post.length - ? expand(m.post, false) - : ['']; - return post.map(function(p) { - return m.pre + n[0] + p; - }); - } - } - } +/***/ }), +/* 206 */ +/***/ (function(module, exports, __webpack_require__) { - // at this point, n is the parts, and we know it's not a comma set - // with a single entry. +"use strict"; - // no need to expand pre, since it is guaranteed to be free of brace-sets - var pre = m.pre; - var post = m.post.length - ? expand(m.post, false) - : ['']; +var LIBRARY = __webpack_require__(69); +var global = __webpack_require__(11); +var ctx = __webpack_require__(48); +var classof = __webpack_require__(100); +var $export = __webpack_require__(41); +var isObject = __webpack_require__(34); +var aFunction = __webpack_require__(46); +var anInstance = __webpack_require__(181); +var forOf = __webpack_require__(183); +var speciesConstructor = __webpack_require__(108); +var task = __webpack_require__(109).set; +var microtask = __webpack_require__(191)(); +var newPromiseCapabilityModule = __webpack_require__(70); +var perform = __webpack_require__(104); +var userAgent = __webpack_require__(202); +var promiseResolve = __webpack_require__(105); +var PROMISE = 'Promise'; +var TypeError = global.TypeError; +var process = global.process; +var versions = process && process.versions; +var v8 = versions && versions.v8 || ''; +var $Promise = global[PROMISE]; +var isNode = classof(process) == 'process'; +var empty = function () { /* empty */ }; +var Internal, newGenericPromiseCapability, OwnPromiseCapability, Wrapper; +var newPromiseCapability = newGenericPromiseCapability = newPromiseCapabilityModule.f; - var N; +var USE_NATIVE = !!function () { + try { + // correct subclassing with @@species support + var promise = $Promise.resolve(1); + var FakePromise = (promise.constructor = {})[__webpack_require__(13)('species')] = function (exec) { + exec(empty, empty); + }; + // unhandled rejections tracking support, NodeJS Promise without it fails @@species test + return (isNode || typeof PromiseRejectionEvent == 'function') + && promise.then(empty) instanceof FakePromise + // v8 6.6 (Node 10 and Chrome 66) have a bug with resolving custom thenables + // https://bugs.chromium.org/p/chromium/issues/detail?id=830565 + // we can't detect it synchronously, so just check versions + && v8.indexOf('6.6') !== 0 + && userAgent.indexOf('Chrome/66') === -1; + } catch (e) { /* empty */ } +}(); - if (isSequence) { - var x = numeric(n[0]); - var y = numeric(n[1]); - var width = Math.max(n[0].length, n[1].length) - var incr = n.length == 3 - ? Math.abs(numeric(n[2])) - : 1; - var test = lte; - var reverse = y < x; - if (reverse) { - incr *= -1; - test = gte; - } - var pad = n.some(isPadded); - - N = []; - - for (var i = x; test(i, y); i += incr) { - var c; - if (isAlphaSequence) { - c = String.fromCharCode(i); - if (c === '\\') - c = ''; - } else { - c = String(i); - if (pad) { - var need = width - c.length; - if (need > 0) { - var z = new Array(need + 1).join('0'); - if (i < 0) - c = '-' + z + c.slice(1); - else - c = z + c; +// helpers +var isThenable = function (it) { + var then; + return isObject(it) && typeof (then = it.then) == 'function' ? then : false; +}; +var notify = function (promise, isReject) { + if (promise._n) return; + promise._n = true; + var chain = promise._c; + microtask(function () { + var value = promise._v; + var ok = promise._s == 1; + var i = 0; + var run = function (reaction) { + var handler = ok ? reaction.ok : reaction.fail; + var resolve = reaction.resolve; + var reject = reaction.reject; + var domain = reaction.domain; + var result, then, exited; + try { + if (handler) { + if (!ok) { + if (promise._h == 2) onHandleUnhandled(promise); + promise._h = 1; } - } + if (handler === true) result = value; + else { + if (domain) domain.enter(); + result = handler(value); // may throw + if (domain) { + domain.exit(); + exited = true; + } + } + if (result === reaction.promise) { + reject(TypeError('Promise-chain cycle')); + } else if (then = isThenable(result)) { + then.call(result, resolve, reject); + } else resolve(result); + } else reject(value); + } catch (e) { + if (domain && !exited) domain.exit(); + reject(e); } - N.push(c); + }; + while (chain.length > i) run(chain[i++]); // variable length - can't use forEach + promise._c = []; + promise._n = false; + if (isReject && !promise._h) onUnhandled(promise); + }); +}; +var onUnhandled = function (promise) { + task.call(global, function () { + var value = promise._v; + var unhandled = isUnhandled(promise); + var result, handler, console; + if (unhandled) { + result = perform(function () { + if (isNode) { + process.emit('unhandledRejection', value, promise); + } else if (handler = global.onunhandledrejection) { + handler({ promise: promise, reason: value }); + } else if ((console = global.console) && console.error) { + console.error('Unhandled promise rejection', value); + } + }); + // Browsers should not trigger `rejectionHandled` event if it was handled here, NodeJS - should + promise._h = isNode || isUnhandled(promise) ? 2 : 1; + } promise._a = undefined; + if (unhandled && result.e) throw result.v; + }); +}; +var isUnhandled = function (promise) { + return promise._h !== 1 && (promise._a || promise._c).length === 0; +}; +var onHandleUnhandled = function (promise) { + task.call(global, function () { + var handler; + if (isNode) { + process.emit('rejectionHandled', promise); + } else if (handler = global.onrejectionhandled) { + handler({ promise: promise, reason: promise._v }); } - } else { - N = concatMap(n, function(el) { return expand(el, false) }); - } - - for (var j = 0; j < N.length; j++) { - for (var k = 0; k < post.length; k++) { - var expansion = pre + N[j] + post[k]; - if (!isTop || isSequence || expansion) - expansions.push(expansion); + }); +}; +var $reject = function (value) { + var promise = this; + if (promise._d) return; + promise._d = true; + promise = promise._w || promise; // unwrap + promise._v = value; + promise._s = 2; + if (!promise._a) promise._a = promise._c.slice(); + notify(promise, true); +}; +var $resolve = function (value) { + var promise = this; + var then; + if (promise._d) return; + promise._d = true; + promise = promise._w || promise; // unwrap + try { + if (promise === value) throw TypeError("Promise can't be resolved itself"); + if (then = isThenable(value)) { + microtask(function () { + var wrapper = { _w: promise, _d: false }; // wrap + try { + then.call(value, ctx($resolve, wrapper, 1), ctx($reject, wrapper, 1)); + } catch (e) { + $reject.call(wrapper, e); + } + }); + } else { + promise._v = value; + promise._s = 1; + notify(promise, false); } + } catch (e) { + $reject.call({ _w: promise, _d: false }, e); // wrap } +}; - return expansions; +// constructor polyfill +if (!USE_NATIVE) { + // 25.4.3.1 Promise(executor) + $Promise = function Promise(executor) { + anInstance(this, $Promise, PROMISE, '_h'); + aFunction(executor); + Internal.call(this); + try { + executor(ctx($resolve, this, 1), ctx($reject, this, 1)); + } catch (err) { + $reject.call(this, err); + } + }; + // eslint-disable-next-line no-unused-vars + Internal = function Promise(executor) { + this._c = []; // <- awaiting reactions + this._a = undefined; // <- checked in isUnhandled reactions + this._s = 0; // <- state + this._d = false; // <- done + this._v = undefined; // <- value + this._h = 0; // <- rejection state, 0 - default, 1 - handled, 2 - unhandled + this._n = false; // <- notify + }; + Internal.prototype = __webpack_require__(196)($Promise.prototype, { + // 25.4.5.3 Promise.prototype.then(onFulfilled, onRejected) + then: function then(onFulfilled, onRejected) { + var reaction = newPromiseCapability(speciesConstructor(this, $Promise)); + reaction.ok = typeof onFulfilled == 'function' ? onFulfilled : true; + reaction.fail = typeof onRejected == 'function' && onRejected; + reaction.domain = isNode ? process.domain : undefined; + this._c.push(reaction); + if (this._a) this._a.push(reaction); + if (this._s) notify(this, false); + return reaction.promise; + }, + // 25.4.5.1 Promise.prototype.catch(onRejected) + 'catch': function (onRejected) { + return this.then(undefined, onRejected); + } + }); + OwnPromiseCapability = function () { + var promise = new Internal(); + this.promise = promise; + this.resolve = ctx($resolve, promise, 1); + this.reject = ctx($reject, promise, 1); + }; + newPromiseCapabilityModule.f = newPromiseCapability = function (C) { + return C === $Promise || C === Wrapper + ? new OwnPromiseCapability(C) + : newGenericPromiseCapability(C); + }; } +$export($export.G + $export.W + $export.F * !USE_NATIVE, { Promise: $Promise }); +__webpack_require__(71)($Promise, PROMISE); +__webpack_require__(198)(PROMISE); +Wrapper = __webpack_require__(23)[PROMISE]; + +// statics +$export($export.S + $export.F * !USE_NATIVE, PROMISE, { + // 25.4.4.5 Promise.reject(r) + reject: function reject(r) { + var capability = newPromiseCapability(this); + var $$reject = capability.reject; + $$reject(r); + return capability.promise; + } +}); +$export($export.S + $export.F * (LIBRARY || !USE_NATIVE), PROMISE, { + // 25.4.4.6 Promise.resolve(x) + resolve: function resolve(x) { + return promiseResolve(LIBRARY && this === Wrapper ? $Promise : this, x); + } +}); +$export($export.S + $export.F * !(USE_NATIVE && __webpack_require__(189)(function (iter) { + $Promise.all(iter)['catch'](empty); +})), PROMISE, { + // 25.4.4.1 Promise.all(iterable) + all: function all(iterable) { + var C = this; + var capability = newPromiseCapability(C); + var resolve = capability.resolve; + var reject = capability.reject; + var result = perform(function () { + var values = []; + var index = 0; + var remaining = 1; + forOf(iterable, false, function (promise) { + var $index = index++; + var alreadyCalled = false; + values.push(undefined); + remaining++; + C.resolve(promise).then(function (value) { + if (alreadyCalled) return; + alreadyCalled = true; + values[$index] = value; + --remaining || resolve(values); + }, reject); + }); + --remaining || resolve(values); + }); + if (result.e) reject(result.v); + return capability.promise; + }, + // 25.4.4.4 Promise.race(iterable) + race: function race(iterable) { + var C = this; + var capability = newPromiseCapability(C); + var reject = capability.reject; + var result = perform(function () { + forOf(iterable, false, function (promise) { + C.resolve(promise).then(capability.resolve, reject); + }); + }); + if (result.e) reject(result.v); + return capability.promise; + } +}); /***/ }), -/* 176 */ +/* 207 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +var $at = __webpack_require__(199)(true); -function preserveCamelCase(str) { - let isLastCharLower = false; - let isLastCharUpper = false; - let isLastLastCharUpper = false; +// 21.1.3.27 String.prototype[@@iterator]() +__webpack_require__(103)(String, 'String', function (iterated) { + this._t = String(iterated); // target + this._i = 0; // next index +// 21.1.5.2.1 %StringIteratorPrototype%.next() +}, function () { + var O = this._t; + var index = this._i; + var point; + if (index >= O.length) return { value: undefined, done: true }; + point = $at(O, index); + this._i += point.length; + return { value: point, done: false }; +}); - for (let i = 0; i < str.length; i++) { - const c = str[i]; - if (isLastCharLower && /[a-zA-Z]/.test(c) && c.toUpperCase() === c) { - str = str.substr(0, i) + '-' + str.substr(i); - isLastCharLower = false; - isLastLastCharUpper = isLastCharUpper; - isLastCharUpper = true; - i++; - } else if (isLastCharUpper && isLastLastCharUpper && /[a-zA-Z]/.test(c) && c.toLowerCase() === c) { - str = str.substr(0, i - 1) + '-' + str.substr(i - 1); - isLastLastCharUpper = isLastCharUpper; - isLastCharUpper = false; - isLastCharLower = true; - } else { - isLastCharLower = c.toLowerCase() === c; - isLastLastCharUpper = isLastCharUpper; - isLastCharUpper = c.toUpperCase() === c; - } - } +/***/ }), +/* 208 */ +/***/ (function(module, exports, __webpack_require__) { - return str; -} +"use strict"; +// https://github.com/tc39/proposal-promise-finally -module.exports = function (str) { - if (arguments.length > 1) { - str = Array.from(arguments) - .map(x => x.trim()) - .filter(x => x.length) - .join('-'); - } else { - str = str.trim(); - } +var $export = __webpack_require__(41); +var core = __webpack_require__(23); +var global = __webpack_require__(11); +var speciesConstructor = __webpack_require__(108); +var promiseResolve = __webpack_require__(105); - if (str.length === 0) { - return ''; - } +$export($export.P + $export.R, 'Promise', { 'finally': function (onFinally) { + var C = speciesConstructor(this, core.Promise || global.Promise); + var isFunction = typeof onFinally == 'function'; + return this.then( + isFunction ? function (x) { + return promiseResolve(C, onFinally()).then(function () { return x; }); + } : onFinally, + isFunction ? function (e) { + return promiseResolve(C, onFinally()).then(function () { throw e; }); + } : onFinally + ); +} }); - if (str.length === 1) { - return str.toLowerCase(); - } - if (/^[a-z0-9]+$/.test(str)) { - return str; - } +/***/ }), +/* 209 */ +/***/ (function(module, exports, __webpack_require__) { - const hasUpperCase = str !== str.toLowerCase(); +"use strict"; - if (hasUpperCase) { - str = preserveCamelCase(str); - } +// https://github.com/tc39/proposal-promise-try +var $export = __webpack_require__(41); +var newPromiseCapability = __webpack_require__(70); +var perform = __webpack_require__(104); - return str - .replace(/^[_.\- ]+/, '') - .toLowerCase() - .replace(/[_.\- ]+(\w|$)/g, (m, p1) => p1.toUpperCase()); -}; +$export($export.S, 'Promise', { 'try': function (callbackfn) { + var promiseCapability = newPromiseCapability.f(this); + var result = perform(callbackfn); + (result.e ? promiseCapability.reject : promiseCapability.resolve)(result.v); + return promiseCapability.promise; +} }); /***/ }), -/* 177 */, -/* 178 */ -/***/ (function(module, exports) { +/* 210 */ +/***/ (function(module, exports, __webpack_require__) { -module.exports = function (xs, fn) { - var res = []; - for (var i = 0; i < xs.length; i++) { - var x = fn(xs[i], i); - if (isArray(x)) res.push.apply(res, x); - else res.push(x); - } - return res; -}; +__webpack_require__(204); +var global = __webpack_require__(11); +var hide = __webpack_require__(31); +var Iterators = __webpack_require__(35); +var TO_STRING_TAG = __webpack_require__(13)('toStringTag'); -var isArray = Array.isArray || function (xs) { - return Object.prototype.toString.call(xs) === '[object Array]'; -}; +var DOMIterables = ('CSSRuleList,CSSStyleDeclaration,CSSValueList,ClientRectList,DOMRectList,DOMStringList,' + + 'DOMTokenList,DataTransferItemList,FileList,HTMLAllCollection,HTMLCollection,HTMLFormElement,HTMLSelectElement,' + + 'MediaList,MimeTypeArray,NamedNodeMap,NodeList,PaintRequestList,Plugin,PluginArray,SVGLengthList,SVGNumberList,' + + 'SVGPathSegList,SVGPointList,SVGStringList,SVGTransformList,SourceBufferList,StyleSheetList,TextTrackCueList,' + + 'TextTrackList,TouchList').split(','); + +for (var i = 0; i < DOMIterables.length; i++) { + var NAME = DOMIterables[i]; + var Collection = global[NAME]; + var proto = Collection && Collection.prototype; + if (proto && !proto[TO_STRING_TAG]) hide(proto, TO_STRING_TAG, NAME); + Iterators[NAME] = Iterators.Array; +} /***/ }), -/* 179 */ +/* 211 */ /***/ (function(module, exports, __webpack_require__) { -__webpack_require__(205); -__webpack_require__(207); -__webpack_require__(210); -__webpack_require__(206); -__webpack_require__(208); -__webpack_require__(209); -module.exports = __webpack_require__(23).Promise; +/** + * This is the web browser implementation of `debug()`. + * + * Expose `debug()` as the module. + */ +exports = module.exports = __webpack_require__(112); +exports.log = log; +exports.formatArgs = formatArgs; +exports.save = save; +exports.load = load; +exports.useColors = useColors; +exports.storage = 'undefined' != typeof chrome + && 'undefined' != typeof chrome.storage + ? chrome.storage.local + : localstorage(); -/***/ }), -/* 180 */ -/***/ (function(module, exports) { +/** + * Colors. + */ -module.exports = function () { /* empty */ }; +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' +]; +/** + * Currently only WebKit-based Web Inspectors, Firefox >= v31, + * and the Firebug extension (any Firefox version) are known + * to support "%c" CSS customizations. + * + * TODO: add a `localStorage` variable to explicitly enable/disable colors + */ -/***/ }), -/* 181 */ -/***/ (function(module, exports) { +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') { + return true; + } -module.exports = function (it, Constructor, name, forbiddenField) { - if (!(it instanceof Constructor) || (forbiddenField !== undefined && forbiddenField in it)) { - throw TypeError(name + ': incorrect invocation!'); - } return it; + // 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+)/)); +} + +/** + * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. + */ + +exports.formatters.j = function(v) { + try { + return JSON.stringify(v); + } catch (err) { + return '[UnexpectedJSONParseError]: ' + err.message; + } }; -/***/ }), -/* 182 */ -/***/ (function(module, exports, __webpack_require__) { +/** + * Colorize log arguments if enabled. + * + * @api public + */ -// false -> Array#indexOf -// true -> Array#includes -var toIObject = __webpack_require__(74); -var toLength = __webpack_require__(110); -var toAbsoluteIndex = __webpack_require__(200); -module.exports = function (IS_INCLUDES) { - return function ($this, el, fromIndex) { - var O = toIObject($this); - var length = toLength(O.length); - var index = toAbsoluteIndex(fromIndex, length); - var value; - // Array#includes uses SameValueZero equality algorithm - // eslint-disable-next-line no-self-compare - if (IS_INCLUDES && el != el) while (length > index) { - value = O[index++]; - // eslint-disable-next-line no-self-compare - if (value != value) return true; - // Array#indexOf ignores holes, Array#includes - not - } else for (;length > index; index++) if (IS_INCLUDES || index in O) { - if (O[index] === el) return IS_INCLUDES || index || 0; - } return !IS_INCLUDES && -1; - }; -}; +function formatArgs(args) { + var useColors = this.useColors; + args[0] = (useColors ? '%c' : '') + + this.namespace + + (useColors ? ' %c' : ' ') + + args[0] + + (useColors ? '%c ' : ' ') + + '+' + exports.humanize(this.diff); -/***/ }), -/* 183 */ -/***/ (function(module, exports, __webpack_require__) { + if (!useColors) return; -var ctx = __webpack_require__(48); -var call = __webpack_require__(187); -var isArrayIter = __webpack_require__(186); -var anObject = __webpack_require__(27); -var toLength = __webpack_require__(110); -var getIterFn = __webpack_require__(203); -var BREAK = {}; -var RETURN = {}; -var exports = module.exports = function (iterable, entries, fn, that, ITERATOR) { - var iterFn = ITERATOR ? function () { return iterable; } : getIterFn(iterable); - var f = ctx(fn, that, entries ? 2 : 1); + var 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 var index = 0; - var length, step, iterator, result; - if (typeof iterFn != 'function') throw TypeError(iterable + ' is not iterable!'); - // fast case for arrays with default iterator - if (isArrayIter(iterFn)) for (length = toLength(iterable.length); length > index; index++) { - result = entries ? f(anObject(step = iterable[index])[0], step[1]) : f(iterable[index]); - if (result === BREAK || result === RETURN) return result; - } else for (iterator = iterFn.call(iterable); !(step = iterator.next()).done;) { - result = call(iterator, f, step.value, entries); - if (result === BREAK || result === RETURN) return result; - } -}; -exports.BREAK = BREAK; -exports.RETURN = RETURN; + var lastC = 0; + args[0].replace(/%[a-zA-Z%]/g, function(match) { + if ('%%' === match) return; + index++; + if ('%c' === match) { + // we only are interested in the *last* %c + // (the user may have provided their own) + lastC = index; + } + }); + args.splice(lastC, 0, c); +} -/***/ }), -/* 184 */ -/***/ (function(module, exports, __webpack_require__) { +/** + * Invokes `console.log()` when available. + * No-op when `console.log` is not a "function". + * + * @api public + */ -module.exports = !__webpack_require__(33) && !__webpack_require__(85)(function () { - return Object.defineProperty(__webpack_require__(68)('div'), 'a', { get: function () { return 7; } }).a != 7; -}); +function log() { + // this hackery is required for IE8/9, where + // the `console.log` function doesn't have 'apply' + return 'object' === typeof console + && console.log + && Function.prototype.apply.call(console.log, console, arguments); +} +/** + * Save `namespaces`. + * + * @param {String} namespaces + * @api private + */ -/***/ }), -/* 185 */ -/***/ (function(module, exports) { +function save(namespaces) { + try { + if (null == namespaces) { + exports.storage.removeItem('debug'); + } else { + exports.storage.debug = namespaces; + } + } catch(e) {} +} -// fast apply, http://jsperf.lnkit.com/fast-apply/5 -module.exports = function (fn, args, that) { - var un = that === undefined; - switch (args.length) { - case 0: return un ? fn() - : fn.call(that); - case 1: return un ? fn(args[0]) - : fn.call(that, args[0]); - case 2: return un ? fn(args[0], args[1]) - : fn.call(that, args[0], args[1]); - case 3: return un ? fn(args[0], args[1], args[2]) - : fn.call(that, args[0], args[1], args[2]); - case 4: return un ? fn(args[0], args[1], args[2], args[3]) - : fn.call(that, args[0], args[1], args[2], args[3]); - } return fn.apply(that, args); -}; +/** + * Load `namespaces`. + * + * @return {String} returns the previously persisted debug modes + * @api private + */ +function load() { + var r; + try { + r = exports.storage.debug; + } catch(e) {} -/***/ }), -/* 186 */ -/***/ (function(module, exports, __webpack_require__) { + // 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; + } -// check on default Array iterator -var Iterators = __webpack_require__(35); -var ITERATOR = __webpack_require__(13)('iterator'); -var ArrayProto = Array.prototype; + return r; +} -module.exports = function (it) { - return it !== undefined && (Iterators.Array === it || ArrayProto[ITERATOR] === it); -}; +/** + * Enable namespaces listed in `localStorage.debug` initially. + */ +exports.enable(load()); -/***/ }), -/* 187 */ -/***/ (function(module, exports, __webpack_require__) { +/** + * Localstorage attempts to return the localstorage. + * + * This is necessary because safari throws + * when a user disables cookies/localstorage + * and you attempt to access it. + * + * @return {LocalStorage} + * @api private + */ -// call something on iterator step with safe closing on error -var anObject = __webpack_require__(27); -module.exports = function (iterator, fn, value, entries) { +function localstorage() { try { - return entries ? fn(anObject(value)[0], value[1]) : fn(value); - // 7.4.6 IteratorClose(iterator, completion) - } catch (e) { - var ret = iterator['return']; - if (ret !== undefined) anObject(ret.call(iterator)); - throw e; - } -}; + return window.localStorage; + } catch (e) {} +} /***/ }), -/* 188 */ +/* 212 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; - -var create = __webpack_require__(192); -var descriptor = __webpack_require__(106); -var setToStringTag = __webpack_require__(71); -var IteratorPrototype = {}; - -// 25.1.2.1.1 %IteratorPrototype%[@@iterator]() -__webpack_require__(31)(IteratorPrototype, __webpack_require__(13)('iterator'), function () { return this; }); +/** + * Detect Electron renderer process, which is node, but we should + * treat as a browser. + */ -module.exports = function (Constructor, NAME, next) { - Constructor.prototype = create(IteratorPrototype, { next: descriptor(1, next) }); - setToStringTag(Constructor, NAME + ' Iterator'); -}; +if (typeof process === 'undefined' || process.type === 'renderer') { + module.exports = __webpack_require__(211); +} else { + module.exports = __webpack_require__(213); +} /***/ }), -/* 189 */ +/* 213 */ /***/ (function(module, exports, __webpack_require__) { -var ITERATOR = __webpack_require__(13)('iterator'); -var SAFE_CLOSING = false; +/** + * Module dependencies. + */ -try { - var riter = [7][ITERATOR](); - riter['return'] = function () { SAFE_CLOSING = true; }; - // eslint-disable-next-line no-throw-literal - Array.from(riter, function () { throw 2; }); -} catch (e) { /* empty */ } +var tty = __webpack_require__(79); +var util = __webpack_require__(2); -module.exports = function (exec, skipClosing) { - if (!skipClosing && !SAFE_CLOSING) return false; - var safe = false; - try { - var arr = [7]; - var iter = arr[ITERATOR](); - iter.next = function () { return { done: safe = true }; }; - arr[ITERATOR] = function () { return iter; }; - exec(arr); - } catch (e) { /* empty */ } - return safe; -}; +/** + * This is the Node.js implementation of `debug()`. + * + * Expose `debug()` as the module. + */ +exports = module.exports = __webpack_require__(112); +exports.init = init; +exports.log = log; +exports.formatArgs = formatArgs; +exports.save = save; +exports.load = load; +exports.useColors = useColors; -/***/ }), -/* 190 */ -/***/ (function(module, exports) { +/** + * Colors. + */ -module.exports = function (done, value) { - return { value: value, done: !!done }; -}; +exports.colors = [ 6, 2, 3, 4, 5, 1 ]; +try { + var supportsColor = __webpack_require__(239); + if (supportsColor && 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 (err) { + // swallow - we only care if `supports-color` is available; it doesn't have to be. +} -/***/ }), -/* 191 */ -/***/ (function(module, exports, __webpack_require__) { +/** + * Build up the default `inspectOpts` object from the environment variables. + * + * $ DEBUG_COLORS=no DEBUG_DEPTH=10 DEBUG_SHOW_HIDDEN=enabled node script.js + */ -var global = __webpack_require__(11); -var macrotask = __webpack_require__(109).set; -var Observer = global.MutationObserver || global.WebKitMutationObserver; -var process = global.process; -var Promise = global.Promise; -var isNode = __webpack_require__(47)(process) == 'process'; +exports.inspectOpts = Object.keys(process.env).filter(function (key) { + return /^debug_/i.test(key); +}).reduce(function (obj, key) { + // camel-case + var prop = key + .substring(6) + .toLowerCase() + .replace(/_([a-z])/g, function (_, k) { return k.toUpperCase() }); -module.exports = function () { - var head, last, notify; + // coerce string value into JS value + var 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); - var flush = function () { - var parent, fn; - if (isNode && (parent = process.domain)) parent.exit(); - while (head) { - fn = head.fn; - head = head.next; - try { - fn(); - } catch (e) { - if (head) notify(); - else last = undefined; - throw e; - } - } last = undefined; - if (parent) parent.enter(); - }; + obj[prop] = val; + return obj; +}, {}); - // Node.js - if (isNode) { - notify = function () { - process.nextTick(flush); - }; - // browsers with MutationObserver, except iOS Safari - https://github.com/zloirock/core-js/issues/339 - } else if (Observer && !(global.navigator && global.navigator.standalone)) { - var toggle = true; - var node = document.createTextNode(''); - new Observer(flush).observe(node, { characterData: true }); // eslint-disable-line no-new - notify = function () { - node.data = toggle = !toggle; - }; - // environments with maybe non-completely correct, but existent Promise - } else if (Promise && Promise.resolve) { - // Promise.resolve without an argument throws an error in LG WebOS 2 - var promise = Promise.resolve(undefined); - notify = function () { - promise.then(flush); - }; - // for other environments - macrotask based on: - // - setImmediate - // - MessageChannel - // - window.postMessag - // - onreadystatechange - // - setTimeout - } else { - notify = function () { - // strange IE + webpack dev server bug - use .call(global) - macrotask.call(global, flush); - }; - } +/** + * Is stdout a TTY? Colored output is enabled when `true`. + */ - return function (fn) { - var task = { fn: fn, next: undefined }; - if (last) last.next = task; - if (!head) { - head = task; - notify(); - } last = task; - }; -}; +function useColors() { + return 'colors' in exports.inspectOpts + ? Boolean(exports.inspectOpts.colors) + : tty.isatty(process.stderr.fd); +} +/** + * Map %o to `util.inspect()`, all on a single line. + */ -/***/ }), -/* 192 */ -/***/ (function(module, exports, __webpack_require__) { +exports.formatters.o = function(v) { + this.inspectOpts.colors = this.useColors; + return util.inspect(v, this.inspectOpts) + .split('\n').map(function(str) { + return str.trim() + }).join(' '); +}; -// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties]) -var anObject = __webpack_require__(27); -var dPs = __webpack_require__(193); -var enumBugKeys = __webpack_require__(101); -var IE_PROTO = __webpack_require__(72)('IE_PROTO'); -var Empty = function () { /* empty */ }; -var PROTOTYPE = 'prototype'; +/** + * Map %o to `util.inspect()`, allowing multiple lines if needed. + */ -// Create object with fake `null` prototype: use iframe Object with cleared prototype -var createDict = function () { - // Thrash, waste and sodomy: IE GC bug - var iframe = __webpack_require__(68)('iframe'); - var i = enumBugKeys.length; - var lt = '<'; - var gt = '>'; - var iframeDocument; - iframe.style.display = 'none'; - __webpack_require__(102).appendChild(iframe); - iframe.src = 'javascript:'; // eslint-disable-line no-script-url - // createDict = iframe.contentWindow.Object; - // html.removeChild(iframe); - iframeDocument = iframe.contentWindow.document; - iframeDocument.open(); - iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt); - iframeDocument.close(); - createDict = iframeDocument.F; - while (i--) delete createDict[PROTOTYPE][enumBugKeys[i]]; - return createDict(); +exports.formatters.O = function(v) { + this.inspectOpts.colors = this.useColors; + return util.inspect(v, this.inspectOpts); }; -module.exports = Object.create || function create(O, Properties) { - var result; - if (O !== null) { - Empty[PROTOTYPE] = anObject(O); - result = new Empty(); - Empty[PROTOTYPE] = null; - // add "__proto__" for Object.getPrototypeOf polyfill - result[IE_PROTO] = O; - } else result = createDict(); - return Properties === undefined ? result : dPs(result, Properties); -}; +/** + * Adds ANSI color escape codes if enabled. + * + * @api public + */ +function formatArgs(args) { + var name = this.namespace; + var useColors = this.useColors; -/***/ }), -/* 193 */ -/***/ (function(module, exports, __webpack_require__) { + if (useColors) { + var c = this.color; + var colorCode = '\u001b[3' + (c < 8 ? c : '8;5;' + c); + var prefix = ' ' + colorCode + ';1m' + name + ' ' + '\u001b[0m'; -var dP = __webpack_require__(50); -var anObject = __webpack_require__(27); -var getKeys = __webpack_require__(132); + args[0] = prefix + args[0].split('\n').join('\n' + prefix); + args.push(colorCode + 'm+' + exports.humanize(this.diff) + '\u001b[0m'); + } else { + args[0] = getDate() + name + ' ' + args[0]; + } +} -module.exports = __webpack_require__(33) ? Object.defineProperties : function defineProperties(O, Properties) { - anObject(O); - var keys = getKeys(Properties); - var length = keys.length; - var i = 0; - var P; - while (length > i) dP.f(O, P = keys[i++], Properties[P]); - return O; -}; +function getDate() { + if (exports.inspectOpts.hideDate) { + return ''; + } else { + return new Date().toISOString() + ' '; + } +} +/** + * Invokes `util.format()` with the specified arguments and writes to stderr. + */ -/***/ }), -/* 194 */ -/***/ (function(module, exports, __webpack_require__) { +function log() { + return process.stderr.write(util.format.apply(util, arguments) + '\n'); +} -// 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O) -var has = __webpack_require__(49); -var toObject = __webpack_require__(133); -var IE_PROTO = __webpack_require__(72)('IE_PROTO'); -var ObjectProto = Object.prototype; +/** + * Save `namespaces`. + * + * @param {String} namespaces + * @api private + */ -module.exports = Object.getPrototypeOf || function (O) { - O = toObject(O); - if (has(O, IE_PROTO)) return O[IE_PROTO]; - if (typeof O.constructor == 'function' && O instanceof O.constructor) { - return O.constructor.prototype; - } return O instanceof Object ? ObjectProto : null; -}; +function save(namespaces) { + if (null == namespaces) { + // 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; + } else { + process.env.DEBUG = namespaces; + } +} +/** + * Load `namespaces`. + * + * @return {String} returns the previously persisted debug modes + * @api private + */ -/***/ }), -/* 195 */ -/***/ (function(module, exports, __webpack_require__) { +function load() { + return process.env.DEBUG; +} -var has = __webpack_require__(49); -var toIObject = __webpack_require__(74); -var arrayIndexOf = __webpack_require__(182)(false); -var IE_PROTO = __webpack_require__(72)('IE_PROTO'); +/** + * Init logic for `debug` instances. + * + * Create a new `inspectOpts` object in case `useColors` is set + * differently for a particular `debug` instance. + */ -module.exports = function (object, names) { - var O = toIObject(object); - var i = 0; - var result = []; - var key; - for (key in O) if (key != IE_PROTO) has(O, key) && result.push(key); - // Don't enum bug & hidden keys - while (names.length > i) if (has(O, key = names[i++])) { - ~arrayIndexOf(result, key) || result.push(key); +function init (debug) { + debug.inspectOpts = {}; + + var keys = Object.keys(exports.inspectOpts); + for (var i = 0; i < keys.length; i++) { + debug.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]]; } - return result; -}; +} + +/** + * Enable namespaces listed in `process.env.DEBUG` initially. + */ + +exports.enable(load()); /***/ }), -/* 196 */ +/* 214 */, +/* 215 */, +/* 216 */, +/* 217 */ /***/ (function(module, exports, __webpack_require__) { -var hide = __webpack_require__(31); -module.exports = function (target, src, safe) { - for (var key in src) { - if (safe && target[key]) target[key] = src[key]; - else hide(target, key, src[key]); - } return target; -}; +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER 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. +var pathModule = __webpack_require__(0); +var isWindows = process.platform === 'win32'; +var fs = __webpack_require__(3); -/***/ }), -/* 197 */ -/***/ (function(module, exports, __webpack_require__) { +// JavaScript implementation of realpath, ported from node pre-v6 -module.exports = __webpack_require__(31); +var DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG); +function rethrow() { + // Only enable in debug mode. A backtrace uses ~1000 bytes of heap space and + // is fairly slow to generate. + var callback; + if (DEBUG) { + var backtrace = new Error; + callback = debugCallback; + } else + callback = missingCallback; -/***/ }), -/* 198 */ -/***/ (function(module, exports, __webpack_require__) { + return callback; -"use strict"; + function debugCallback(err) { + if (err) { + backtrace.message = err.message; + err = backtrace; + missingCallback(err); + } + } -var global = __webpack_require__(11); -var core = __webpack_require__(23); -var dP = __webpack_require__(50); -var DESCRIPTORS = __webpack_require__(33); -var SPECIES = __webpack_require__(13)('species'); + function missingCallback(err) { + if (err) { + if (process.throwDeprecation) + throw err; // Forgot a callback but don't know where? Use NODE_DEBUG=fs + else if (!process.noDeprecation) { + var msg = 'fs: missing callback ' + (err.stack || err.message); + if (process.traceDeprecation) + console.trace(msg); + else + console.error(msg); + } + } + } +} -module.exports = function (KEY) { - var C = typeof core[KEY] == 'function' ? core[KEY] : global[KEY]; - if (DESCRIPTORS && C && !C[SPECIES]) dP.f(C, SPECIES, { - configurable: true, - get: function () { return this; } - }); -}; +function maybeCallback(cb) { + return typeof cb === 'function' ? cb : rethrow(); +} +var normalize = pathModule.normalize; -/***/ }), -/* 199 */ -/***/ (function(module, exports, __webpack_require__) { +// Regexp that finds the next partion of a (partial) path +// result is [base_with_slash, base], e.g. ['somedir/', 'somedir'] +if (isWindows) { + var nextPartRe = /(.*?)(?:[\/\\]+|$)/g; +} else { + var nextPartRe = /(.*?)(?:[\/]+|$)/g; +} -var toInteger = __webpack_require__(73); -var defined = __webpack_require__(67); -// true -> String#at -// false -> String#codePointAt -module.exports = function (TO_STRING) { - return function (that, pos) { - var s = String(defined(that)); - var i = toInteger(pos); - var l = s.length; - var a, b; - if (i < 0 || i >= l) return TO_STRING ? '' : undefined; - a = s.charCodeAt(i); - return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff - ? TO_STRING ? s.charAt(i) : a - : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000; - }; -}; +// Regex to find the device root, including trailing slash. E.g. 'c:\\'. +if (isWindows) { + var splitRootRe = /^(?:[a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?[\\\/]*/; +} else { + var splitRootRe = /^[\/]*/; +} +exports.realpathSync = function realpathSync(p, cache) { + // make p is absolute + p = pathModule.resolve(p); -/***/ }), -/* 200 */ -/***/ (function(module, exports, __webpack_require__) { + if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { + return cache[p]; + } -var toInteger = __webpack_require__(73); -var max = Math.max; -var min = Math.min; -module.exports = function (index, length) { - index = toInteger(index); - return index < 0 ? max(index + length, 0) : min(index, length); -}; + var original = p, + seenLinks = {}, + knownHard = {}; + // current character position in p + var pos; + // the partial path so far, including a trailing slash if any + var current; + // the partial path without a trailing slash (except when pointing at a root) + var base; + // the partial path scanned in the previous round, with slash + var previous; -/***/ }), -/* 201 */ -/***/ (function(module, exports, __webpack_require__) { + start(); -// 7.1.1 ToPrimitive(input [, PreferredType]) -var isObject = __webpack_require__(34); -// instead of the ES6 spec version, we didn't implement @@toPrimitive case -// and the second argument - flag - preferred type is a string -module.exports = function (it, S) { - if (!isObject(it)) return it; - var fn, val; - if (S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val; - if (typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it))) return val; - if (!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val; - throw TypeError("Can't convert object to primitive value"); -}; + function start() { + // Skip over roots + var m = splitRootRe.exec(p); + pos = m[0].length; + current = m[0]; + base = m[0]; + previous = ''; + // On windows, check that the root exists. On unix there is no need. + if (isWindows && !knownHard[base]) { + fs.lstatSync(base); + knownHard[base] = true; + } + } -/***/ }), -/* 202 */ -/***/ (function(module, exports, __webpack_require__) { + // walk down the path, swapping out linked pathparts for their real + // values + // NB: p.length changes. + while (pos < p.length) { + // find the next part + nextPartRe.lastIndex = pos; + var result = nextPartRe.exec(p); + previous = current; + current += result[0]; + base = previous + result[1]; + pos = nextPartRe.lastIndex; -var global = __webpack_require__(11); -var navigator = global.navigator; + // continue if not a symlink + if (knownHard[base] || (cache && cache[base] === base)) { + continue; + } -module.exports = navigator && navigator.userAgent || ''; + var resolvedLink; + if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { + // some known symbolic link. no need to stat again. + resolvedLink = cache[base]; + } else { + var stat = fs.lstatSync(base); + if (!stat.isSymbolicLink()) { + knownHard[base] = true; + if (cache) cache[base] = base; + continue; + } + + // read the link if it wasn't read before + // dev/ino always return 0 on windows, so skip the check. + var linkTarget = null; + if (!isWindows) { + var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); + if (seenLinks.hasOwnProperty(id)) { + linkTarget = seenLinks[id]; + } + } + if (linkTarget === null) { + fs.statSync(base); + linkTarget = fs.readlinkSync(base); + } + resolvedLink = pathModule.resolve(previous, linkTarget); + // track this, if given a cache. + if (cache) cache[base] = resolvedLink; + if (!isWindows) seenLinks[id] = linkTarget; + } + // resolve the link, then start over + p = pathModule.resolve(resolvedLink, p.slice(pos)); + start(); + } -/***/ }), -/* 203 */ -/***/ (function(module, exports, __webpack_require__) { + if (cache) cache[original] = p; -var classof = __webpack_require__(100); -var ITERATOR = __webpack_require__(13)('iterator'); -var Iterators = __webpack_require__(35); -module.exports = __webpack_require__(23).getIteratorMethod = function (it) { - if (it != undefined) return it[ITERATOR] - || it['@@iterator'] - || Iterators[classof(it)]; + return p; }; -/***/ }), -/* 204 */ -/***/ (function(module, exports, __webpack_require__) { +exports.realpath = function realpath(p, cache, cb) { + if (typeof cb !== 'function') { + cb = maybeCallback(cache); + cache = null; + } -"use strict"; + // make p is absolute + p = pathModule.resolve(p); -var addToUnscopables = __webpack_require__(180); -var step = __webpack_require__(190); -var Iterators = __webpack_require__(35); -var toIObject = __webpack_require__(74); + if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { + return process.nextTick(cb.bind(null, null, cache[p])); + } -// 22.1.3.4 Array.prototype.entries() -// 22.1.3.13 Array.prototype.keys() -// 22.1.3.29 Array.prototype.values() -// 22.1.3.30 Array.prototype[@@iterator]() -module.exports = __webpack_require__(103)(Array, 'Array', function (iterated, kind) { - this._t = toIObject(iterated); // target - this._i = 0; // next index - this._k = kind; // kind -// 22.1.5.2.1 %ArrayIteratorPrototype%.next() -}, function () { - var O = this._t; - var kind = this._k; - var index = this._i++; - if (!O || index >= O.length) { - this._t = undefined; - return step(1); + var original = p, + seenLinks = {}, + knownHard = {}; + + // current character position in p + var pos; + // the partial path so far, including a trailing slash if any + var current; + // the partial path without a trailing slash (except when pointing at a root) + var base; + // the partial path scanned in the previous round, with slash + var previous; + + start(); + + function start() { + // Skip over roots + var m = splitRootRe.exec(p); + pos = m[0].length; + current = m[0]; + base = m[0]; + previous = ''; + + // On windows, check that the root exists. On unix there is no need. + if (isWindows && !knownHard[base]) { + fs.lstat(base, function(err) { + if (err) return cb(err); + knownHard[base] = true; + LOOP(); + }); + } else { + process.nextTick(LOOP); + } } - if (kind == 'keys') return step(0, index); - if (kind == 'values') return step(0, O[index]); - return step(0, [index, O[index]]); -}, 'values'); -// argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7) -Iterators.Arguments = Iterators.Array; + // walk down the path, swapping out linked pathparts for their real + // values + function LOOP() { + // stop if scanned past end of path + if (pos >= p.length) { + if (cache) cache[original] = p; + return cb(null, p); + } -addToUnscopables('keys'); -addToUnscopables('values'); -addToUnscopables('entries'); + // find the next part + nextPartRe.lastIndex = pos; + var result = nextPartRe.exec(p); + previous = current; + current += result[0]; + base = previous + result[1]; + pos = nextPartRe.lastIndex; + // continue if not a symlink + if (knownHard[base] || (cache && cache[base] === base)) { + return process.nextTick(LOOP); + } -/***/ }), -/* 205 */ -/***/ (function(module, exports) { + if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { + // known symbolic link. no need to stat again. + return gotResolvedLink(cache[base]); + } + + return fs.lstat(base, gotStat); + } + + function gotStat(err, stat) { + if (err) return cb(err); + + // if not a symlink, skip to the next path part + if (!stat.isSymbolicLink()) { + knownHard[base] = true; + if (cache) cache[base] = base; + return process.nextTick(LOOP); + } + + // stat & read the link if not read before + // call gotTarget as soon as the link target is known + // dev/ino always return 0 on windows, so skip the check. + if (!isWindows) { + var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); + if (seenLinks.hasOwnProperty(id)) { + return gotTarget(null, seenLinks[id], base); + } + } + fs.stat(base, function(err) { + if (err) return cb(err); + + fs.readlink(base, function(err, target) { + if (!isWindows) seenLinks[id] = target; + gotTarget(err, target); + }); + }); + } + + function gotTarget(err, target, base) { + if (err) return cb(err); + var resolvedLink = pathModule.resolve(previous, target); + if (cache) cache[base] = resolvedLink; + gotResolvedLink(resolvedLink); + } + + function gotResolvedLink(resolvedLink) { + // resolve the link, then start over + p = pathModule.resolve(resolvedLink, p.slice(pos)); + start(); + } +}; /***/ }), -/* 206 */ +/* 218 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; +module.exports = globSync +globSync.GlobSync = GlobSync -var LIBRARY = __webpack_require__(69); -var global = __webpack_require__(11); -var ctx = __webpack_require__(48); -var classof = __webpack_require__(100); -var $export = __webpack_require__(41); -var isObject = __webpack_require__(34); -var aFunction = __webpack_require__(46); -var anInstance = __webpack_require__(181); -var forOf = __webpack_require__(183); -var speciesConstructor = __webpack_require__(108); -var task = __webpack_require__(109).set; -var microtask = __webpack_require__(191)(); -var newPromiseCapabilityModule = __webpack_require__(70); -var perform = __webpack_require__(104); -var userAgent = __webpack_require__(202); -var promiseResolve = __webpack_require__(105); -var PROMISE = 'Promise'; -var TypeError = global.TypeError; -var process = global.process; -var versions = process && process.versions; -var v8 = versions && versions.v8 || ''; -var $Promise = global[PROMISE]; -var isNode = classof(process) == 'process'; -var empty = function () { /* empty */ }; -var Internal, newGenericPromiseCapability, OwnPromiseCapability, Wrapper; -var newPromiseCapability = newGenericPromiseCapability = newPromiseCapabilityModule.f; +var fs = __webpack_require__(3) +var rp = __webpack_require__(114) +var minimatch = __webpack_require__(60) +var Minimatch = minimatch.Minimatch +var Glob = __webpack_require__(75).Glob +var util = __webpack_require__(2) +var path = __webpack_require__(0) +var assert = __webpack_require__(22) +var isAbsolute = __webpack_require__(76) +var common = __webpack_require__(115) +var alphasort = common.alphasort +var alphasorti = common.alphasorti +var setopts = common.setopts +var ownProp = common.ownProp +var childrenIgnored = common.childrenIgnored +var isIgnored = common.isIgnored -var USE_NATIVE = !!function () { - try { - // correct subclassing with @@species support - var promise = $Promise.resolve(1); - var FakePromise = (promise.constructor = {})[__webpack_require__(13)('species')] = function (exec) { - exec(empty, empty); - }; - // unhandled rejections tracking support, NodeJS Promise without it fails @@species test - return (isNode || typeof PromiseRejectionEvent == 'function') - && promise.then(empty) instanceof FakePromise - // v8 6.6 (Node 10 and Chrome 66) have a bug with resolving custom thenables - // https://bugs.chromium.org/p/chromium/issues/detail?id=830565 - // we can't detect it synchronously, so just check versions - && v8.indexOf('6.6') !== 0 - && userAgent.indexOf('Chrome/66') === -1; - } catch (e) { /* empty */ } -}(); +function globSync (pattern, options) { + if (typeof options === 'function' || arguments.length === 3) + throw new TypeError('callback provided to sync glob\n'+ + 'See: https://github.com/isaacs/node-glob/issues/167') -// helpers -var isThenable = function (it) { - var then; - return isObject(it) && typeof (then = it.then) == 'function' ? then : false; -}; -var notify = function (promise, isReject) { - if (promise._n) return; - promise._n = true; - var chain = promise._c; - microtask(function () { - var value = promise._v; - var ok = promise._s == 1; - var i = 0; - var run = function (reaction) { - var handler = ok ? reaction.ok : reaction.fail; - var resolve = reaction.resolve; - var reject = reaction.reject; - var domain = reaction.domain; - var result, then, exited; - try { - if (handler) { - if (!ok) { - if (promise._h == 2) onHandleUnhandled(promise); - promise._h = 1; - } - if (handler === true) result = value; - else { - if (domain) domain.enter(); - result = handler(value); // may throw - if (domain) { - domain.exit(); - exited = true; - } - } - if (result === reaction.promise) { - reject(TypeError('Promise-chain cycle')); - } else if (then = isThenable(result)) { - then.call(result, resolve, reject); - } else resolve(result); - } else reject(value); - } catch (e) { - if (domain && !exited) domain.exit(); - reject(e); - } - }; - while (chain.length > i) run(chain[i++]); // variable length - can't use forEach - promise._c = []; - promise._n = false; - if (isReject && !promise._h) onUnhandled(promise); - }); -}; -var onUnhandled = function (promise) { - task.call(global, function () { - var value = promise._v; - var unhandled = isUnhandled(promise); - var result, handler, console; - if (unhandled) { - result = perform(function () { - if (isNode) { - process.emit('unhandledRejection', value, promise); - } else if (handler = global.onunhandledrejection) { - handler({ promise: promise, reason: value }); - } else if ((console = global.console) && console.error) { - console.error('Unhandled promise rejection', value); - } - }); - // Browsers should not trigger `rejectionHandled` event if it was handled here, NodeJS - should - promise._h = isNode || isUnhandled(promise) ? 2 : 1; - } promise._a = undefined; - if (unhandled && result.e) throw result.v; - }); -}; -var isUnhandled = function (promise) { - return promise._h !== 1 && (promise._a || promise._c).length === 0; -}; -var onHandleUnhandled = function (promise) { - task.call(global, function () { - var handler; - if (isNode) { - process.emit('rejectionHandled', promise); - } else if (handler = global.onrejectionhandled) { - handler({ promise: promise, reason: promise._v }); - } - }); -}; -var $reject = function (value) { - var promise = this; - if (promise._d) return; - promise._d = true; - promise = promise._w || promise; // unwrap - promise._v = value; - promise._s = 2; - if (!promise._a) promise._a = promise._c.slice(); - notify(promise, true); -}; -var $resolve = function (value) { - var promise = this; - var then; - if (promise._d) return; - promise._d = true; - promise = promise._w || promise; // unwrap - try { - if (promise === value) throw TypeError("Promise can't be resolved itself"); - if (then = isThenable(value)) { - microtask(function () { - var wrapper = { _w: promise, _d: false }; // wrap + return new GlobSync(pattern, options).found +} + +function GlobSync (pattern, options) { + if (!pattern) + throw new Error('must provide pattern') + + if (typeof options === 'function' || arguments.length === 3) + throw new TypeError('callback provided to sync glob\n'+ + 'See: https://github.com/isaacs/node-glob/issues/167') + + if (!(this instanceof GlobSync)) + return new GlobSync(pattern, options) + + setopts(this, pattern, options) + + if (this.noprocess) + return this + + var n = this.minimatch.set.length + this.matches = new Array(n) + for (var i = 0; i < n; i ++) { + this._process(this.minimatch.set[i], i, false) + } + this._finish() +} + +GlobSync.prototype._finish = function () { + assert(this instanceof GlobSync) + if (this.realpath) { + var self = this + this.matches.forEach(function (matchset, index) { + var set = self.matches[index] = Object.create(null) + for (var p in matchset) { try { - then.call(value, ctx($resolve, wrapper, 1), ctx($reject, wrapper, 1)); - } catch (e) { - $reject.call(wrapper, e); + p = self._makeAbs(p) + var real = rp.realpathSync(p, self.realpathCache) + set[real] = true + } catch (er) { + if (er.syscall === 'stat') + set[self._makeAbs(p)] = true + else + throw er } - }); - } else { - promise._v = value; - promise._s = 1; - notify(promise, false); - } - } catch (e) { - $reject.call({ _w: promise, _d: false }, e); // wrap + } + }) } -}; - -// constructor polyfill -if (!USE_NATIVE) { - // 25.4.3.1 Promise(executor) - $Promise = function Promise(executor) { - anInstance(this, $Promise, PROMISE, '_h'); - aFunction(executor); - Internal.call(this); - try { - executor(ctx($resolve, this, 1), ctx($reject, this, 1)); - } catch (err) { - $reject.call(this, err); - } - }; - // eslint-disable-next-line no-unused-vars - Internal = function Promise(executor) { - this._c = []; // <- awaiting reactions - this._a = undefined; // <- checked in isUnhandled reactions - this._s = 0; // <- state - this._d = false; // <- done - this._v = undefined; // <- value - this._h = 0; // <- rejection state, 0 - default, 1 - handled, 2 - unhandled - this._n = false; // <- notify - }; - Internal.prototype = __webpack_require__(196)($Promise.prototype, { - // 25.4.5.3 Promise.prototype.then(onFulfilled, onRejected) - then: function then(onFulfilled, onRejected) { - var reaction = newPromiseCapability(speciesConstructor(this, $Promise)); - reaction.ok = typeof onFulfilled == 'function' ? onFulfilled : true; - reaction.fail = typeof onRejected == 'function' && onRejected; - reaction.domain = isNode ? process.domain : undefined; - this._c.push(reaction); - if (this._a) this._a.push(reaction); - if (this._s) notify(this, false); - return reaction.promise; - }, - // 25.4.5.1 Promise.prototype.catch(onRejected) - 'catch': function (onRejected) { - return this.then(undefined, onRejected); - } - }); - OwnPromiseCapability = function () { - var promise = new Internal(); - this.promise = promise; - this.resolve = ctx($resolve, promise, 1); - this.reject = ctx($reject, promise, 1); - }; - newPromiseCapabilityModule.f = newPromiseCapability = function (C) { - return C === $Promise || C === Wrapper - ? new OwnPromiseCapability(C) - : newGenericPromiseCapability(C); - }; + common.finish(this) } -$export($export.G + $export.W + $export.F * !USE_NATIVE, { Promise: $Promise }); -__webpack_require__(71)($Promise, PROMISE); -__webpack_require__(198)(PROMISE); -Wrapper = __webpack_require__(23)[PROMISE]; -// statics -$export($export.S + $export.F * !USE_NATIVE, PROMISE, { - // 25.4.4.5 Promise.reject(r) - reject: function reject(r) { - var capability = newPromiseCapability(this); - var $$reject = capability.reject; - $$reject(r); - return capability.promise; - } -}); -$export($export.S + $export.F * (LIBRARY || !USE_NATIVE), PROMISE, { - // 25.4.4.6 Promise.resolve(x) - resolve: function resolve(x) { - return promiseResolve(LIBRARY && this === Wrapper ? $Promise : this, x); +GlobSync.prototype._process = function (pattern, index, inGlobStar) { + assert(this instanceof GlobSync) + + // Get the first [n] parts of pattern that are all strings. + var n = 0 + while (typeof pattern[n] === 'string') { + n ++ } -}); -$export($export.S + $export.F * !(USE_NATIVE && __webpack_require__(189)(function (iter) { - $Promise.all(iter)['catch'](empty); -})), PROMISE, { - // 25.4.4.1 Promise.all(iterable) - all: function all(iterable) { - var C = this; - var capability = newPromiseCapability(C); - var resolve = capability.resolve; - var reject = capability.reject; - var result = perform(function () { - var values = []; - var index = 0; - var remaining = 1; - forOf(iterable, false, function (promise) { - var $index = index++; - var alreadyCalled = false; - values.push(undefined); - remaining++; - C.resolve(promise).then(function (value) { - if (alreadyCalled) return; - alreadyCalled = true; - values[$index] = value; - --remaining || resolve(values); - }, reject); - }); - --remaining || resolve(values); - }); - if (result.e) reject(result.v); - return capability.promise; - }, - // 25.4.4.4 Promise.race(iterable) - race: function race(iterable) { - var C = this; - var capability = newPromiseCapability(C); - var reject = capability.reject; - var result = perform(function () { - forOf(iterable, false, function (promise) { - C.resolve(promise).then(capability.resolve, reject); - }); - }); - if (result.e) reject(result.v); - return capability.promise; + // now n is the index of the first one that is *not* a string. + + // See if there's anything else + var prefix + switch (n) { + // if not, then this is rather simple + case pattern.length: + this._processSimple(pattern.join('/'), index) + return + + case 0: + // pattern *starts* with some non-trivial item. + // going to readdir(cwd), but not include the prefix in matches. + prefix = null + break + + default: + // pattern has some string bits in the front. + // whatever it starts with, whether that's 'absolute' like /foo/bar, + // or 'relative' like '../baz' + prefix = pattern.slice(0, n).join('/') + break } -}); + var remain = pattern.slice(n) -/***/ }), -/* 207 */ -/***/ (function(module, exports, __webpack_require__) { + // get the list of entries. + var read + if (prefix === null) + read = '.' + else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { + if (!prefix || !isAbsolute(prefix)) + prefix = '/' + prefix + read = prefix + } else + read = prefix -"use strict"; + var abs = this._makeAbs(read) -var $at = __webpack_require__(199)(true); + //if ignored, skip processing + if (childrenIgnored(this, read)) + return -// 21.1.3.27 String.prototype[@@iterator]() -__webpack_require__(103)(String, 'String', function (iterated) { - this._t = String(iterated); // target - this._i = 0; // next index -// 21.1.5.2.1 %StringIteratorPrototype%.next() -}, function () { - var O = this._t; - var index = this._i; - var point; - if (index >= O.length) return { value: undefined, done: true }; - point = $at(O, index); - this._i += point.length; - return { value: point, done: false }; -}); + var isGlobStar = remain[0] === minimatch.GLOBSTAR + if (isGlobStar) + this._processGlobStar(prefix, read, abs, remain, index, inGlobStar) + else + this._processReaddir(prefix, read, abs, remain, index, inGlobStar) +} -/***/ }), -/* 208 */ -/***/ (function(module, exports, __webpack_require__) { +GlobSync.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar) { + var entries = this._readdir(abs, inGlobStar) -"use strict"; -// https://github.com/tc39/proposal-promise-finally + // if the abs isn't a dir, then nothing can match! + if (!entries) + return -var $export = __webpack_require__(41); -var core = __webpack_require__(23); -var global = __webpack_require__(11); -var speciesConstructor = __webpack_require__(108); -var promiseResolve = __webpack_require__(105); + // It will only match dot entries if it starts with a dot, or if + // dot is set. Stuff like @(.foo|.bar) isn't allowed. + var pn = remain[0] + var negate = !!this.minimatch.negate + var rawGlob = pn._glob + var dotOk = this.dot || rawGlob.charAt(0) === '.' -$export($export.P + $export.R, 'Promise', { 'finally': function (onFinally) { - var C = speciesConstructor(this, core.Promise || global.Promise); - var isFunction = typeof onFinally == 'function'; - return this.then( - isFunction ? function (x) { - return promiseResolve(C, onFinally()).then(function () { return x; }); - } : onFinally, - isFunction ? function (e) { - return promiseResolve(C, onFinally()).then(function () { throw e; }); - } : onFinally - ); -} }); + var matchedEntries = [] + for (var i = 0; i < entries.length; i++) { + var e = entries[i] + if (e.charAt(0) !== '.' || dotOk) { + var m + if (negate && !prefix) { + m = !e.match(pn) + } else { + m = e.match(pn) + } + if (m) + matchedEntries.push(e) + } + } + var len = matchedEntries.length + // If there are no matched entries, then nothing matches. + if (len === 0) + return -/***/ }), -/* 209 */ -/***/ (function(module, exports, __webpack_require__) { + // if this is the last remaining pattern bit, then no need for + // an additional stat *unless* the user has specified mark or + // stat explicitly. We know they exist, since readdir returned + // them. -"use strict"; + if (remain.length === 1 && !this.mark && !this.stat) { + if (!this.matches[index]) + this.matches[index] = Object.create(null) -// https://github.com/tc39/proposal-promise-try -var $export = __webpack_require__(41); -var newPromiseCapability = __webpack_require__(70); -var perform = __webpack_require__(104); + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + if (prefix) { + if (prefix.slice(-1) !== '/') + e = prefix + '/' + e + else + e = prefix + e + } -$export($export.S, 'Promise', { 'try': function (callbackfn) { - var promiseCapability = newPromiseCapability.f(this); - var result = perform(callbackfn); - (result.e ? promiseCapability.reject : promiseCapability.resolve)(result.v); - return promiseCapability.promise; -} }); + if (e.charAt(0) === '/' && !this.nomount) { + e = path.join(this.root, e) + } + this._emitMatch(index, e) + } + // This was the last one, and no stats were needed + return + } + // now test all matched entries as stand-ins for that part + // of the pattern. + remain.shift() + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + var newPattern + if (prefix) + newPattern = [prefix, e] + else + newPattern = [e] + this._process(newPattern.concat(remain), index, inGlobStar) + } +} -/***/ }), -/* 210 */ -/***/ (function(module, exports, __webpack_require__) { -__webpack_require__(204); -var global = __webpack_require__(11); -var hide = __webpack_require__(31); -var Iterators = __webpack_require__(35); -var TO_STRING_TAG = __webpack_require__(13)('toStringTag'); +GlobSync.prototype._emitMatch = function (index, e) { + if (isIgnored(this, e)) + return -var DOMIterables = ('CSSRuleList,CSSStyleDeclaration,CSSValueList,ClientRectList,DOMRectList,DOMStringList,' + - 'DOMTokenList,DataTransferItemList,FileList,HTMLAllCollection,HTMLCollection,HTMLFormElement,HTMLSelectElement,' + - 'MediaList,MimeTypeArray,NamedNodeMap,NodeList,PaintRequestList,Plugin,PluginArray,SVGLengthList,SVGNumberList,' + - 'SVGPathSegList,SVGPointList,SVGStringList,SVGTransformList,SourceBufferList,StyleSheetList,TextTrackCueList,' + - 'TextTrackList,TouchList').split(','); + var abs = this._makeAbs(e) -for (var i = 0; i < DOMIterables.length; i++) { - var NAME = DOMIterables[i]; - var Collection = global[NAME]; - var proto = Collection && Collection.prototype; - if (proto && !proto[TO_STRING_TAG]) hide(proto, TO_STRING_TAG, NAME); - Iterators[NAME] = Iterators.Array; -} + if (this.mark) + e = this._mark(e) + if (this.absolute) { + e = abs + } -/***/ }), -/* 211 */ -/***/ (function(module, exports, __webpack_require__) { + if (this.matches[index][e]) + return -/** - * This is the web browser implementation of `debug()`. - * - * Expose `debug()` as the module. - */ + if (this.nodir) { + var c = this.cache[abs] + if (c === 'DIR' || Array.isArray(c)) + return + } -exports = module.exports = __webpack_require__(112); -exports.log = log; -exports.formatArgs = formatArgs; -exports.save = save; -exports.load = load; -exports.useColors = useColors; -exports.storage = 'undefined' != typeof chrome - && 'undefined' != typeof chrome.storage - ? chrome.storage.local - : localstorage(); + this.matches[index][e] = true -/** - * Colors. - */ + if (this.stat) + this._stat(e) +} -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' -]; -/** - * Currently only WebKit-based Web Inspectors, Firefox >= v31, - * and the Firebug extension (any Firefox version) are known - * to support "%c" CSS customizations. - * - * TODO: add a `localStorage` variable to explicitly enable/disable colors - */ - -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') { - 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+)/)); -} - -/** - * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. - */ +GlobSync.prototype._readdirInGlobStar = function (abs) { + // follow all symlinked directories forever + // just proceed as if this is a non-globstar situation + if (this.follow) + return this._readdir(abs, false) -exports.formatters.j = function(v) { + var entries + var lstat + var stat try { - return JSON.stringify(v); - } catch (err) { - return '[UnexpectedJSONParseError]: ' + err.message; + lstat = fs.lstatSync(abs) + } catch (er) { + if (er.code === 'ENOENT') { + // lstat failed, doesn't exist + return null + } } -}; - - -/** - * Colorize log arguments if enabled. - * - * @api public - */ - -function formatArgs(args) { - var useColors = this.useColors; - - args[0] = (useColors ? '%c' : '') - + this.namespace - + (useColors ? ' %c' : ' ') - + args[0] - + (useColors ? '%c ' : ' ') - + '+' + exports.humanize(this.diff); - if (!useColors) return; - - var c = 'color: ' + this.color; - args.splice(1, 0, c, 'color: inherit') + var isSym = lstat && lstat.isSymbolicLink() + this.symlinks[abs] = isSym - // 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 - var index = 0; - var lastC = 0; - args[0].replace(/%[a-zA-Z%]/g, function(match) { - if ('%%' === match) return; - index++; - if ('%c' === match) { - // we only are interested in the *last* %c - // (the user may have provided their own) - lastC = index; - } - }); + // If it's not a symlink or a dir, then it's definitely a regular file. + // don't bother doing a readdir in that case. + if (!isSym && lstat && !lstat.isDirectory()) + this.cache[abs] = 'FILE' + else + entries = this._readdir(abs, false) - args.splice(lastC, 0, c); + return entries } -/** - * Invokes `console.log()` when available. - * No-op when `console.log` is not a "function". - * - * @api public - */ - -function log() { - // this hackery is required for IE8/9, where - // the `console.log` function doesn't have 'apply' - return 'object' === typeof console - && console.log - && Function.prototype.apply.call(console.log, console, arguments); -} +GlobSync.prototype._readdir = function (abs, inGlobStar) { + var entries -/** - * Save `namespaces`. - * - * @param {String} namespaces - * @api private - */ + if (inGlobStar && !ownProp(this.symlinks, abs)) + return this._readdirInGlobStar(abs) -function save(namespaces) { - try { - if (null == namespaces) { - exports.storage.removeItem('debug'); - } else { - exports.storage.debug = namespaces; - } - } catch(e) {} -} + if (ownProp(this.cache, abs)) { + var c = this.cache[abs] + if (!c || c === 'FILE') + return null -/** - * Load `namespaces`. - * - * @return {String} returns the previously persisted debug modes - * @api private - */ + if (Array.isArray(c)) + return c + } -function load() { - var r; try { - r = exports.storage.debug; - } catch(e) {} - - // 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 this._readdirEntries(abs, fs.readdirSync(abs)) + } catch (er) { + this._readdirError(abs, er) + return null } - - return r; } -/** - * Enable namespaces listed in `localStorage.debug` initially. - */ - -exports.enable(load()); +GlobSync.prototype._readdirEntries = function (abs, entries) { + // if we haven't asked to stat everything, then just + // assume that everything in there exists, so we can avoid + // having to stat it a second time. + if (!this.mark && !this.stat) { + for (var i = 0; i < entries.length; i ++) { + var e = entries[i] + if (abs === '/') + e = abs + e + else + e = abs + '/' + e + this.cache[e] = true + } + } -/** - * Localstorage attempts to return the localstorage. - * - * This is necessary because safari throws - * when a user disables cookies/localstorage - * and you attempt to access it. - * - * @return {LocalStorage} - * @api private - */ + this.cache[abs] = entries -function localstorage() { - try { - return window.localStorage; - } catch (e) {} + // mark and cache dir-ness + return entries } +GlobSync.prototype._readdirError = function (f, er) { + // handle errors, and cache the information + switch (er.code) { + case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 + case 'ENOTDIR': // totally normal. means it *does* exist. + var abs = this._makeAbs(f) + this.cache[abs] = 'FILE' + if (abs === this.cwdAbs) { + var error = new Error(er.code + ' invalid cwd ' + this.cwd) + error.path = this.cwd + error.code = er.code + throw error + } + break -/***/ }), -/* 212 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * Detect Electron renderer process, which is node, but we should - * treat as a browser. - */ + case 'ENOENT': // not terribly unusual + case 'ELOOP': + case 'ENAMETOOLONG': + case 'UNKNOWN': + this.cache[this._makeAbs(f)] = false + break -if (typeof process === 'undefined' || process.type === 'renderer') { - module.exports = __webpack_require__(211); -} else { - module.exports = __webpack_require__(213); + default: // some unusual error. Treat as failure. + this.cache[this._makeAbs(f)] = false + if (this.strict) + throw er + if (!this.silent) + console.error('glob error', er) + break + } } +GlobSync.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar) { -/***/ }), -/* 213 */ -/***/ (function(module, exports, __webpack_require__) { + var entries = this._readdir(abs, inGlobStar) -/** - * Module dependencies. - */ + // no entries means not a dir, so it can never have matches + // foo.txt/** doesn't match foo.txt + if (!entries) + return -var tty = __webpack_require__(79); -var util = __webpack_require__(2); + // test without the globstar, and with every child both below + // and replacing the globstar. + var remainWithoutGlobStar = remain.slice(1) + var gspref = prefix ? [ prefix ] : [] + var noGlobStar = gspref.concat(remainWithoutGlobStar) -/** - * This is the Node.js implementation of `debug()`. - * - * Expose `debug()` as the module. - */ + // the noGlobStar pattern exits the inGlobStar state + this._process(noGlobStar, index, false) -exports = module.exports = __webpack_require__(112); -exports.init = init; -exports.log = log; -exports.formatArgs = formatArgs; -exports.save = save; -exports.load = load; -exports.useColors = useColors; + var len = entries.length + var isSym = this.symlinks[abs] -/** - * Colors. - */ + // If it's a symlink, and we're in a globstar, then stop + if (isSym && inGlobStar) + return -exports.colors = [ 6, 2, 3, 4, 5, 1 ]; + for (var i = 0; i < len; i++) { + var e = entries[i] + if (e.charAt(0) === '.' && !this.dot) + continue -try { - var supportsColor = __webpack_require__(239); - if (supportsColor && 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 - ]; + // these two cases enter the inGlobStar state + var instead = gspref.concat(entries[i], remainWithoutGlobStar) + this._process(instead, index, true) + + var below = gspref.concat(entries[i], remain) + this._process(below, index, true) } -} catch (err) { - // swallow - we only care if `supports-color` is available; it doesn't have to be. } -/** - * Build up the default `inspectOpts` object from the environment variables. - * - * $ DEBUG_COLORS=no DEBUG_DEPTH=10 DEBUG_SHOW_HIDDEN=enabled node script.js - */ +GlobSync.prototype._processSimple = function (prefix, index) { + // XXX review this. Shouldn't it be doing the mounting etc + // before doing stat? kinda weird? + var exists = this._stat(prefix) -exports.inspectOpts = Object.keys(process.env).filter(function (key) { - return /^debug_/i.test(key); -}).reduce(function (obj, key) { - // camel-case - var prop = key - .substring(6) - .toLowerCase() - .replace(/_([a-z])/g, function (_, k) { return k.toUpperCase() }); + if (!this.matches[index]) + this.matches[index] = Object.create(null) - // coerce string value into JS value - var 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); + // If it doesn't exist, then just mark the lack of results + if (!exists) + return - obj[prop] = val; - return obj; -}, {}); + if (prefix && isAbsolute(prefix) && !this.nomount) { + var trail = /[\/\\]$/.test(prefix) + if (prefix.charAt(0) === '/') { + prefix = path.join(this.root, prefix) + } else { + prefix = path.resolve(this.root, prefix) + if (trail) + prefix += '/' + } + } -/** - * Is stdout a TTY? Colored output is enabled when `true`. - */ + if (process.platform === 'win32') + prefix = prefix.replace(/\\/g, '/') -function useColors() { - return 'colors' in exports.inspectOpts - ? Boolean(exports.inspectOpts.colors) - : tty.isatty(process.stderr.fd); + // Mark this as a match + this._emitMatch(index, prefix) } -/** - * Map %o to `util.inspect()`, all on a single line. - */ - -exports.formatters.o = function(v) { - this.inspectOpts.colors = this.useColors; - return util.inspect(v, this.inspectOpts) - .split('\n').map(function(str) { - return str.trim() - }).join(' '); -}; +// Returns either 'DIR', 'FILE', or false +GlobSync.prototype._stat = function (f) { + var abs = this._makeAbs(f) + var needDir = f.slice(-1) === '/' -/** - * Map %o to `util.inspect()`, allowing multiple lines if needed. - */ + if (f.length > this.maxLength) + return false -exports.formatters.O = function(v) { - this.inspectOpts.colors = this.useColors; - return util.inspect(v, this.inspectOpts); -}; + if (!this.stat && ownProp(this.cache, abs)) { + var c = this.cache[abs] -/** - * Adds ANSI color escape codes if enabled. - * - * @api public - */ + if (Array.isArray(c)) + c = 'DIR' -function formatArgs(args) { - var name = this.namespace; - var useColors = this.useColors; + // It exists, but maybe not how we need it + if (!needDir || c === 'DIR') + return c - if (useColors) { - var c = this.color; - var colorCode = '\u001b[3' + (c < 8 ? c : '8;5;' + c); - var prefix = ' ' + colorCode + ';1m' + name + ' ' + '\u001b[0m'; + if (needDir && c === 'FILE') + return false - args[0] = prefix + args[0].split('\n').join('\n' + prefix); - args.push(colorCode + 'm+' + exports.humanize(this.diff) + '\u001b[0m'); - } else { - args[0] = getDate() + name + ' ' + args[0]; + // otherwise we have to stat, because maybe c=true + // if we know it exists, but not what it is. } -} -function getDate() { - if (exports.inspectOpts.hideDate) { - return ''; - } else { - return new Date().toISOString() + ' '; + var exists + var stat = this.statCache[abs] + if (!stat) { + var lstat + try { + lstat = fs.lstatSync(abs) + } catch (er) { + if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) { + this.statCache[abs] = false + return false + } + } + + if (lstat && lstat.isSymbolicLink()) { + try { + stat = fs.statSync(abs) + } catch (er) { + stat = lstat + } + } else { + stat = lstat + } } -} -/** - * Invokes `util.format()` with the specified arguments and writes to stderr. - */ + this.statCache[abs] = stat -function log() { - return process.stderr.write(util.format.apply(util, arguments) + '\n'); -} + var c = true + if (stat) + c = stat.isDirectory() ? 'DIR' : 'FILE' -/** - * Save `namespaces`. - * - * @param {String} namespaces - * @api private - */ + this.cache[abs] = this.cache[abs] || c -function save(namespaces) { - if (null == namespaces) { - // 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; - } else { - process.env.DEBUG = namespaces; - } + if (needDir && c === 'FILE') + return false + + return c } -/** - * Load `namespaces`. - * - * @return {String} returns the previously persisted debug modes - * @api private - */ +GlobSync.prototype._mark = function (p) { + return common.mark(this, p) +} -function load() { - return process.env.DEBUG; +GlobSync.prototype._makeAbs = function (f) { + return common.makeAbs(this, f) } -/** - * Init logic for `debug` instances. - * - * Create a new `inspectOpts` object in case `useColors` is set - * differently for a particular `debug` instance. - */ -function init (debug) { - debug.inspectOpts = {}; +/***/ }), +/* 219 */, +/* 220 */, +/* 221 */ +/***/ (function(module, exports, __webpack_require__) { - var keys = Object.keys(exports.inspectOpts); - for (var i = 0; i < keys.length; i++) { - debug.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]]; - } -} +"use strict"; -/** - * Enable namespaces listed in `process.env.DEBUG` initially. - */ +module.exports = function (flag, argv) { + argv = argv || process.argv; -exports.enable(load()); + var terminatorPos = argv.indexOf('--'); + var prefix = /^--/.test(flag) ? '' : '--'; + var pos = argv.indexOf(prefix + flag); + + return pos !== -1 && (terminatorPos !== -1 ? pos < terminatorPos : true); +}; /***/ }), -/* 214 */, -/* 215 */, -/* 216 */, -/* 217 */ +/* 222 */, +/* 223 */ /***/ (function(module, exports, __webpack_require__) { -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER 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. - -var pathModule = __webpack_require__(0); -var isWindows = process.platform === 'win32'; -var fs = __webpack_require__(3); - -// JavaScript implementation of realpath, ported from node pre-v6 - -var DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG); - -function rethrow() { - // Only enable in debug mode. A backtrace uses ~1000 bytes of heap space and - // is fairly slow to generate. - var callback; - if (DEBUG) { - var backtrace = new Error; - callback = debugCallback; - } else - callback = missingCallback; +var wrappy = __webpack_require__(123) +var reqs = Object.create(null) +var once = __webpack_require__(61) - return callback; +module.exports = wrappy(inflight) - function debugCallback(err) { - if (err) { - backtrace.message = err.message; - err = backtrace; - missingCallback(err); - } +function inflight (key, cb) { + if (reqs[key]) { + reqs[key].push(cb) + return null + } else { + reqs[key] = [cb] + return makeres(key) } +} - function missingCallback(err) { - if (err) { - if (process.throwDeprecation) - throw err; // Forgot a callback but don't know where? Use NODE_DEBUG=fs - else if (!process.noDeprecation) { - var msg = 'fs: missing callback ' + (err.stack || err.message); - if (process.traceDeprecation) - console.trace(msg); - else - console.error(msg); +function makeres (key) { + return once(function RES () { + var cbs = reqs[key] + var len = cbs.length + var args = slice(arguments) + + // XXX It's somewhat ambiguous whether a new callback added in this + // pass should be queued for later execution if something in the + // list of callbacks throws, or if it should just be discarded. + // However, it's such an edge case that it hardly matters, and either + // choice is likely as surprising as the other. + // As it happens, we do go ahead and schedule it for later execution. + try { + for (var i = 0; i < len; i++) { + cbs[i].apply(null, args) + } + } finally { + if (cbs.length > len) { + // added more in the interim. + // de-zalgo, just in case, but don't call again. + cbs.splice(0, len) + process.nextTick(function () { + RES.apply(null, args) + }) + } else { + delete reqs[key] } } - } + }) } -function maybeCallback(cb) { - return typeof cb === 'function' ? cb : rethrow(); +function slice (args) { + var length = args.length + var array = [] + + for (var i = 0; i < length; i++) array[i] = args[i] + return array } -var normalize = pathModule.normalize; -// Regexp that finds the next partion of a (partial) path -// result is [base_with_slash, base], e.g. ['somedir/', 'somedir'] -if (isWindows) { - var nextPartRe = /(.*?)(?:[\/\\]+|$)/g; -} else { - var nextPartRe = /(.*?)(?:[\/]+|$)/g; -} +/***/ }), +/* 224 */ +/***/ (function(module, exports) { -// Regex to find the device root, including trailing slash. E.g. 'c:\\'. -if (isWindows) { - var splitRootRe = /^(?:[a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?[\\\/]*/; +if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); + }; } else { - var splitRootRe = /^[\/]*/; + // old school shim for old browsers + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + var TempCtor = function () {} + TempCtor.prototype = superCtor.prototype + ctor.prototype = new TempCtor() + ctor.prototype.constructor = ctor + } } -exports.realpathSync = function realpathSync(p, cache) { - // make p is absolute - p = pathModule.resolve(p); - - if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { - return cache[p]; - } - var original = p, - seenLinks = {}, - knownHard = {}; +/***/ }), +/* 225 */, +/* 226 */, +/* 227 */ +/***/ (function(module, exports, __webpack_require__) { - // current character position in p - var pos; - // the partial path so far, including a trailing slash if any - var current; - // the partial path without a trailing slash (except when pointing at a root) - var base; - // the partial path scanned in the previous round, with slash - var previous; +// @flow - start(); +/*:: +declare var __webpack_require__: mixed; +*/ - function start() { - // Skip over roots - var m = splitRootRe.exec(p); - pos = m[0].length; - current = m[0]; - base = m[0]; - previous = ''; +module.exports = typeof __webpack_require__ !== "undefined"; - // On windows, check that the root exists. On unix there is no need. - if (isWindows && !knownHard[base]) { - fs.lstatSync(base); - knownHard[base] = true; - } - } - // walk down the path, swapping out linked pathparts for their real - // values - // NB: p.length changes. - while (pos < p.length) { - // find the next part - nextPartRe.lastIndex = pos; - var result = nextPartRe.exec(p); - previous = current; - current += result[0]; - base = previous + result[1]; - pos = nextPartRe.lastIndex; +/***/ }), +/* 228 */, +/* 229 */ +/***/ (function(module, exports) { - // continue if not a symlink - if (knownHard[base] || (cache && cache[base] === base)) { - continue; - } +/** + * Helpers. + */ - var resolvedLink; - if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { - // some known symbolic link. no need to stat again. - resolvedLink = cache[base]; - } else { - var stat = fs.lstatSync(base); - if (!stat.isSymbolicLink()) { - knownHard[base] = true; - if (cache) cache[base] = base; - continue; - } +var s = 1000; +var m = s * 60; +var h = m * 60; +var d = h * 24; +var y = d * 365.25; - // read the link if it wasn't read before - // dev/ino always return 0 on windows, so skip the check. - var linkTarget = null; - if (!isWindows) { - var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); - if (seenLinks.hasOwnProperty(id)) { - linkTarget = seenLinks[id]; - } - } - if (linkTarget === null) { - fs.statSync(base); - linkTarget = fs.readlinkSync(base); - } - resolvedLink = pathModule.resolve(previous, linkTarget); - // track this, if given a cache. - if (cache) cache[base] = resolvedLink; - if (!isWindows) seenLinks[id] = linkTarget; - } +/** + * Parse or format the given `val`. + * + * Options: + * + * - `long` verbose formatting [false] + * + * @param {String|Number} val + * @param {Object} [options] + * @throws {Error} throw an error if val is not a non-empty string or a number + * @return {String|Number} + * @api public + */ - // resolve the link, then start over - p = pathModule.resolve(resolvedLink, p.slice(pos)); - start(); +module.exports = function(val, options) { + options = options || {}; + var type = typeof val; + if (type === 'string' && val.length > 0) { + return parse(val); + } else if (type === 'number' && isNaN(val) === false) { + return options.long ? fmtLong(val) : fmtShort(val); } - - if (cache) cache[original] = p; - - return p; + throw new Error( + 'val is not a non-empty string or a valid number. val=' + + JSON.stringify(val) + ); }; +/** + * Parse the given `str` and return milliseconds. + * + * @param {String} str + * @return {Number} + * @api private + */ -exports.realpath = function realpath(p, cache, cb) { - if (typeof cb !== 'function') { - cb = maybeCallback(cache); - cache = null; +function parse(str) { + str = String(str); + if (str.length > 100) { + return; + } + var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec( + str + ); + if (!match) { + return; + } + var n = parseFloat(match[1]); + var type = (match[2] || 'ms').toLowerCase(); + switch (type) { + case 'years': + case 'year': + case 'yrs': + case 'yr': + case 'y': + return n * y; + case 'days': + case 'day': + case 'd': + return n * d; + case 'hours': + case 'hour': + case 'hrs': + case 'hr': + case 'h': + return n * h; + case 'minutes': + case 'minute': + case 'mins': + case 'min': + case 'm': + return n * m; + case 'seconds': + case 'second': + case 'secs': + case 'sec': + case 's': + return n * s; + case 'milliseconds': + case 'millisecond': + case 'msecs': + case 'msec': + case 'ms': + return n; + default: + return undefined; } +} - // make p is absolute - p = pathModule.resolve(p); +/** + * Short format for `ms`. + * + * @param {Number} ms + * @return {String} + * @api private + */ - if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { - return process.nextTick(cb.bind(null, null, cache[p])); +function fmtShort(ms) { + if (ms >= d) { + return Math.round(ms / d) + 'd'; } + if (ms >= h) { + return Math.round(ms / h) + 'h'; + } + if (ms >= m) { + return Math.round(ms / m) + 'm'; + } + if (ms >= s) { + return Math.round(ms / s) + 's'; + } + return ms + 'ms'; +} - var original = p, - seenLinks = {}, - knownHard = {}; - - // current character position in p - var pos; - // the partial path so far, including a trailing slash if any - var current; - // the partial path without a trailing slash (except when pointing at a root) - var base; - // the partial path scanned in the previous round, with slash - var previous; +/** + * Long format for `ms`. + * + * @param {Number} ms + * @return {String} + * @api private + */ - start(); +function fmtLong(ms) { + return plural(ms, d, 'day') || + plural(ms, h, 'hour') || + plural(ms, m, 'minute') || + plural(ms, s, 'second') || + ms + ' ms'; +} - function start() { - // Skip over roots - var m = splitRootRe.exec(p); - pos = m[0].length; - current = m[0]; - base = m[0]; - previous = ''; +/** + * Pluralization helper. + */ - // On windows, check that the root exists. On unix there is no need. - if (isWindows && !knownHard[base]) { - fs.lstat(base, function(err) { - if (err) return cb(err); - knownHard[base] = true; - LOOP(); - }); - } else { - process.nextTick(LOOP); - } +function plural(ms, n, name) { + if (ms < n) { + return; } + if (ms < n * 1.5) { + return Math.floor(ms / n) + ' ' + name; + } + return Math.ceil(ms / n) + ' ' + name + 's'; +} - // walk down the path, swapping out linked pathparts for their real - // values - function LOOP() { - // stop if scanned past end of path - if (pos >= p.length) { - if (cache) cache[original] = p; - return cb(null, p); - } - // find the next part - nextPartRe.lastIndex = pos; - var result = nextPartRe.exec(p); - previous = current; - current += result[0]; - base = previous + result[1]; - pos = nextPartRe.lastIndex; +/***/ }), +/* 230 */, +/* 231 */, +/* 232 */, +/* 233 */ +/***/ (function(module, exports, __webpack_require__) { - // continue if not a symlink - if (knownHard[base] || (cache && cache[base] === base)) { - return process.nextTick(LOOP); - } +module.exports = rimraf +rimraf.sync = rimrafSync - if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { - // known symbolic link. no need to stat again. - return gotResolvedLink(cache[base]); - } +var assert = __webpack_require__(22) +var path = __webpack_require__(0) +var fs = __webpack_require__(3) +var glob = __webpack_require__(75) +var _0666 = parseInt('666', 8) - return fs.lstat(base, gotStat); - } +var defaultGlobOpts = { + nosort: true, + silent: true +} - function gotStat(err, stat) { - if (err) return cb(err); +// for EMFILE handling +var timeout = 0 - // if not a symlink, skip to the next path part - if (!stat.isSymbolicLink()) { - knownHard[base] = true; - if (cache) cache[base] = base; - return process.nextTick(LOOP); - } +var isWindows = (process.platform === "win32") - // stat & read the link if not read before - // call gotTarget as soon as the link target is known - // dev/ino always return 0 on windows, so skip the check. - if (!isWindows) { - var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); - if (seenLinks.hasOwnProperty(id)) { - return gotTarget(null, seenLinks[id], base); - } - } - fs.stat(base, function(err) { - if (err) return cb(err); +function defaults (options) { + var methods = [ + 'unlink', + 'chmod', + 'stat', + 'lstat', + 'rmdir', + 'readdir' + ] + methods.forEach(function(m) { + options[m] = options[m] || fs[m] + m = m + 'Sync' + options[m] = options[m] || fs[m] + }) - fs.readlink(base, function(err, target) { - if (!isWindows) seenLinks[id] = target; - gotTarget(err, target); - }); - }); + options.maxBusyTries = options.maxBusyTries || 3 + options.emfileWait = options.emfileWait || 1000 + if (options.glob === false) { + options.disableGlob = true } + options.disableGlob = options.disableGlob || false + options.glob = options.glob || defaultGlobOpts +} - function gotTarget(err, target, base) { - if (err) return cb(err); - - var resolvedLink = pathModule.resolve(previous, target); - if (cache) cache[base] = resolvedLink; - gotResolvedLink(resolvedLink); +function rimraf (p, options, cb) { + if (typeof options === 'function') { + cb = options + options = {} } - function gotResolvedLink(resolvedLink) { - // resolve the link, then start over - p = pathModule.resolve(resolvedLink, p.slice(pos)); - start(); - } -}; + assert(p, 'rimraf: missing path') + assert.equal(typeof p, 'string', 'rimraf: path should be a string') + assert.equal(typeof cb, 'function', 'rimraf: callback function required') + assert(options, 'rimraf: invalid options argument provided') + assert.equal(typeof options, 'object', 'rimraf: options should be object') + defaults(options) -/***/ }), -/* 218 */ -/***/ (function(module, exports, __webpack_require__) { + var busyTries = 0 + var errState = null + var n = 0 -module.exports = globSync -globSync.GlobSync = GlobSync + if (options.disableGlob || !glob.hasMagic(p)) + return afterGlob(null, [p]) -var fs = __webpack_require__(3) -var rp = __webpack_require__(114) -var minimatch = __webpack_require__(60) -var Minimatch = minimatch.Minimatch -var Glob = __webpack_require__(75).Glob -var util = __webpack_require__(2) -var path = __webpack_require__(0) -var assert = __webpack_require__(22) -var isAbsolute = __webpack_require__(76) -var common = __webpack_require__(115) -var alphasort = common.alphasort -var alphasorti = common.alphasorti -var setopts = common.setopts -var ownProp = common.ownProp -var childrenIgnored = common.childrenIgnored -var isIgnored = common.isIgnored + options.lstat(p, function (er, stat) { + if (!er) + return afterGlob(null, [p]) -function globSync (pattern, options) { - if (typeof options === 'function' || arguments.length === 3) - throw new TypeError('callback provided to sync glob\n'+ - 'See: https://github.com/isaacs/node-glob/issues/167') + glob(p, options.glob, afterGlob) + }) - return new GlobSync(pattern, options).found -} + function next (er) { + errState = errState || er + if (--n === 0) + cb(errState) + } -function GlobSync (pattern, options) { - if (!pattern) - throw new Error('must provide pattern') + function afterGlob (er, results) { + if (er) + return cb(er) - if (typeof options === 'function' || arguments.length === 3) - throw new TypeError('callback provided to sync glob\n'+ - 'See: https://github.com/isaacs/node-glob/issues/167') + n = results.length + if (n === 0) + return cb() - if (!(this instanceof GlobSync)) - return new GlobSync(pattern, options) + results.forEach(function (p) { + rimraf_(p, options, function CB (er) { + if (er) { + if ((er.code === "EBUSY" || er.code === "ENOTEMPTY" || er.code === "EPERM") && + busyTries < options.maxBusyTries) { + busyTries ++ + var time = busyTries * 100 + // try again, with the same exact callback as this one. + return setTimeout(function () { + rimraf_(p, options, CB) + }, time) + } - setopts(this, pattern, options) + // this one won't happen if graceful-fs is used. + if (er.code === "EMFILE" && timeout < options.emfileWait) { + return setTimeout(function () { + rimraf_(p, options, CB) + }, timeout ++) + } - if (this.noprocess) - return this + // already gone + if (er.code === "ENOENT") er = null + } - var n = this.minimatch.set.length - this.matches = new Array(n) - for (var i = 0; i < n; i ++) { - this._process(this.minimatch.set[i], i, false) + timeout = 0 + next(er) + }) + }) } - this._finish() } -GlobSync.prototype._finish = function () { - assert(this instanceof GlobSync) - if (this.realpath) { - var self = this - this.matches.forEach(function (matchset, index) { - var set = self.matches[index] = Object.create(null) - for (var p in matchset) { - try { - p = self._makeAbs(p) - var real = rp.realpathSync(p, self.realpathCache) - set[real] = true - } catch (er) { - if (er.syscall === 'stat') - set[self._makeAbs(p)] = true - else - throw er - } +// Two possible strategies. +// 1. Assume it's a file. unlink it, then do the dir stuff on EPERM or EISDIR +// 2. Assume it's a directory. readdir, then do the file stuff on ENOTDIR +// +// Both result in an extra syscall when you guess wrong. However, there +// are likely far more normal files in the world than directories. This +// is based on the assumption that a the average number of files per +// directory is >= 1. +// +// If anyone ever complains about this, then I guess the strategy could +// be made configurable somehow. But until then, YAGNI. +function rimraf_ (p, options, cb) { + assert(p) + assert(options) + assert(typeof cb === 'function') + + // sunos lets the root user unlink directories, which is... weird. + // so we have to lstat here and make sure it's not a dir. + options.lstat(p, function (er, st) { + if (er && er.code === "ENOENT") + return cb(null) + + // Windows can EPERM on stat. Life is suffering. + if (er && er.code === "EPERM" && isWindows) + fixWinEPERM(p, options, er, cb) + + if (st && st.isDirectory()) + return rmdir(p, options, er, cb) + + options.unlink(p, function (er) { + if (er) { + if (er.code === "ENOENT") + return cb(null) + if (er.code === "EPERM") + return (isWindows) + ? fixWinEPERM(p, options, er, cb) + : rmdir(p, options, er, cb) + if (er.code === "EISDIR") + return rmdir(p, options, er, cb) } + return cb(er) }) - } - common.finish(this) + }) } +function fixWinEPERM (p, options, er, cb) { + assert(p) + assert(options) + assert(typeof cb === 'function') + if (er) + assert(er instanceof Error) -GlobSync.prototype._process = function (pattern, index, inGlobStar) { - assert(this instanceof GlobSync) + options.chmod(p, _0666, function (er2) { + if (er2) + cb(er2.code === "ENOENT" ? null : er) + else + options.stat(p, function(er3, stats) { + if (er3) + cb(er3.code === "ENOENT" ? null : er) + else if (stats.isDirectory()) + rmdir(p, options, er, cb) + else + options.unlink(p, cb) + }) + }) +} - // Get the first [n] parts of pattern that are all strings. - var n = 0 - while (typeof pattern[n] === 'string') { - n ++ - } - // now n is the index of the first one that is *not* a string. +function fixWinEPERMSync (p, options, er) { + assert(p) + assert(options) + if (er) + assert(er instanceof Error) - // See if there's anything else - var prefix - switch (n) { - // if not, then this is rather simple - case pattern.length: - this._processSimple(pattern.join('/'), index) + try { + options.chmodSync(p, _0666) + } catch (er2) { + if (er2.code === "ENOENT") return + else + throw er + } - case 0: - // pattern *starts* with some non-trivial item. - // going to readdir(cwd), but not include the prefix in matches. - prefix = null - break - - default: - // pattern has some string bits in the front. - // whatever it starts with, whether that's 'absolute' like /foo/bar, - // or 'relative' like '../baz' - prefix = pattern.slice(0, n).join('/') - break + try { + var stats = options.statSync(p) + } catch (er3) { + if (er3.code === "ENOENT") + return + else + throw er } - var remain = pattern.slice(n) + if (stats.isDirectory()) + rmdirSync(p, options, er) + else + options.unlinkSync(p) +} - // get the list of entries. - var read - if (prefix === null) - read = '.' - else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { - if (!prefix || !isAbsolute(prefix)) - prefix = '/' + prefix - read = prefix - } else - read = prefix +function rmdir (p, options, originalEr, cb) { + assert(p) + assert(options) + if (originalEr) + assert(originalEr instanceof Error) + assert(typeof cb === 'function') - var abs = this._makeAbs(read) + // try to rmdir first, and only readdir on ENOTEMPTY or EEXIST (SunOS) + // if we guessed wrong, and it's not a directory, then + // raise the original error. + options.rmdir(p, function (er) { + if (er && (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM")) + rmkids(p, options, cb) + else if (er && er.code === "ENOTDIR") + cb(originalEr) + else + cb(er) + }) +} - //if ignored, skip processing - if (childrenIgnored(this, read)) - return +function rmkids(p, options, cb) { + assert(p) + assert(options) + assert(typeof cb === 'function') - var isGlobStar = remain[0] === minimatch.GLOBSTAR - if (isGlobStar) - this._processGlobStar(prefix, read, abs, remain, index, inGlobStar) - else - this._processReaddir(prefix, read, abs, remain, index, inGlobStar) + options.readdir(p, function (er, files) { + if (er) + return cb(er) + var n = files.length + if (n === 0) + return options.rmdir(p, cb) + var errState + files.forEach(function (f) { + rimraf(path.join(p, f), options, function (er) { + if (errState) + return + if (er) + return cb(errState = er) + if (--n === 0) + options.rmdir(p, cb) + }) + }) + }) } +// this looks simpler, and is strictly *faster*, but will +// tie up the JavaScript thread and fail on excessively +// deep directory trees. +function rimrafSync (p, options) { + options = options || {} + defaults(options) -GlobSync.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar) { - var entries = this._readdir(abs, inGlobStar) - - // if the abs isn't a dir, then nothing can match! - if (!entries) - return + assert(p, 'rimraf: missing path') + assert.equal(typeof p, 'string', 'rimraf: path should be a string') + assert(options, 'rimraf: missing options') + assert.equal(typeof options, 'object', 'rimraf: options should be object') - // It will only match dot entries if it starts with a dot, or if - // dot is set. Stuff like @(.foo|.bar) isn't allowed. - var pn = remain[0] - var negate = !!this.minimatch.negate - var rawGlob = pn._glob - var dotOk = this.dot || rawGlob.charAt(0) === '.' + var results - var matchedEntries = [] - for (var i = 0; i < entries.length; i++) { - var e = entries[i] - if (e.charAt(0) !== '.' || dotOk) { - var m - if (negate && !prefix) { - m = !e.match(pn) - } else { - m = e.match(pn) - } - if (m) - matchedEntries.push(e) + if (options.disableGlob || !glob.hasMagic(p)) { + results = [p] + } else { + try { + options.lstatSync(p) + results = [p] + } catch (er) { + results = glob.sync(p, options.glob) } } - var len = matchedEntries.length - // If there are no matched entries, then nothing matches. - if (len === 0) + if (!results.length) return - // if this is the last remaining pattern bit, then no need for - // an additional stat *unless* the user has specified mark or - // stat explicitly. We know they exist, since readdir returned - // them. - - if (remain.length === 1 && !this.mark && !this.stat) { - if (!this.matches[index]) - this.matches[index] = Object.create(null) + for (var i = 0; i < results.length; i++) { + var p = results[i] - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - if (prefix) { - if (prefix.slice(-1) !== '/') - e = prefix + '/' + e - else - e = prefix + e - } + try { + var st = options.lstatSync(p) + } catch (er) { + if (er.code === "ENOENT") + return - if (e.charAt(0) === '/' && !this.nomount) { - e = path.join(this.root, e) - } - this._emitMatch(index, e) + // Windows can EPERM on stat. Life is suffering. + if (er.code === "EPERM" && isWindows) + fixWinEPERMSync(p, options, er) } - // This was the last one, and no stats were needed - return - } - - // now test all matched entries as stand-ins for that part - // of the pattern. - remain.shift() - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - var newPattern - if (prefix) - newPattern = [prefix, e] - else - newPattern = [e] - this._process(newPattern.concat(remain), index, inGlobStar) - } -} - - -GlobSync.prototype._emitMatch = function (index, e) { - if (isIgnored(this, e)) - return - - var abs = this._makeAbs(e) - if (this.mark) - e = this._mark(e) + try { + // sunos lets the root user unlink directories, which is... weird. + if (st && st.isDirectory()) + rmdirSync(p, options, null) + else + options.unlinkSync(p) + } catch (er) { + if (er.code === "ENOENT") + return + if (er.code === "EPERM") + return isWindows ? fixWinEPERMSync(p, options, er) : rmdirSync(p, options, er) + if (er.code !== "EISDIR") + throw er - if (this.absolute) { - e = abs + rmdirSync(p, options, er) + } } +} - if (this.matches[index][e]) - return +function rmdirSync (p, options, originalEr) { + assert(p) + assert(options) + if (originalEr) + assert(originalEr instanceof Error) - if (this.nodir) { - var c = this.cache[abs] - if (c === 'DIR' || Array.isArray(c)) + try { + options.rmdirSync(p) + } catch (er) { + if (er.code === "ENOENT") return + if (er.code === "ENOTDIR") + throw originalEr + if (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM") + rmkidsSync(p, options) } - - this.matches[index][e] = true - - if (this.stat) - this._stat(e) } +function rmkidsSync (p, options) { + assert(p) + assert(options) + options.readdirSync(p).forEach(function (f) { + rimrafSync(path.join(p, f), options) + }) -GlobSync.prototype._readdirInGlobStar = function (abs) { - // follow all symlinked directories forever - // just proceed as if this is a non-globstar situation - if (this.follow) - return this._readdir(abs, false) - - var entries - var lstat - var stat - try { - lstat = fs.lstatSync(abs) - } catch (er) { - if (er.code === 'ENOENT') { - // lstat failed, doesn't exist - return null + // We only end up here once we got ENOTEMPTY at least once, and + // at this point, we are guaranteed to have removed all the kids. + // So, we know that it won't be ENOENT or ENOTDIR or anything else. + // try really hard to delete stuff on windows, because it has a + // PROFOUNDLY annoying habit of not closing handles promptly when + // files are deleted, resulting in spurious ENOTEMPTY errors. + var retries = isWindows ? 100 : 1 + var i = 0 + do { + var threw = true + try { + var ret = options.rmdirSync(p, options) + threw = false + return ret + } finally { + if (++i < retries && threw) + continue } - } + } while (true) +} - var isSym = lstat && lstat.isSymbolicLink() - this.symlinks[abs] = isSym - // If it's not a symlink or a dir, then it's definitely a regular file. - // don't bother doing a readdir in that case. - if (!isSym && lstat && !lstat.isDirectory()) - this.cache[abs] = 'FILE' - else - entries = this._readdir(abs, false) +/***/ }), +/* 234 */, +/* 235 */, +/* 236 */, +/* 237 */, +/* 238 */, +/* 239 */ +/***/ (function(module, exports, __webpack_require__) { - return entries -} +"use strict"; -GlobSync.prototype._readdir = function (abs, inGlobStar) { - var entries +var hasFlag = __webpack_require__(221); - if (inGlobStar && !ownProp(this.symlinks, abs)) - return this._readdirInGlobStar(abs) +var support = function (level) { + if (level === 0) { + return false; + } - if (ownProp(this.cache, abs)) { - var c = this.cache[abs] - if (!c || c === 'FILE') - return null + return { + level: level, + hasBasic: true, + has256: level >= 2, + has16m: level >= 3 + }; +}; - if (Array.isArray(c)) - return c - } +var supportLevel = (function () { + if (hasFlag('no-color') || + hasFlag('no-colors') || + hasFlag('color=false')) { + return 0; + } - try { - return this._readdirEntries(abs, fs.readdirSync(abs)) - } catch (er) { - this._readdirError(abs, er) - return null - } -} + if (hasFlag('color=16m') || + hasFlag('color=full') || + hasFlag('color=truecolor')) { + return 3; + } -GlobSync.prototype._readdirEntries = function (abs, entries) { - // if we haven't asked to stat everything, then just - // assume that everything in there exists, so we can avoid - // having to stat it a second time. - if (!this.mark && !this.stat) { - for (var i = 0; i < entries.length; i ++) { - var e = entries[i] - if (abs === '/') - e = abs + e - else - e = abs + '/' + e - this.cache[e] = true - } - } + if (hasFlag('color=256')) { + return 2; + } - this.cache[abs] = entries + if (hasFlag('color') || + hasFlag('colors') || + hasFlag('color=true') || + hasFlag('color=always')) { + return 1; + } - // mark and cache dir-ness - return entries -} + if (process.stdout && !process.stdout.isTTY) { + return 0; + } -GlobSync.prototype._readdirError = function (f, er) { - // handle errors, and cache the information - switch (er.code) { - case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 - case 'ENOTDIR': // totally normal. means it *does* exist. - var abs = this._makeAbs(f) - this.cache[abs] = 'FILE' - if (abs === this.cwdAbs) { - var error = new Error(er.code + ' invalid cwd ' + this.cwd) - error.path = this.cwd - error.code = er.code - throw error - } - break + if (process.platform === 'win32') { + return 1; + } - case 'ENOENT': // not terribly unusual - case 'ELOOP': - case 'ENAMETOOLONG': - case 'UNKNOWN': - this.cache[this._makeAbs(f)] = false - break + if ('CI' in process.env) { + if ('TRAVIS' in process.env || process.env.CI === 'Travis') { + return 1; + } - default: // some unusual error. Treat as failure. - this.cache[this._makeAbs(f)] = false - if (this.strict) - throw er - if (!this.silent) - console.error('glob error', er) - break - } -} + return 0; + } -GlobSync.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar) { + if ('TEAMCITY_VERSION' in process.env) { + return process.env.TEAMCITY_VERSION.match(/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/) === null ? 0 : 1; + } - var entries = this._readdir(abs, inGlobStar) + if (/^(screen|xterm)-256(?:color)?/.test(process.env.TERM)) { + return 2; + } - // no entries means not a dir, so it can never have matches - // foo.txt/** doesn't match foo.txt - if (!entries) - return + if (/^screen|^xterm|^vt100|color|ansi|cygwin|linux/i.test(process.env.TERM)) { + return 1; + } - // test without the globstar, and with every child both below - // and replacing the globstar. - var remainWithoutGlobStar = remain.slice(1) - var gspref = prefix ? [ prefix ] : [] - var noGlobStar = gspref.concat(remainWithoutGlobStar) + if ('COLORTERM' in process.env) { + return 1; + } - // the noGlobStar pattern exits the inGlobStar state - this._process(noGlobStar, index, false) + if (process.env.TERM === 'dumb') { + return 0; + } - var len = entries.length - var isSym = this.symlinks[abs] + return 0; +})(); - // If it's a symlink, and we're in a globstar, then stop - if (isSym && inGlobStar) - return +if (supportLevel === 0 && 'FORCE_COLOR' in process.env) { + supportLevel = 1; +} - for (var i = 0; i < len; i++) { - var e = entries[i] - if (e.charAt(0) === '.' && !this.dot) - continue +module.exports = process && support(supportLevel); - // these two cases enter the inGlobStar state - var instead = gspref.concat(entries[i], remainWithoutGlobStar) - this._process(instead, index, true) - var below = gspref.concat(entries[i], remain) - this._process(below, index, true) - } -} +/***/ }) +/******/ ]); -GlobSync.prototype._processSimple = function (prefix, index) { - // XXX review this. Shouldn't it be doing the mounting etc - // before doing stat? kinda weird? - var exists = this._stat(prefix) +/***/ }), +/* 285 */ +/***/ (function(module, exports) { - if (!this.matches[index]) - this.matches[index] = Object.create(null) +module.exports = require("buffer"); - // If it doesn't exist, then just mark the lack of results - if (!exists) - return +/***/ }), +/* 286 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { - if (prefix && isAbsolute(prefix) && !this.nomount) { - var trail = /[\/\\]$/.test(prefix) - if (prefix.charAt(0) === '/') { - prefix = path.join(this.root, prefix) - } else { - prefix = path.resolve(this.root, prefix) - if (trail) - prefix += '/' - } - } +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BootstrapCacheFile", function() { return BootstrapCacheFile; }); +/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(133); +/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(fs__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_1__); +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - if (process.platform === 'win32') - prefix = prefix.replace(/\\/g, '/') +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ - // Mark this as a match - this._emitMatch(index, prefix) -} -// Returns either 'DIR', 'FILE', or false -GlobSync.prototype._stat = function (f) { - var abs = this._makeAbs(f) - var needDir = f.slice(-1) === '/' +class BootstrapCacheFile { + constructor(kbn, project, checksums) { + _defineProperty(this, "path", void 0); - if (f.length > this.maxLength) - return false + _defineProperty(this, "expectedValue", void 0); - if (!this.stat && ownProp(this.cache, abs)) { - var c = this.cache[abs] + this.path = path__WEBPACK_IMPORTED_MODULE_1___default.a.resolve(project.targetLocation, '.bootstrap-cache'); - if (Array.isArray(c)) - c = 'DIR' + if (!checksums) { + return; + } - // It exists, but maybe not how we need it - if (!needDir || c === 'DIR') - return c + const projectAndDepCacheKeys = Array.from(kbn.getProjectAndDeps(project.name).values()) // sort deps by name so that the key is stable + .sort((a, b) => a.name.localeCompare(b.name)) // get the cacheKey for each project, return undefined if the cache key couldn't be determined + .map(p => { + const cacheKey = checksums.get(p.name); - if (needDir && c === 'FILE') - return false + if (cacheKey) { + return `${p.name}:${cacheKey}`; + } + }); // if any of the relevant cache keys are undefined then the projectCacheKey must be too - // otherwise we have to stat, because maybe c=true - // if we know it exists, but not what it is. + this.expectedValue = projectAndDepCacheKeys.some(k => !k) ? undefined : [`# this is only human readable for debugging, please don't try to parse this`, ...projectAndDepCacheKeys].join('\n'); } - var exists - var stat = this.statCache[abs] - if (!stat) { - var lstat + isValid() { + if (!this.expectedValue) { + return false; + } + try { - lstat = fs.lstatSync(abs) - } catch (er) { - if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) { - this.statCache[abs] = false - return false + return fs__WEBPACK_IMPORTED_MODULE_0___default.a.readFileSync(this.path, 'utf8') === this.expectedValue; + } catch (error) { + if (error.code === 'ENOENT') { + return false; } + + throw error; } + } - if (lstat && lstat.isSymbolicLink()) { - try { - stat = fs.statSync(abs) - } catch (er) { - stat = lstat + delete() { + try { + fs__WEBPACK_IMPORTED_MODULE_0___default.a.unlinkSync(this.path); + } catch (error) { + if (error.code !== 'ENOENT') { + throw error; } - } else { - stat = lstat } } - this.statCache[abs] = stat - - var c = true - if (stat) - c = stat.isDirectory() ? 'DIR' : 'FILE' - - this.cache[abs] = this.cache[abs] || c - - if (needDir && c === 'FILE') - return false - - return c -} + write() { + if (!this.expectedValue) { + return; + } -GlobSync.prototype._mark = function (p) { - return common.mark(this, p) -} + fs__WEBPACK_IMPORTED_MODULE_0___default.a.mkdirSync(path__WEBPACK_IMPORTED_MODULE_1___default.a.dirname(this.path), { + recursive: true + }); + fs__WEBPACK_IMPORTED_MODULE_0___default.a.writeFileSync(this.path, this.expectedValue); + } -GlobSync.prototype._makeAbs = function (f) { - return common.makeAbs(this, f) } - /***/ }), -/* 219 */, -/* 220 */, -/* 221 */ -/***/ (function(module, exports, __webpack_require__) { +/* 287 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CleanCommand", function() { return CleanCommand; }); +/* harmony import */ var del__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(288); +/* harmony import */ var del__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(del__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var ora__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(375); +/* harmony import */ var ora__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(ora__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var _utils_fs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(130); +/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(143); +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ -module.exports = function (flag, argv) { - argv = argv || process.argv; - var terminatorPos = argv.indexOf('--'); - var prefix = /^--/.test(flag) ? '' : '--'; - var pos = argv.indexOf(prefix + flag); - return pos !== -1 && (terminatorPos !== -1 ? pos < terminatorPos : true); -}; -/***/ }), -/* 222 */, -/* 223 */ -/***/ (function(module, exports, __webpack_require__) { +const CleanCommand = { + description: 'Remove the node_modules and target directories from all projects.', + name: 'clean', -var wrappy = __webpack_require__(123) -var reqs = Object.create(null) -var once = __webpack_require__(61) + async run(projects) { + const toDelete = []; -module.exports = wrappy(inflight) + for (const project of projects.values()) { + if (await Object(_utils_fs__WEBPACK_IMPORTED_MODULE_3__["isDirectory"])(project.nodeModulesLocation)) { + toDelete.push({ + cwd: project.path, + pattern: Object(path__WEBPACK_IMPORTED_MODULE_2__["relative"])(project.path, project.nodeModulesLocation) + }); + } -function inflight (key, cb) { - if (reqs[key]) { - reqs[key].push(cb) - return null - } else { - reqs[key] = [cb] - return makeres(key) - } -} + if (await Object(_utils_fs__WEBPACK_IMPORTED_MODULE_3__["isDirectory"])(project.targetLocation)) { + toDelete.push({ + cwd: project.path, + pattern: Object(path__WEBPACK_IMPORTED_MODULE_2__["relative"])(project.path, project.targetLocation) + }); + } -function makeres (key) { - return once(function RES () { - var cbs = reqs[key] - var len = cbs.length - var args = slice(arguments) + const { + extraPatterns + } = project.getCleanConfig(); - // XXX It's somewhat ambiguous whether a new callback added in this - // pass should be queued for later execution if something in the - // list of callbacks throws, or if it should just be discarded. - // However, it's such an edge case that it hardly matters, and either - // choice is likely as surprising as the other. - // As it happens, we do go ahead and schedule it for later execution. - try { - for (var i = 0; i < len; i++) { - cbs[i].apply(null, args) - } - } finally { - if (cbs.length > len) { - // added more in the interim. - // de-zalgo, just in case, but don't call again. - cbs.splice(0, len) - process.nextTick(function () { - RES.apply(null, args) - }) - } else { - delete reqs[key] + if (extraPatterns) { + toDelete.push({ + cwd: project.path, + pattern: extraPatterns + }); } } - }) -} - -function slice (args) { - var length = args.length - var array = [] - for (var i = 0; i < length; i++) array[i] = args[i] - return array -} + if (toDelete.length === 0) { + _utils_log__WEBPACK_IMPORTED_MODULE_4__["log"].success('Nothing to delete'); + } else { + /** + * In order to avoid patterns like `/build` in packages from accidentally + * impacting files outside the package we use `process.chdir()` to change + * the cwd to the package and execute `del()` without the `force` option + * so it will check that each file being deleted is within the package. + * + * `del()` does support a `cwd` option, but it's only for resolving the + * patterns and does not impact the cwd check. + */ + const originalCwd = process.cwd(); + try { + for (const { + pattern, + cwd + } of toDelete) { + process.chdir(cwd); + const promise = del__WEBPACK_IMPORTED_MODULE_0___default()(pattern); -/***/ }), -/* 224 */ -/***/ (function(module, exports) { + if (_utils_log__WEBPACK_IMPORTED_MODULE_4__["log"].wouldLogLevel('info')) { + ora__WEBPACK_IMPORTED_MODULE_1___default.a.promise(promise, Object(path__WEBPACK_IMPORTED_MODULE_2__["relative"])(originalCwd, Object(path__WEBPACK_IMPORTED_MODULE_2__["join"])(cwd, String(pattern)))); + } -if (typeof Object.create === 'function') { - // implementation from standard node.js 'util' module - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - ctor.prototype = Object.create(superCtor.prototype, { - constructor: { - value: ctor, - enumerable: false, - writable: true, - configurable: true + await promise; + } + } finally { + process.chdir(originalCwd); } - }); - }; -} else { - // old school shim for old browsers - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - var TempCtor = function () {} - TempCtor.prototype = superCtor.prototype - ctor.prototype = new TempCtor() - ctor.prototype.constructor = ctor + } } -} +}; /***/ }), -/* 225 */, -/* 226 */, -/* 227 */ +/* 288 */ /***/ (function(module, exports, __webpack_require__) { -// @flow +"use strict"; -/*:: -declare var __webpack_require__: mixed; -*/ +const {promisify} = __webpack_require__(111); +const path = __webpack_require__(4); +const globby = __webpack_require__(289); +const isGlob = __webpack_require__(367); +const slash = __webpack_require__(365); +const gracefulFs = __webpack_require__(132); +const isPathCwd = __webpack_require__(368); +const isPathInside = __webpack_require__(369); +const rimraf = __webpack_require__(370); +const pMap = __webpack_require__(371); -module.exports = typeof __webpack_require__ !== "undefined"; +const rimrafP = promisify(rimraf); +const rimrafOptions = { + glob: false, + unlink: gracefulFs.unlink, + unlinkSync: gracefulFs.unlinkSync, + chmod: gracefulFs.chmod, + chmodSync: gracefulFs.chmodSync, + stat: gracefulFs.stat, + statSync: gracefulFs.statSync, + lstat: gracefulFs.lstat, + lstatSync: gracefulFs.lstatSync, + rmdir: gracefulFs.rmdir, + rmdirSync: gracefulFs.rmdirSync, + readdir: gracefulFs.readdir, + readdirSync: gracefulFs.readdirSync +}; -/***/ }), -/* 228 */, -/* 229 */ -/***/ (function(module, exports) { +function safeCheck(file, cwd) { + if (isPathCwd(file)) { + throw new Error('Cannot delete the current working directory. Can be overridden with the `force` option.'); + } -/** - * Helpers. - */ + if (!isPathInside(file, cwd)) { + throw new Error('Cannot delete files/directories outside the current working directory. Can be overridden with the `force` option.'); + } +} -var s = 1000; -var m = s * 60; -var h = m * 60; -var d = h * 24; -var y = d * 365.25; - -/** - * Parse or format the given `val`. - * - * Options: - * - * - `long` verbose formatting [false] - * - * @param {String|Number} val - * @param {Object} [options] - * @throws {Error} throw an error if val is not a non-empty string or a number - * @return {String|Number} - * @api public - */ +function normalizePatterns(patterns) { + patterns = Array.isArray(patterns) ? patterns : [patterns]; -module.exports = function(val, options) { - options = options || {}; - var type = typeof val; - if (type === 'string' && val.length > 0) { - return parse(val); - } else if (type === 'number' && isNaN(val) === false) { - return options.long ? fmtLong(val) : fmtShort(val); - } - throw new Error( - 'val is not a non-empty string or a valid number. val=' + - JSON.stringify(val) - ); -}; + patterns = patterns.map(pattern => { + if (process.platform === 'win32' && isGlob(pattern) === false) { + return slash(pattern); + } -/** - * Parse the given `str` and return milliseconds. - * - * @param {String} str - * @return {Number} - * @api private - */ + return pattern; + }); -function parse(str) { - str = String(str); - if (str.length > 100) { - return; - } - var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec( - str - ); - if (!match) { - return; - } - var n = parseFloat(match[1]); - var type = (match[2] || 'ms').toLowerCase(); - switch (type) { - case 'years': - case 'year': - case 'yrs': - case 'yr': - case 'y': - return n * y; - case 'days': - case 'day': - case 'd': - return n * d; - case 'hours': - case 'hour': - case 'hrs': - case 'hr': - case 'h': - return n * h; - case 'minutes': - case 'minute': - case 'mins': - case 'min': - case 'm': - return n * m; - case 'seconds': - case 'second': - case 'secs': - case 'sec': - case 's': - return n * s; - case 'milliseconds': - case 'millisecond': - case 'msecs': - case 'msec': - case 'ms': - return n; - default: - return undefined; - } + return patterns; } -/** - * Short format for `ms`. - * - * @param {Number} ms - * @return {String} - * @api private - */ - -function fmtShort(ms) { - if (ms >= d) { - return Math.round(ms / d) + 'd'; - } - if (ms >= h) { - return Math.round(ms / h) + 'h'; - } - if (ms >= m) { - return Math.round(ms / m) + 'm'; - } - if (ms >= s) { - return Math.round(ms / s) + 's'; - } - return ms + 'ms'; -} +module.exports = async (patterns, {force, dryRun, cwd = process.cwd(), ...options} = {}) => { + options = { + expandDirectories: false, + onlyFiles: false, + followSymbolicLinks: false, + cwd, + ...options + }; -/** - * Long format for `ms`. - * - * @param {Number} ms - * @return {String} - * @api private - */ + patterns = normalizePatterns(patterns); -function fmtLong(ms) { - return plural(ms, d, 'day') || - plural(ms, h, 'hour') || - plural(ms, m, 'minute') || - plural(ms, s, 'second') || - ms + ' ms'; -} + const files = (await globby(patterns, options)) + .sort((a, b) => b.localeCompare(a)); -/** - * Pluralization helper. - */ + const mapper = async file => { + file = path.resolve(cwd, file); -function plural(ms, n, name) { - if (ms < n) { - return; - } - if (ms < n * 1.5) { - return Math.floor(ms / n) + ' ' + name; - } - return Math.ceil(ms / n) + ' ' + name + 's'; -} + if (!force) { + safeCheck(file, cwd); + } + if (!dryRun) { + await rimrafP(file, rimrafOptions); + } -/***/ }), -/* 230 */, -/* 231 */, -/* 232 */, -/* 233 */ -/***/ (function(module, exports, __webpack_require__) { + return file; + }; -module.exports = rimraf -rimraf.sync = rimrafSync + const removedFiles = await pMap(files, mapper, options); -var assert = __webpack_require__(22) -var path = __webpack_require__(0) -var fs = __webpack_require__(3) -var glob = __webpack_require__(75) -var _0666 = parseInt('666', 8) + removedFiles.sort((a, b) => a.localeCompare(b)); -var defaultGlobOpts = { - nosort: true, - silent: true -} + return removedFiles; +}; -// for EMFILE handling -var timeout = 0 +module.exports.sync = (patterns, {force, dryRun, cwd = process.cwd(), ...options} = {}) => { + options = { + expandDirectories: false, + onlyFiles: false, + followSymbolicLinks: false, + cwd, + ...options + }; -var isWindows = (process.platform === "win32") + patterns = normalizePatterns(patterns); -function defaults (options) { - var methods = [ - 'unlink', - 'chmod', - 'stat', - 'lstat', - 'rmdir', - 'readdir' - ] - methods.forEach(function(m) { - options[m] = options[m] || fs[m] - m = m + 'Sync' - options[m] = options[m] || fs[m] - }) + const files = globby.sync(patterns, options) + .sort((a, b) => b.localeCompare(a)); - options.maxBusyTries = options.maxBusyTries || 3 - options.emfileWait = options.emfileWait || 1000 - if (options.glob === false) { - options.disableGlob = true - } - options.disableGlob = options.disableGlob || false - options.glob = options.glob || defaultGlobOpts -} + const removedFiles = files.map(file => { + file = path.resolve(cwd, file); -function rimraf (p, options, cb) { - if (typeof options === 'function') { - cb = options - options = {} - } + if (!force) { + safeCheck(file, cwd); + } - assert(p, 'rimraf: missing path') - assert.equal(typeof p, 'string', 'rimraf: path should be a string') - assert.equal(typeof cb, 'function', 'rimraf: callback function required') - assert(options, 'rimraf: invalid options argument provided') - assert.equal(typeof options, 'object', 'rimraf: options should be object') + if (!dryRun) { + rimraf.sync(file, rimrafOptions); + } - defaults(options) + return file; + }); - var busyTries = 0 - var errState = null - var n = 0 + removedFiles.sort((a, b) => a.localeCompare(b)); - if (options.disableGlob || !glob.hasMagic(p)) - return afterGlob(null, [p]) + return removedFiles; +}; - options.lstat(p, function (er, stat) { - if (!er) - return afterGlob(null, [p]) - glob(p, options.glob, afterGlob) - }) +/***/ }), +/* 289 */ +/***/ (function(module, exports, __webpack_require__) { - function next (er) { - errState = errState || er - if (--n === 0) - cb(errState) - } +"use strict"; - function afterGlob (er, results) { - if (er) - return cb(er) +const fs = __webpack_require__(133); +const arrayUnion = __webpack_require__(290); +const merge2 = __webpack_require__(291); +const glob = __webpack_require__(146); +const fastGlob = __webpack_require__(292); +const dirGlob = __webpack_require__(361); +const gitignore = __webpack_require__(363); +const {FilterStream, UniqueStream} = __webpack_require__(366); - n = results.length - if (n === 0) - return cb() +const DEFAULT_FILTER = () => false; - results.forEach(function (p) { - rimraf_(p, options, function CB (er) { - if (er) { - if ((er.code === "EBUSY" || er.code === "ENOTEMPTY" || er.code === "EPERM") && - busyTries < options.maxBusyTries) { - busyTries ++ - var time = busyTries * 100 - // try again, with the same exact callback as this one. - return setTimeout(function () { - rimraf_(p, options, CB) - }, time) - } +const isNegative = pattern => pattern[0] === '!'; - // this one won't happen if graceful-fs is used. - if (er.code === "EMFILE" && timeout < options.emfileWait) { - return setTimeout(function () { - rimraf_(p, options, CB) - }, timeout ++) - } +const assertPatternsInput = patterns => { + if (!patterns.every(pattern => typeof pattern === 'string')) { + throw new TypeError('Patterns must be a string or an array of strings'); + } +}; - // already gone - if (er.code === "ENOENT") er = null - } +const checkCwdOption = (options = {}) => { + if (!options.cwd) { + return; + } - timeout = 0 - next(er) - }) - }) - } -} + let stat; + try { + stat = fs.statSync(options.cwd); + } catch (_) { + return; + } -// Two possible strategies. -// 1. Assume it's a file. unlink it, then do the dir stuff on EPERM or EISDIR -// 2. Assume it's a directory. readdir, then do the file stuff on ENOTDIR -// -// Both result in an extra syscall when you guess wrong. However, there -// are likely far more normal files in the world than directories. This -// is based on the assumption that a the average number of files per -// directory is >= 1. -// -// If anyone ever complains about this, then I guess the strategy could -// be made configurable somehow. But until then, YAGNI. -function rimraf_ (p, options, cb) { - assert(p) - assert(options) - assert(typeof cb === 'function') + if (!stat.isDirectory()) { + throw new Error('The `cwd` option must be a path to a directory'); + } +}; - // sunos lets the root user unlink directories, which is... weird. - // so we have to lstat here and make sure it's not a dir. - options.lstat(p, function (er, st) { - if (er && er.code === "ENOENT") - return cb(null) +const getPathString = p => p.stats instanceof fs.Stats ? p.path : p; - // Windows can EPERM on stat. Life is suffering. - if (er && er.code === "EPERM" && isWindows) - fixWinEPERM(p, options, er, cb) +const generateGlobTasks = (patterns, taskOptions) => { + patterns = arrayUnion([].concat(patterns)); + assertPatternsInput(patterns); + checkCwdOption(taskOptions); - if (st && st.isDirectory()) - return rmdir(p, options, er, cb) + const globTasks = []; - options.unlink(p, function (er) { - if (er) { - if (er.code === "ENOENT") - return cb(null) - if (er.code === "EPERM") - return (isWindows) - ? fixWinEPERM(p, options, er, cb) - : rmdir(p, options, er, cb) - if (er.code === "EISDIR") - return rmdir(p, options, er, cb) - } - return cb(er) - }) - }) -} + taskOptions = { + ignore: [], + expandDirectories: true, + ...taskOptions + }; -function fixWinEPERM (p, options, er, cb) { - assert(p) - assert(options) - assert(typeof cb === 'function') - if (er) - assert(er instanceof Error) + for (const [index, pattern] of patterns.entries()) { + if (isNegative(pattern)) { + continue; + } - options.chmod(p, _0666, function (er2) { - if (er2) - cb(er2.code === "ENOENT" ? null : er) - else - options.stat(p, function(er3, stats) { - if (er3) - cb(er3.code === "ENOENT" ? null : er) - else if (stats.isDirectory()) - rmdir(p, options, er, cb) - else - options.unlink(p, cb) - }) - }) -} + const ignore = patterns + .slice(index) + .filter(isNegative) + .map(pattern => pattern.slice(1)); -function fixWinEPERMSync (p, options, er) { - assert(p) - assert(options) - if (er) - assert(er instanceof Error) + const options = { + ...taskOptions, + ignore: taskOptions.ignore.concat(ignore) + }; - try { - options.chmodSync(p, _0666) - } catch (er2) { - if (er2.code === "ENOENT") - return - else - throw er - } + globTasks.push({pattern, options}); + } - try { - var stats = options.statSync(p) - } catch (er3) { - if (er3.code === "ENOENT") - return - else - throw er - } + return globTasks; +}; - if (stats.isDirectory()) - rmdirSync(p, options, er) - else - options.unlinkSync(p) -} +const globDirs = (task, fn) => { + let options = {}; + if (task.options.cwd) { + options.cwd = task.options.cwd; + } -function rmdir (p, options, originalEr, cb) { - assert(p) - assert(options) - if (originalEr) - assert(originalEr instanceof Error) - assert(typeof cb === 'function') + if (Array.isArray(task.options.expandDirectories)) { + options = { + ...options, + files: task.options.expandDirectories + }; + } else if (typeof task.options.expandDirectories === 'object') { + options = { + ...options, + ...task.options.expandDirectories + }; + } - // try to rmdir first, and only readdir on ENOTEMPTY or EEXIST (SunOS) - // if we guessed wrong, and it's not a directory, then - // raise the original error. - options.rmdir(p, function (er) { - if (er && (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM")) - rmkids(p, options, cb) - else if (er && er.code === "ENOTDIR") - cb(originalEr) - else - cb(er) - }) -} + return fn(task.pattern, options); +}; -function rmkids(p, options, cb) { - assert(p) - assert(options) - assert(typeof cb === 'function') +const getPattern = (task, fn) => task.options.expandDirectories ? globDirs(task, fn) : [task.pattern]; - options.readdir(p, function (er, files) { - if (er) - return cb(er) - var n = files.length - if (n === 0) - return options.rmdir(p, cb) - var errState - files.forEach(function (f) { - rimraf(path.join(p, f), options, function (er) { - if (errState) - return - if (er) - return cb(errState = er) - if (--n === 0) - options.rmdir(p, cb) - }) - }) - }) -} +const getFilterSync = options => { + return options && options.gitignore ? + gitignore.sync({cwd: options.cwd, ignore: options.ignore}) : + DEFAULT_FILTER; +}; -// this looks simpler, and is strictly *faster*, but will -// tie up the JavaScript thread and fail on excessively -// deep directory trees. -function rimrafSync (p, options) { - options = options || {} - defaults(options) - - assert(p, 'rimraf: missing path') - assert.equal(typeof p, 'string', 'rimraf: path should be a string') - assert(options, 'rimraf: missing options') - assert.equal(typeof options, 'object', 'rimraf: options should be object') - - var results - - if (options.disableGlob || !glob.hasMagic(p)) { - results = [p] - } else { - try { - options.lstatSync(p) - results = [p] - } catch (er) { - results = glob.sync(p, options.glob) - } - } - - if (!results.length) - return - - for (var i = 0; i < results.length; i++) { - var p = results[i] - - try { - var st = options.lstatSync(p) - } catch (er) { - if (er.code === "ENOENT") - return - - // Windows can EPERM on stat. Life is suffering. - if (er.code === "EPERM" && isWindows) - fixWinEPERMSync(p, options, er) - } - - try { - // sunos lets the root user unlink directories, which is... weird. - if (st && st.isDirectory()) - rmdirSync(p, options, null) - else - options.unlinkSync(p) - } catch (er) { - if (er.code === "ENOENT") - return - if (er.code === "EPERM") - return isWindows ? fixWinEPERMSync(p, options, er) : rmdirSync(p, options, er) - if (er.code !== "EISDIR") - throw er - - rmdirSync(p, options, er) - } - } -} - -function rmdirSync (p, options, originalEr) { - assert(p) - assert(options) - if (originalEr) - assert(originalEr instanceof Error) - - try { - options.rmdirSync(p) - } catch (er) { - if (er.code === "ENOENT") - return - if (er.code === "ENOTDIR") - throw originalEr - if (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM") - rmkidsSync(p, options) - } -} - -function rmkidsSync (p, options) { - assert(p) - assert(options) - options.readdirSync(p).forEach(function (f) { - rimrafSync(path.join(p, f), options) - }) - - // We only end up here once we got ENOTEMPTY at least once, and - // at this point, we are guaranteed to have removed all the kids. - // So, we know that it won't be ENOENT or ENOTDIR or anything else. - // try really hard to delete stuff on windows, because it has a - // PROFOUNDLY annoying habit of not closing handles promptly when - // files are deleted, resulting in spurious ENOTEMPTY errors. - var retries = isWindows ? 100 : 1 - var i = 0 - do { - var threw = true - try { - var ret = options.rmdirSync(p, options) - threw = false - return ret - } finally { - if (++i < retries && threw) - continue - } - } while (true) -} - - -/***/ }), -/* 234 */, -/* 235 */, -/* 236 */, -/* 237 */, -/* 238 */, -/* 239 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -var hasFlag = __webpack_require__(221); - -var support = function (level) { - if (level === 0) { - return false; - } +const globToTask = task => glob => { + const {options} = task; + if (options.ignore && Array.isArray(options.ignore) && options.expandDirectories) { + options.ignore = dirGlob.sync(options.ignore); + } return { - level: level, - hasBasic: true, - has256: level >= 2, - has16m: level >= 3 + pattern: glob, + options }; }; -var supportLevel = (function () { - if (hasFlag('no-color') || - hasFlag('no-colors') || - hasFlag('color=false')) { - return 0; - } +module.exports = async (patterns, options) => { + const globTasks = generateGlobTasks(patterns, options); - if (hasFlag('color=16m') || - hasFlag('color=full') || - hasFlag('color=truecolor')) { - return 3; - } + const getFilter = async () => { + return options && options.gitignore ? + gitignore({cwd: options.cwd, ignore: options.ignore}) : + DEFAULT_FILTER; + }; - if (hasFlag('color=256')) { - return 2; - } + const getTasks = async () => { + const tasks = await Promise.all(globTasks.map(async task => { + const globs = await getPattern(task, dirGlob); + return Promise.all(globs.map(globToTask(task))); + })); - if (hasFlag('color') || - hasFlag('colors') || - hasFlag('color=true') || - hasFlag('color=always')) { - return 1; - } + return arrayUnion(...tasks); + }; - if (process.stdout && !process.stdout.isTTY) { - return 0; - } + const [filter, tasks] = await Promise.all([getFilter(), getTasks()]); + const paths = await Promise.all(tasks.map(task => fastGlob(task.pattern, task.options))); - if (process.platform === 'win32') { - return 1; - } + return arrayUnion(...paths).filter(path_ => !filter(getPathString(path_))); +}; - if ('CI' in process.env) { - if ('TRAVIS' in process.env || process.env.CI === 'Travis') { - return 1; - } +module.exports.sync = (patterns, options) => { + const globTasks = generateGlobTasks(patterns, options); - return 0; - } + const tasks = globTasks.reduce((tasks, task) => { + const newTask = getPattern(task, dirGlob.sync).map(globToTask(task)); + return tasks.concat(newTask); + }, []); - if ('TEAMCITY_VERSION' in process.env) { - return process.env.TEAMCITY_VERSION.match(/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/) === null ? 0 : 1; - } + const filter = getFilterSync(options); - if (/^(screen|xterm)-256(?:color)?/.test(process.env.TERM)) { - return 2; - } + return tasks.reduce( + (matches, task) => arrayUnion(matches, fastGlob.sync(task.pattern, task.options)), + [] + ).filter(path_ => !filter(path_)); +}; - if (/^screen|^xterm|^vt100|color|ansi|cygwin|linux/i.test(process.env.TERM)) { - return 1; - } +module.exports.stream = (patterns, options) => { + const globTasks = generateGlobTasks(patterns, options); - if ('COLORTERM' in process.env) { - return 1; - } + const tasks = globTasks.reduce((tasks, task) => { + const newTask = getPattern(task, dirGlob.sync).map(globToTask(task)); + return tasks.concat(newTask); + }, []); - if (process.env.TERM === 'dumb') { - return 0; - } + const filter = getFilterSync(options); + const filterStream = new FilterStream(p => !filter(p)); + const uniqueStream = new UniqueStream(); - return 0; -})(); + return merge2(tasks.map(task => fastGlob.stream(task.pattern, task.options))) + .pipe(filterStream) + .pipe(uniqueStream); +}; -if (supportLevel === 0 && 'FORCE_COLOR' in process.env) { - supportLevel = 1; -} +module.exports.generateGlobTasks = generateGlobTasks; -module.exports = process && support(supportLevel); +module.exports.hasMagic = (patterns, options) => [] + .concat(patterns) + .some(pattern => glob.hasMagic(pattern, options)); +module.exports.gitignore = gitignore; -/***/ }) -/******/ ]); /***/ }), -/* 293 */ -/***/ (function(module, exports) { +/* 290 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +module.exports = (...arguments_) => { + return [...new Set([].concat(...arguments_))]; +}; -module.exports = require("buffer"); /***/ }), -/* 294 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* 291 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BootstrapCacheFile", function() { return BootstrapCacheFile; }); -/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(133); -/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(fs__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4); -/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_1__); -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 + * merge2 + * https://github.com/teambition/merge2 * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Copyright (c) 2014-2020 Teambition + * Licensed under the MIT license. */ +const Stream = __webpack_require__(137) +const PassThrough = Stream.PassThrough +const slice = Array.prototype.slice +module.exports = merge2 -class BootstrapCacheFile { - constructor(kbn, project, checksums) { - _defineProperty(this, "path", void 0); +function merge2 () { + const streamsQueue = [] + const args = slice.call(arguments) + let merging = false + let options = args[args.length - 1] - _defineProperty(this, "expectedValue", void 0); + if (options && !Array.isArray(options) && options.pipe == null) { + args.pop() + } else { + options = {} + } - this.path = path__WEBPACK_IMPORTED_MODULE_1___default.a.resolve(project.targetLocation, '.bootstrap-cache'); + const doEnd = options.end !== false + const doPipeError = options.pipeError === true + if (options.objectMode == null) { + options.objectMode = true + } + if (options.highWaterMark == null) { + options.highWaterMark = 64 * 1024 + } + const mergedStream = PassThrough(options) - if (!checksums) { - return; + function addStream () { + for (let i = 0, len = arguments.length; i < len; i++) { + streamsQueue.push(pauseStreams(arguments[i], options)) } + mergeStream() + return this + } - const projectAndDepCacheKeys = Array.from(kbn.getProjectAndDeps(project.name).values()) // sort deps by name so that the key is stable - .sort((a, b) => a.name.localeCompare(b.name)) // get the cacheKey for each project, return undefined if the cache key couldn't be determined - .map(p => { - const cacheKey = checksums.get(p.name); + function mergeStream () { + if (merging) { + return + } + merging = true - if (cacheKey) { - return `${p.name}:${cacheKey}`; - } - }); // if any of the relevant cache keys are undefined then the projectCacheKey must be too + let streams = streamsQueue.shift() + if (!streams) { + process.nextTick(endStream) + return + } + if (!Array.isArray(streams)) { + streams = [streams] + } - this.expectedValue = projectAndDepCacheKeys.some(k => !k) ? undefined : [`# this is only human readable for debugging, please don't try to parse this`, ...projectAndDepCacheKeys].join('\n'); - } + let pipesCount = streams.length + 1 - isValid() { - if (!this.expectedValue) { - return false; + function next () { + if (--pipesCount > 0) { + return + } + merging = false + mergeStream() } - try { - return fs__WEBPACK_IMPORTED_MODULE_0___default.a.readFileSync(this.path, 'utf8') === this.expectedValue; - } catch (error) { - if (error.code === 'ENOENT') { - return false; + function pipe (stream) { + function onend () { + stream.removeListener('merge2UnpipeEnd', onend) + stream.removeListener('end', onend) + if (doPipeError) { + stream.removeListener('error', onerror) + } + next() + } + function onerror (err) { + mergedStream.emit('error', err) + } + // skip ended stream + if (stream._readableState.endEmitted) { + return next() } - throw error; - } - } + stream.on('merge2UnpipeEnd', onend) + stream.on('end', onend) - delete() { - try { - fs__WEBPACK_IMPORTED_MODULE_0___default.a.unlinkSync(this.path); - } catch (error) { - if (error.code !== 'ENOENT') { - throw error; + if (doPipeError) { + stream.on('error', onerror) } + + stream.pipe(mergedStream, { end: false }) + // compatible for old stream + stream.resume() + } + + for (let i = 0; i < streams.length; i++) { + pipe(streams[i]) } + + next() } - write() { - if (!this.expectedValue) { - return; + function endStream () { + merging = false + // emit 'queueDrain' when all streams merged. + mergedStream.emit('queueDrain') + if (doEnd) { + mergedStream.end() } + } - fs__WEBPACK_IMPORTED_MODULE_0___default.a.mkdirSync(path__WEBPACK_IMPORTED_MODULE_1___default.a.dirname(this.path), { - recursive: true - }); - fs__WEBPACK_IMPORTED_MODULE_0___default.a.writeFileSync(this.path, this.expectedValue); + mergedStream.setMaxListeners(0) + mergedStream.add = addStream + mergedStream.on('unpipe', function (stream) { + stream.emit('merge2UnpipeEnd') + }) + + if (args.length) { + addStream.apply(null, args) } + return mergedStream +} +// check and pause streams for pipe. +function pauseStreams (streams, options) { + if (!Array.isArray(streams)) { + // Backwards-compat with old-style streams + if (!streams._readableState && streams.pipe) { + streams = streams.pipe(PassThrough(options)) + } + if (!streams._readableState || !streams.pause || !streams.pipe) { + throw new Error('Only readable stream can be merged.') + } + streams.pause() + } else { + for (let i = 0, len = streams.length; i < len; i++) { + streams[i] = pauseStreams(streams[i], options) + } + } + return streams } + /***/ }), -/* 295 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* 292 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CleanCommand", function() { return CleanCommand; }); -/* harmony import */ var del__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(296); -/* harmony import */ var del__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(del__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var ora__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(383); -/* harmony import */ var ora__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(ora__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4); -/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var _utils_fs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(130); -/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(143); -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - - + +const taskManager = __webpack_require__(293); +const async_1 = __webpack_require__(322); +const stream_1 = __webpack_require__(357); +const sync_1 = __webpack_require__(358); +const settings_1 = __webpack_require__(360); +const utils = __webpack_require__(294); +async function FastGlob(source, options) { + assertPatternsInput(source); + const works = getWorks(source, async_1.default, options); + const result = await Promise.all(works); + return utils.array.flatten(result); +} +// https://github.com/typescript-eslint/typescript-eslint/issues/60 +// eslint-disable-next-line no-redeclare +(function (FastGlob) { + function sync(source, options) { + assertPatternsInput(source); + const works = getWorks(source, sync_1.default, options); + return utils.array.flatten(works); + } + FastGlob.sync = sync; + function stream(source, options) { + assertPatternsInput(source); + const works = getWorks(source, stream_1.default, options); + /** + * The stream returned by the provider cannot work with an asynchronous iterator. + * To support asynchronous iterators, regardless of the number of tasks, we always multiplex streams. + * This affects performance (+25%). I don't see best solution right now. + */ + return utils.stream.merge(works); + } + FastGlob.stream = stream; + function generateTasks(source, options) { + assertPatternsInput(source); + const patterns = [].concat(source); + const settings = new settings_1.default(options); + return taskManager.generate(patterns, settings); + } + FastGlob.generateTasks = generateTasks; + function isDynamicPattern(source, options) { + assertPatternsInput(source); + const settings = new settings_1.default(options); + return utils.pattern.isDynamicPattern(source, settings); + } + FastGlob.isDynamicPattern = isDynamicPattern; + function escapePath(source) { + assertPatternsInput(source); + return utils.path.escape(source); + } + FastGlob.escapePath = escapePath; +})(FastGlob || (FastGlob = {})); +function getWorks(source, _Provider, options) { + const patterns = [].concat(source); + const settings = new settings_1.default(options); + const tasks = taskManager.generate(patterns, settings); + const provider = new _Provider(settings); + return tasks.map(provider.read, provider); +} +function assertPatternsInput(input) { + const source = [].concat(input); + const isValidSource = source.every((item) => utils.string.isString(item) && !utils.string.isEmpty(item)); + if (!isValidSource) { + throw new TypeError('Patterns must be a string (non empty) or an array of strings'); + } +} +module.exports = FastGlob; +/***/ }), +/* 293 */ +/***/ (function(module, exports, __webpack_require__) { -const CleanCommand = { - description: 'Remove the node_modules and target directories from all projects.', - name: 'clean', +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const utils = __webpack_require__(294); +function generate(patterns, settings) { + const positivePatterns = getPositivePatterns(patterns); + const negativePatterns = getNegativePatternsAsPositive(patterns, settings.ignore); + const staticPatterns = positivePatterns.filter((pattern) => utils.pattern.isStaticPattern(pattern, settings)); + const dynamicPatterns = positivePatterns.filter((pattern) => utils.pattern.isDynamicPattern(pattern, settings)); + const staticTasks = convertPatternsToTasks(staticPatterns, negativePatterns, /* dynamic */ false); + const dynamicTasks = convertPatternsToTasks(dynamicPatterns, negativePatterns, /* dynamic */ true); + return staticTasks.concat(dynamicTasks); +} +exports.generate = generate; +function convertPatternsToTasks(positive, negative, dynamic) { + const positivePatternsGroup = groupPatternsByBaseDirectory(positive); + // When we have a global group – there is no reason to divide the patterns into independent tasks. + // In this case, the global task covers the rest. + if ('.' in positivePatternsGroup) { + const task = convertPatternGroupToTask('.', positive, negative, dynamic); + return [task]; + } + return convertPatternGroupsToTasks(positivePatternsGroup, negative, dynamic); +} +exports.convertPatternsToTasks = convertPatternsToTasks; +function getPositivePatterns(patterns) { + return utils.pattern.getPositivePatterns(patterns); +} +exports.getPositivePatterns = getPositivePatterns; +function getNegativePatternsAsPositive(patterns, ignore) { + const negative = utils.pattern.getNegativePatterns(patterns).concat(ignore); + const positive = negative.map(utils.pattern.convertToPositivePattern); + return positive; +} +exports.getNegativePatternsAsPositive = getNegativePatternsAsPositive; +function groupPatternsByBaseDirectory(patterns) { + const group = {}; + return patterns.reduce((collection, pattern) => { + const base = utils.pattern.getBaseDirectory(pattern); + if (base in collection) { + collection[base].push(pattern); + } + else { + collection[base] = [pattern]; + } + return collection; + }, group); +} +exports.groupPatternsByBaseDirectory = groupPatternsByBaseDirectory; +function convertPatternGroupsToTasks(positive, negative, dynamic) { + return Object.keys(positive).map((base) => { + return convertPatternGroupToTask(base, positive[base], negative, dynamic); + }); +} +exports.convertPatternGroupsToTasks = convertPatternGroupsToTasks; +function convertPatternGroupToTask(base, positive, negative, dynamic) { + return { + dynamic, + positive, + negative, + base, + patterns: [].concat(positive, negative.map(utils.pattern.convertToNegativePattern)) + }; +} +exports.convertPatternGroupToTask = convertPatternGroupToTask; - async run(projects) { - const toDelete = []; - for (const project of projects.values()) { - if (await Object(_utils_fs__WEBPACK_IMPORTED_MODULE_3__["isDirectory"])(project.nodeModulesLocation)) { - toDelete.push({ - cwd: project.path, - pattern: Object(path__WEBPACK_IMPORTED_MODULE_2__["relative"])(project.path, project.nodeModulesLocation) - }); - } +/***/ }), +/* 294 */ +/***/ (function(module, exports, __webpack_require__) { - if (await Object(_utils_fs__WEBPACK_IMPORTED_MODULE_3__["isDirectory"])(project.targetLocation)) { - toDelete.push({ - cwd: project.path, - pattern: Object(path__WEBPACK_IMPORTED_MODULE_2__["relative"])(project.path, project.targetLocation) - }); - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const array = __webpack_require__(295); +exports.array = array; +const errno = __webpack_require__(296); +exports.errno = errno; +const fs = __webpack_require__(297); +exports.fs = fs; +const path = __webpack_require__(298); +exports.path = path; +const pattern = __webpack_require__(299); +exports.pattern = pattern; +const stream = __webpack_require__(320); +exports.stream = stream; +const string = __webpack_require__(321); +exports.string = string; - const { - extraPatterns - } = project.getCleanConfig(); - if (extraPatterns) { - toDelete.push({ - cwd: project.path, - pattern: extraPatterns - }); - } - } +/***/ }), +/* 295 */ +/***/ (function(module, exports, __webpack_require__) { - if (toDelete.length === 0) { - _utils_log__WEBPACK_IMPORTED_MODULE_4__["log"].success('Nothing to delete'); - } else { - /** - * In order to avoid patterns like `/build` in packages from accidentally - * impacting files outside the package we use `process.chdir()` to change - * the cwd to the package and execute `del()` without the `force` option - * so it will check that each file being deleted is within the package. - * - * `del()` does support a `cwd` option, but it's only for resolving the - * patterns and does not impact the cwd check. - */ - const originalCwd = process.cwd(); +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +function flatten(items) { + return items.reduce((collection, item) => [].concat(collection, item), []); +} +exports.flatten = flatten; +function splitWhen(items, predicate) { + const result = [[]]; + let groupIndex = 0; + for (const item of items) { + if (predicate(item)) { + groupIndex++; + result[groupIndex] = []; + } + else { + result[groupIndex].push(item); + } + } + return result; +} +exports.splitWhen = splitWhen; - try { - for (const { - pattern, - cwd - } of toDelete) { - process.chdir(cwd); - const promise = del__WEBPACK_IMPORTED_MODULE_0___default()(pattern); - if (_utils_log__WEBPACK_IMPORTED_MODULE_4__["log"].wouldLogLevel('info')) { - ora__WEBPACK_IMPORTED_MODULE_1___default.a.promise(promise, Object(path__WEBPACK_IMPORTED_MODULE_2__["relative"])(originalCwd, Object(path__WEBPACK_IMPORTED_MODULE_2__["join"])(cwd, String(pattern)))); - } +/***/ }), +/* 296 */ +/***/ (function(module, exports, __webpack_require__) { - await promise; - } - } finally { - process.chdir(originalCwd); - } - } - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +function isEnoentCodeError(error) { + return error.code === 'ENOENT'; +} +exports.isEnoentCodeError = isEnoentCodeError; -}; /***/ }), -/* 296 */ +/* 297 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +class DirentFromStats { + constructor(name, stats) { + this.name = name; + this.isBlockDevice = stats.isBlockDevice.bind(stats); + this.isCharacterDevice = stats.isCharacterDevice.bind(stats); + this.isDirectory = stats.isDirectory.bind(stats); + this.isFIFO = stats.isFIFO.bind(stats); + this.isFile = stats.isFile.bind(stats); + this.isSocket = stats.isSocket.bind(stats); + this.isSymbolicLink = stats.isSymbolicLink.bind(stats); + } +} +function createDirentFromStats(name, stats) { + return new DirentFromStats(name, stats); +} +exports.createDirentFromStats = createDirentFromStats; -const {promisify} = __webpack_require__(111); -const path = __webpack_require__(4); -const globby = __webpack_require__(297); -const isGlob = __webpack_require__(375); -const slash = __webpack_require__(373); -const gracefulFs = __webpack_require__(132); -const isPathCwd = __webpack_require__(376); -const isPathInside = __webpack_require__(377); -const rimraf = __webpack_require__(378); -const pMap = __webpack_require__(379); - -const rimrafP = promisify(rimraf); -const rimrafOptions = { - glob: false, - unlink: gracefulFs.unlink, - unlinkSync: gracefulFs.unlinkSync, - chmod: gracefulFs.chmod, - chmodSync: gracefulFs.chmodSync, - stat: gracefulFs.stat, - statSync: gracefulFs.statSync, - lstat: gracefulFs.lstat, - lstatSync: gracefulFs.lstatSync, - rmdir: gracefulFs.rmdir, - rmdirSync: gracefulFs.rmdirSync, - readdir: gracefulFs.readdir, - readdirSync: gracefulFs.readdirSync -}; +/***/ }), +/* 298 */ +/***/ (function(module, exports, __webpack_require__) { -function safeCheck(file, cwd) { - if (isPathCwd(file)) { - throw new Error('Cannot delete the current working directory. Can be overridden with the `force` option.'); - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const path = __webpack_require__(4); +const LEADING_DOT_SEGMENT_CHARACTERS_COUNT = 2; // ./ or .\\ +const UNESCAPED_GLOB_SYMBOLS_RE = /(\\?)([()*?[\]{|}]|^!|[!+@](?=\())/g; +/** + * Designed to work only with simple paths: `dir\\file`. + */ +function unixify(filepath) { + return filepath.replace(/\\/g, '/'); +} +exports.unixify = unixify; +function makeAbsolute(cwd, filepath) { + return path.resolve(cwd, filepath); +} +exports.makeAbsolute = makeAbsolute; +function escape(pattern) { + return pattern.replace(UNESCAPED_GLOB_SYMBOLS_RE, '\\$2'); +} +exports.escape = escape; +function removeLeadingDotSegment(entry) { + // We do not use `startsWith` because this is 10x slower than current implementation for some cases. + // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with + if (entry.charAt(0) === '.') { + const secondCharactery = entry.charAt(1); + if (secondCharactery === '/' || secondCharactery === '\\') { + return entry.slice(LEADING_DOT_SEGMENT_CHARACTERS_COUNT); + } + } + return entry; +} +exports.removeLeadingDotSegment = removeLeadingDotSegment; - if (!isPathInside(file, cwd)) { - throw new Error('Cannot delete files/directories outside the current working directory. Can be overridden with the `force` option.'); - } -} -function normalizePatterns(patterns) { - patterns = Array.isArray(patterns) ? patterns : [patterns]; +/***/ }), +/* 299 */ +/***/ (function(module, exports, __webpack_require__) { - patterns = patterns.map(pattern => { - if (process.platform === 'win32' && isGlob(pattern) === false) { - return slash(pattern); - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const path = __webpack_require__(4); +const globParent = __webpack_require__(300); +const micromatch = __webpack_require__(303); +const picomatch = __webpack_require__(314); +const GLOBSTAR = '**'; +const ESCAPE_SYMBOL = '\\'; +const COMMON_GLOB_SYMBOLS_RE = /[*?]|^!/; +const REGEX_CHARACTER_CLASS_SYMBOLS_RE = /\[.*]/; +const REGEX_GROUP_SYMBOLS_RE = /(?:^|[^!*+?@])\(.*\|.*\)/; +const GLOB_EXTENSION_SYMBOLS_RE = /[!*+?@]\(.*\)/; +const BRACE_EXPANSIONS_SYMBOLS_RE = /{.*(?:,|\.\.).*}/; +function isStaticPattern(pattern, options = {}) { + return !isDynamicPattern(pattern, options); +} +exports.isStaticPattern = isStaticPattern; +function isDynamicPattern(pattern, options = {}) { + /** + * When the `caseSensitiveMatch` option is disabled, all patterns must be marked as dynamic, because we cannot check + * filepath directly (without read directory). + */ + if (options.caseSensitiveMatch === false || pattern.includes(ESCAPE_SYMBOL)) { + return true; + } + if (COMMON_GLOB_SYMBOLS_RE.test(pattern) || REGEX_CHARACTER_CLASS_SYMBOLS_RE.test(pattern) || REGEX_GROUP_SYMBOLS_RE.test(pattern)) { + return true; + } + if (options.extglob !== false && GLOB_EXTENSION_SYMBOLS_RE.test(pattern)) { + return true; + } + if (options.braceExpansion !== false && BRACE_EXPANSIONS_SYMBOLS_RE.test(pattern)) { + return true; + } + return false; +} +exports.isDynamicPattern = isDynamicPattern; +function convertToPositivePattern(pattern) { + return isNegativePattern(pattern) ? pattern.slice(1) : pattern; +} +exports.convertToPositivePattern = convertToPositivePattern; +function convertToNegativePattern(pattern) { + return '!' + pattern; +} +exports.convertToNegativePattern = convertToNegativePattern; +function isNegativePattern(pattern) { + return pattern.startsWith('!') && pattern[1] !== '('; +} +exports.isNegativePattern = isNegativePattern; +function isPositivePattern(pattern) { + return !isNegativePattern(pattern); +} +exports.isPositivePattern = isPositivePattern; +function getNegativePatterns(patterns) { + return patterns.filter(isNegativePattern); +} +exports.getNegativePatterns = getNegativePatterns; +function getPositivePatterns(patterns) { + return patterns.filter(isPositivePattern); +} +exports.getPositivePatterns = getPositivePatterns; +function getBaseDirectory(pattern) { + return globParent(pattern, { flipBackslashes: false }); +} +exports.getBaseDirectory = getBaseDirectory; +function hasGlobStar(pattern) { + return pattern.includes(GLOBSTAR); +} +exports.hasGlobStar = hasGlobStar; +function endsWithSlashGlobStar(pattern) { + return pattern.endsWith('/' + GLOBSTAR); +} +exports.endsWithSlashGlobStar = endsWithSlashGlobStar; +function isAffectDepthOfReadingPattern(pattern) { + const basename = path.basename(pattern); + return endsWithSlashGlobStar(pattern) || isStaticPattern(basename); +} +exports.isAffectDepthOfReadingPattern = isAffectDepthOfReadingPattern; +function expandPatternsWithBraceExpansion(patterns) { + return patterns.reduce((collection, pattern) => { + return collection.concat(expandBraceExpansion(pattern)); + }, []); +} +exports.expandPatternsWithBraceExpansion = expandPatternsWithBraceExpansion; +function expandBraceExpansion(pattern) { + return micromatch.braces(pattern, { + expand: true, + nodupes: true + }); +} +exports.expandBraceExpansion = expandBraceExpansion; +function getPatternParts(pattern, options) { + const info = picomatch.scan(pattern, Object.assign(Object.assign({}, options), { parts: true })); + // See micromatch/picomatch#58 for more details + if (info.parts.length === 0) { + return [pattern]; + } + return info.parts; +} +exports.getPatternParts = getPatternParts; +function makeRe(pattern, options) { + return micromatch.makeRe(pattern, options); +} +exports.makeRe = makeRe; +function convertPatternsToRe(patterns, options) { + return patterns.map((pattern) => makeRe(pattern, options)); +} +exports.convertPatternsToRe = convertPatternsToRe; +function matchAny(entry, patternsRe) { + return patternsRe.some((patternRe) => patternRe.test(entry)); +} +exports.matchAny = matchAny; - return pattern; - }); - return patterns; -} +/***/ }), +/* 300 */ +/***/ (function(module, exports, __webpack_require__) { -module.exports = async (patterns, {force, dryRun, cwd = process.cwd(), ...options} = {}) => { - options = { - expandDirectories: false, - onlyFiles: false, - followSymbolicLinks: false, - cwd, - ...options - }; +"use strict"; - patterns = normalizePatterns(patterns); - const files = (await globby(patterns, options)) - .sort((a, b) => b.localeCompare(a)); +var isGlob = __webpack_require__(301); +var pathPosixDirname = __webpack_require__(4).posix.dirname; +var isWin32 = __webpack_require__(120).platform() === 'win32'; - const mapper = async file => { - file = path.resolve(cwd, file); +var slash = '/'; +var backslash = /\\/g; +var enclosure = /[\{\[].*[\/]*.*[\}\]]$/; +var globby = /(^|[^\\])([\{\[]|\([^\)]+$)/; +var escaped = /\\([\!\*\?\|\[\]\(\)\{\}])/g; - if (!force) { - safeCheck(file, cwd); - } +/** + * @param {string} str + * @param {Object} opts + * @param {boolean} [opts.flipBackslashes=true] + */ +module.exports = function globParent(str, opts) { + var options = Object.assign({ flipBackslashes: true }, opts); - if (!dryRun) { - await rimrafP(file, rimrafOptions); - } + // flip windows path separators + if (options.flipBackslashes && isWin32 && str.indexOf(slash) < 0) { + str = str.replace(backslash, slash); + } - return file; - }; + // special case for strings ending in enclosure containing path separator + if (enclosure.test(str)) { + str += slash; + } - const removedFiles = await pMap(files, mapper, options); + // preserves full path in case of trailing path separator + str += 'a'; - removedFiles.sort((a, b) => a.localeCompare(b)); + // remove path parts that are globby + do { + str = pathPosixDirname(str); + } while (isGlob(str) || globby.test(str)); - return removedFiles; + // remove escape chars and return result + return str.replace(escaped, '$1'); }; -module.exports.sync = (patterns, {force, dryRun, cwd = process.cwd(), ...options} = {}) => { - options = { - expandDirectories: false, - onlyFiles: false, - followSymbolicLinks: false, - cwd, - ...options - }; - patterns = normalizePatterns(patterns); +/***/ }), +/* 301 */ +/***/ (function(module, exports, __webpack_require__) { - const files = globby.sync(patterns, options) - .sort((a, b) => b.localeCompare(a)); +/*! + * is-glob + * + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. + */ - const removedFiles = files.map(file => { - file = path.resolve(cwd, file); +var isExtglob = __webpack_require__(302); +var chars = { '{': '}', '(': ')', '[': ']'}; +var strictRegex = /\\(.)|(^!|\*|[\].+)]\?|\[[^\\\]]+\]|\{[^\\}]+\}|\(\?[:!=][^\\)]+\)|\([^|]+\|[^\\)]+\))/; +var relaxedRegex = /\\(.)|(^!|[*?{}()[\]]|\(\?)/; - if (!force) { - safeCheck(file, cwd); - } +module.exports = function isGlob(str, options) { + if (typeof str !== 'string' || str === '') { + return false; + } - if (!dryRun) { - rimraf.sync(file, rimrafOptions); - } + if (isExtglob(str)) { + return true; + } - return file; - }); + var regex = strictRegex; + var match; - removedFiles.sort((a, b) => a.localeCompare(b)); + // optionally relax regex + if (options && options.strict === false) { + regex = relaxedRegex; + } - return removedFiles; + while ((match = regex.exec(str))) { + if (match[2]) return true; + var idx = match.index + match[0].length; + + // if an open bracket/brace/paren is escaped, + // set the index to the next closing character + var open = match[1]; + var close = open ? chars[open] : null; + if (open && close) { + var n = str.indexOf(close, idx); + if (n !== -1) { + idx = n + 1; + } + } + + str = str.slice(idx); + } + return false; }; /***/ }), -/* 297 */ -/***/ (function(module, exports, __webpack_require__) { +/* 302 */ +/***/ (function(module, exports) { -"use strict"; - -const fs = __webpack_require__(133); -const arrayUnion = __webpack_require__(298); -const merge2 = __webpack_require__(299); -const glob = __webpack_require__(146); -const fastGlob = __webpack_require__(300); -const dirGlob = __webpack_require__(369); -const gitignore = __webpack_require__(371); -const {FilterStream, UniqueStream} = __webpack_require__(374); +/*! + * is-extglob + * + * Copyright (c) 2014-2016, Jon Schlinkert. + * Licensed under the MIT License. + */ -const DEFAULT_FILTER = () => false; +module.exports = function isExtglob(str) { + if (typeof str !== 'string' || str === '') { + return false; + } -const isNegative = pattern => pattern[0] === '!'; + var match; + while ((match = /(\\).|([@?!+*]\(.*\))/g.exec(str))) { + if (match[2]) return true; + str = str.slice(match.index + match[0].length); + } -const assertPatternsInput = patterns => { - if (!patterns.every(pattern => typeof pattern === 'string')) { - throw new TypeError('Patterns must be a string or an array of strings'); - } + return false; }; -const checkCwdOption = (options = {}) => { - if (!options.cwd) { - return; - } - let stat; - try { - stat = fs.statSync(options.cwd); - } catch (_) { - return; - } +/***/ }), +/* 303 */ +/***/ (function(module, exports, __webpack_require__) { - if (!stat.isDirectory()) { - throw new Error('The `cwd` option must be a path to a directory'); - } -}; +"use strict"; -const getPathString = p => p.stats instanceof fs.Stats ? p.path : p; -const generateGlobTasks = (patterns, taskOptions) => { - patterns = arrayUnion([].concat(patterns)); - assertPatternsInput(patterns); - checkCwdOption(taskOptions); +const util = __webpack_require__(111); +const braces = __webpack_require__(304); +const picomatch = __webpack_require__(314); +const utils = __webpack_require__(317); +const isEmptyString = val => typeof val === 'string' && (val === '' || val === './'); - const globTasks = []; +/** + * Returns an array of strings that match one or more glob patterns. + * + * ```js + * const mm = require('micromatch'); + * // mm(list, patterns[, options]); + * + * console.log(mm(['a.js', 'a.txt'], ['*.js'])); + * //=> [ 'a.js' ] + * ``` + * @param {String|Array} list List of strings to match. + * @param {String|Array} patterns One or more glob patterns to use for matching. + * @param {Object} options See available [options](#options) + * @return {Array} Returns an array of matches + * @summary false + * @api public + */ - taskOptions = { - ignore: [], - expandDirectories: true, - ...taskOptions - }; +const micromatch = (list, patterns, options) => { + patterns = [].concat(patterns); + list = [].concat(list); - for (const [index, pattern] of patterns.entries()) { - if (isNegative(pattern)) { - continue; - } + let omit = new Set(); + let keep = new Set(); + let items = new Set(); + let negatives = 0; - const ignore = patterns - .slice(index) - .filter(isNegative) - .map(pattern => pattern.slice(1)); + let onResult = state => { + items.add(state.output); + if (options && options.onResult) { + options.onResult(state); + } + }; - const options = { - ...taskOptions, - ignore: taskOptions.ignore.concat(ignore) - }; + for (let i = 0; i < patterns.length; i++) { + let isMatch = picomatch(String(patterns[i]), { ...options, onResult }, true); + let negated = isMatch.state.negated || isMatch.state.negatedExtglob; + if (negated) negatives++; - globTasks.push({pattern, options}); - } + for (let item of list) { + let matched = isMatch(item, true); - return globTasks; -}; + let match = negated ? !matched.isMatch : matched.isMatch; + if (!match) continue; -const globDirs = (task, fn) => { - let options = {}; - if (task.options.cwd) { - options.cwd = task.options.cwd; - } + if (negated) { + omit.add(matched.output); + } else { + omit.delete(matched.output); + keep.add(matched.output); + } + } + } - if (Array.isArray(task.options.expandDirectories)) { - options = { - ...options, - files: task.options.expandDirectories - }; - } else if (typeof task.options.expandDirectories === 'object') { - options = { - ...options, - ...task.options.expandDirectories - }; - } + let result = negatives === patterns.length ? [...items] : [...keep]; + let matches = result.filter(item => !omit.has(item)); - return fn(task.pattern, options); -}; + if (options && matches.length === 0) { + if (options.failglob === true) { + throw new Error(`No matches found for "${patterns.join(', ')}"`); + } -const getPattern = (task, fn) => task.options.expandDirectories ? globDirs(task, fn) : [task.pattern]; + if (options.nonull === true || options.nullglob === true) { + return options.unescape ? patterns.map(p => p.replace(/\\/g, '')) : patterns; + } + } -const getFilterSync = options => { - return options && options.gitignore ? - gitignore.sync({cwd: options.cwd, ignore: options.ignore}) : - DEFAULT_FILTER; + return matches; }; -const globToTask = task => glob => { - const {options} = task; - if (options.ignore && Array.isArray(options.ignore) && options.expandDirectories) { - options.ignore = dirGlob.sync(options.ignore); - } +/** + * Backwards compatibility + */ - return { - pattern: glob, - options - }; -}; +micromatch.match = micromatch; -module.exports = async (patterns, options) => { - const globTasks = generateGlobTasks(patterns, options); +/** + * Returns a matcher function from the given glob `pattern` and `options`. + * The returned function takes a string to match as its only argument and returns + * true if the string is a match. + * + * ```js + * const mm = require('micromatch'); + * // mm.matcher(pattern[, options]); + * + * const isMatch = mm.matcher('*.!(*a)'); + * console.log(isMatch('a.a')); //=> false + * console.log(isMatch('a.b')); //=> true + * ``` + * @param {String} `pattern` Glob pattern + * @param {Object} `options` + * @return {Function} Returns a matcher function. + * @api public + */ - const getFilter = async () => { - return options && options.gitignore ? - gitignore({cwd: options.cwd, ignore: options.ignore}) : - DEFAULT_FILTER; - }; +micromatch.matcher = (pattern, options) => picomatch(pattern, options); - const getTasks = async () => { - const tasks = await Promise.all(globTasks.map(async task => { - const globs = await getPattern(task, dirGlob); - return Promise.all(globs.map(globToTask(task))); - })); +/** + * Returns true if **any** of the given glob `patterns` match the specified `string`. + * + * ```js + * const mm = require('micromatch'); + * // mm.isMatch(string, patterns[, options]); + * + * console.log(mm.isMatch('a.a', ['b.*', '*.a'])); //=> true + * console.log(mm.isMatch('a.a', 'b.*')); //=> false + * ``` + * @param {String} str The string to test. + * @param {String|Array} patterns One or more glob patterns to use for matching. + * @param {Object} [options] See available [options](#options). + * @return {Boolean} Returns true if any patterns match `str` + * @api public + */ - return arrayUnion(...tasks); - }; +micromatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str); - const [filter, tasks] = await Promise.all([getFilter(), getTasks()]); - const paths = await Promise.all(tasks.map(task => fastGlob(task.pattern, task.options))); +/** + * Backwards compatibility + */ - return arrayUnion(...paths).filter(path_ => !filter(getPathString(path_))); -}; +micromatch.any = micromatch.isMatch; -module.exports.sync = (patterns, options) => { - const globTasks = generateGlobTasks(patterns, options); +/** + * Returns a list of strings that _**do not match any**_ of the given `patterns`. + * + * ```js + * const mm = require('micromatch'); + * // mm.not(list, patterns[, options]); + * + * console.log(mm.not(['a.a', 'b.b', 'c.c'], '*.a')); + * //=> ['b.b', 'c.c'] + * ``` + * @param {Array} `list` Array of strings to match. + * @param {String|Array} `patterns` One or more glob pattern to use for matching. + * @param {Object} `options` See available [options](#options) for changing how matches are performed + * @return {Array} Returns an array of strings that **do not match** the given patterns. + * @api public + */ - const tasks = globTasks.reduce((tasks, task) => { - const newTask = getPattern(task, dirGlob.sync).map(globToTask(task)); - return tasks.concat(newTask); - }, []); +micromatch.not = (list, patterns, options = {}) => { + patterns = [].concat(patterns).map(String); + let result = new Set(); + let items = []; - const filter = getFilterSync(options); + let onResult = state => { + if (options.onResult) options.onResult(state); + items.push(state.output); + }; - return tasks.reduce( - (matches, task) => arrayUnion(matches, fastGlob.sync(task.pattern, task.options)), - [] - ).filter(path_ => !filter(path_)); -}; + let matches = micromatch(list, patterns, { ...options, onResult }); -module.exports.stream = (patterns, options) => { - const globTasks = generateGlobTasks(patterns, options); + for (let item of items) { + if (!matches.includes(item)) { + result.add(item); + } + } + return [...result]; +}; - const tasks = globTasks.reduce((tasks, task) => { - const newTask = getPattern(task, dirGlob.sync).map(globToTask(task)); - return tasks.concat(newTask); - }, []); +/** + * Returns true if the given `string` contains the given pattern. Similar + * to [.isMatch](#isMatch) but the pattern can match any part of the string. + * + * ```js + * var mm = require('micromatch'); + * // mm.contains(string, pattern[, options]); + * + * console.log(mm.contains('aa/bb/cc', '*b')); + * //=> true + * console.log(mm.contains('aa/bb/cc', '*d')); + * //=> false + * ``` + * @param {String} `str` The string to match. + * @param {String|Array} `patterns` Glob pattern to use for matching. + * @param {Object} `options` See available [options](#options) for changing how matches are performed + * @return {Boolean} Returns true if the patter matches any part of `str`. + * @api public + */ - const filter = getFilterSync(options); - const filterStream = new FilterStream(p => !filter(p)); - const uniqueStream = new UniqueStream(); +micromatch.contains = (str, pattern, options) => { + if (typeof str !== 'string') { + throw new TypeError(`Expected a string: "${util.inspect(str)}"`); + } - return merge2(tasks.map(task => fastGlob.stream(task.pattern, task.options))) - .pipe(filterStream) - .pipe(uniqueStream); -}; + if (Array.isArray(pattern)) { + return pattern.some(p => micromatch.contains(str, p, options)); + } -module.exports.generateGlobTasks = generateGlobTasks; + if (typeof pattern === 'string') { + if (isEmptyString(str) || isEmptyString(pattern)) { + return false; + } -module.exports.hasMagic = (patterns, options) => [] - .concat(patterns) - .some(pattern => glob.hasMagic(pattern, options)); + if (str.includes(pattern) || (str.startsWith('./') && str.slice(2).includes(pattern))) { + return true; + } + } -module.exports.gitignore = gitignore; + return micromatch.isMatch(str, pattern, { ...options, contains: true }); +}; +/** + * Filter the keys of the given object with the given `glob` pattern + * and `options`. Does not attempt to match nested keys. If you need this feature, + * use [glob-object][] instead. + * + * ```js + * const mm = require('micromatch'); + * // mm.matchKeys(object, patterns[, options]); + * + * const obj = { aa: 'a', ab: 'b', ac: 'c' }; + * console.log(mm.matchKeys(obj, '*b')); + * //=> { ab: 'b' } + * ``` + * @param {Object} `object` The object with keys to filter. + * @param {String|Array} `patterns` One or more glob patterns to use for matching. + * @param {Object} `options` See available [options](#options) for changing how matches are performed + * @return {Object} Returns an object with only keys that match the given patterns. + * @api public + */ -/***/ }), -/* 298 */ -/***/ (function(module, exports, __webpack_require__) { +micromatch.matchKeys = (obj, patterns, options) => { + if (!utils.isObject(obj)) { + throw new TypeError('Expected the first argument to be an object'); + } + let keys = micromatch(Object.keys(obj), patterns, options); + let res = {}; + for (let key of keys) res[key] = obj[key]; + return res; +}; -"use strict"; +/** + * Returns true if some of the strings in the given `list` match any of the given glob `patterns`. + * + * ```js + * const mm = require('micromatch'); + * // mm.some(list, patterns[, options]); + * + * console.log(mm.some(['foo.js', 'bar.js'], ['*.js', '!foo.js'])); + * // true + * console.log(mm.some(['foo.js'], ['*.js', '!foo.js'])); + * // false + * ``` + * @param {String|Array} `list` The string or array of strings to test. Returns as soon as the first match is found. + * @param {String|Array} `patterns` One or more glob patterns to use for matching. + * @param {Object} `options` See available [options](#options) for changing how matches are performed + * @return {Boolean} Returns true if any patterns match `str` + * @api public + */ +micromatch.some = (list, patterns, options) => { + let items = [].concat(list); -module.exports = (...arguments_) => { - return [...new Set([].concat(...arguments_))]; + for (let pattern of [].concat(patterns)) { + let isMatch = picomatch(String(pattern), options); + if (items.some(item => isMatch(item))) { + return true; + } + } + return false; }; +/** + * Returns true if every string in the given `list` matches + * any of the given glob `patterns`. + * + * ```js + * const mm = require('micromatch'); + * // mm.every(list, patterns[, options]); + * + * console.log(mm.every('foo.js', ['foo.js'])); + * // true + * console.log(mm.every(['foo.js', 'bar.js'], ['*.js'])); + * // true + * console.log(mm.every(['foo.js', 'bar.js'], ['*.js', '!foo.js'])); + * // false + * console.log(mm.every(['foo.js'], ['*.js', '!foo.js'])); + * // false + * ``` + * @param {String|Array} `list` The string or array of strings to test. + * @param {String|Array} `patterns` One or more glob patterns to use for matching. + * @param {Object} `options` See available [options](#options) for changing how matches are performed + * @return {Boolean} Returns true if any patterns match `str` + * @api public + */ -/***/ }), -/* 299 */ -/***/ (function(module, exports, __webpack_require__) { +micromatch.every = (list, patterns, options) => { + let items = [].concat(list); -"use strict"; + for (let pattern of [].concat(patterns)) { + let isMatch = picomatch(String(pattern), options); + if (!items.every(item => isMatch(item))) { + return false; + } + } + return true; +}; -/* - * merge2 - * https://github.com/teambition/merge2 +/** + * Returns true if **all** of the given `patterns` match + * the specified string. * - * Copyright (c) 2014-2020 Teambition - * Licensed under the MIT license. + * ```js + * const mm = require('micromatch'); + * // mm.all(string, patterns[, options]); + * + * console.log(mm.all('foo.js', ['foo.js'])); + * // true + * + * console.log(mm.all('foo.js', ['*.js', '!foo.js'])); + * // false + * + * console.log(mm.all('foo.js', ['*.js', 'foo.js'])); + * // true + * + * console.log(mm.all('foo.js', ['*.js', 'f*', '*o*', '*o.js'])); + * // true + * ``` + * @param {String|Array} `str` The string to test. + * @param {String|Array} `patterns` One or more glob patterns to use for matching. + * @param {Object} `options` See available [options](#options) for changing how matches are performed + * @return {Boolean} Returns true if any patterns match `str` + * @api public */ -const Stream = __webpack_require__(137) -const PassThrough = Stream.PassThrough -const slice = Array.prototype.slice -module.exports = merge2 +micromatch.all = (str, patterns, options) => { + if (typeof str !== 'string') { + throw new TypeError(`Expected a string: "${util.inspect(str)}"`); + } -function merge2 () { - const streamsQueue = [] - const args = slice.call(arguments) - let merging = false - let options = args[args.length - 1] + return [].concat(patterns).every(p => picomatch(p, options)(str)); +}; - if (options && !Array.isArray(options) && options.pipe == null) { - args.pop() - } else { - options = {} - } +/** + * Returns an array of matches captured by `pattern` in `string, or `null` if the pattern did not match. + * + * ```js + * const mm = require('micromatch'); + * // mm.capture(pattern, string[, options]); + * + * console.log(mm.capture('test/*.js', 'test/foo.js')); + * //=> ['foo'] + * console.log(mm.capture('test/*.js', 'foo/bar.css')); + * //=> null + * ``` + * @param {String} `glob` Glob pattern to use for matching. + * @param {String} `input` String to match + * @param {Object} `options` See available [options](#options) for changing how matches are performed + * @return {Boolean} Returns an array of captures if the input matches the glob pattern, otherwise `null`. + * @api public + */ - const doEnd = options.end !== false - const doPipeError = options.pipeError === true - if (options.objectMode == null) { - options.objectMode = true - } - if (options.highWaterMark == null) { - options.highWaterMark = 64 * 1024 - } - const mergedStream = PassThrough(options) +micromatch.capture = (glob, input, options) => { + let posix = utils.isWindows(options); + let regex = picomatch.makeRe(String(glob), { ...options, capture: true }); + let match = regex.exec(posix ? utils.toPosixSlashes(input) : input); - function addStream () { - for (let i = 0, len = arguments.length; i < len; i++) { - streamsQueue.push(pauseStreams(arguments[i], options)) - } - mergeStream() - return this + if (match) { + return match.slice(1).map(v => v === void 0 ? '' : v); } +}; - function mergeStream () { - if (merging) { - return - } - merging = true +/** + * Create a regular expression from the given glob `pattern`. + * + * ```js + * const mm = require('micromatch'); + * // mm.makeRe(pattern[, options]); + * + * console.log(mm.makeRe('*.js')); + * //=> /^(?:(\.[\\\/])?(?!\.)(?=.)[^\/]*?\.js)$/ + * ``` + * @param {String} `pattern` A glob pattern to convert to regex. + * @param {Object} `options` + * @return {RegExp} Returns a regex created from the given pattern. + * @api public + */ - let streams = streamsQueue.shift() - if (!streams) { - process.nextTick(endStream) - return - } - if (!Array.isArray(streams)) { - streams = [streams] - } +micromatch.makeRe = (...args) => picomatch.makeRe(...args); - let pipesCount = streams.length + 1 +/** + * Scan a glob pattern to separate the pattern into segments. Used + * by the [split](#split) method. + * + * ```js + * const mm = require('micromatch'); + * const state = mm.scan(pattern[, options]); + * ``` + * @param {String} `pattern` + * @param {Object} `options` + * @return {Object} Returns an object with + * @api public + */ - function next () { - if (--pipesCount > 0) { - return - } - merging = false - mergeStream() +micromatch.scan = (...args) => picomatch.scan(...args); + +/** + * Parse a glob pattern to create the source string for a regular + * expression. + * + * ```js + * const mm = require('micromatch'); + * const state = mm(pattern[, options]); + * ``` + * @param {String} `glob` + * @param {Object} `options` + * @return {Object} Returns an object with useful properties and output to be used as regex source string. + * @api public + */ + +micromatch.parse = (patterns, options) => { + let res = []; + for (let pattern of [].concat(patterns || [])) { + for (let str of braces(String(pattern), options)) { + res.push(picomatch.parse(str, options)); } + } + return res; +}; - function pipe (stream) { - function onend () { - stream.removeListener('merge2UnpipeEnd', onend) - stream.removeListener('end', onend) - if (doPipeError) { - stream.removeListener('error', onerror) - } - next() - } - function onerror (err) { - mergedStream.emit('error', err) - } - // skip ended stream - if (stream._readableState.endEmitted) { - return next() - } +/** + * Process the given brace `pattern`. + * + * ```js + * const { braces } = require('micromatch'); + * console.log(braces('foo/{a,b,c}/bar')); + * //=> [ 'foo/(a|b|c)/bar' ] + * + * console.log(braces('foo/{a,b,c}/bar', { expand: true })); + * //=> [ 'foo/a/bar', 'foo/b/bar', 'foo/c/bar' ] + * ``` + * @param {String} `pattern` String with brace pattern to process. + * @param {Object} `options` Any [options](#options) to change how expansion is performed. See the [braces][] library for all available options. + * @return {Array} + * @api public + */ - stream.on('merge2UnpipeEnd', onend) - stream.on('end', onend) +micromatch.braces = (pattern, options) => { + if (typeof pattern !== 'string') throw new TypeError('Expected a string'); + if ((options && options.nobrace === true) || !/\{.*\}/.test(pattern)) { + return [pattern]; + } + return braces(pattern, options); +}; - if (doPipeError) { - stream.on('error', onerror) - } +/** + * Expand braces + */ - stream.pipe(mergedStream, { end: false }) - // compatible for old stream - stream.resume() - } +micromatch.braceExpand = (pattern, options) => { + if (typeof pattern !== 'string') throw new TypeError('Expected a string'); + return micromatch.braces(pattern, { ...options, expand: true }); +}; - for (let i = 0; i < streams.length; i++) { - pipe(streams[i]) - } +/** + * Expose micromatch + */ - next() - } +module.exports = micromatch; - function endStream () { - merging = false - // emit 'queueDrain' when all streams merged. - mergedStream.emit('queueDrain') - if (doEnd) { - mergedStream.end() - } - } - mergedStream.setMaxListeners(0) - mergedStream.add = addStream - mergedStream.on('unpipe', function (stream) { - stream.emit('merge2UnpipeEnd') - }) +/***/ }), +/* 304 */ +/***/ (function(module, exports, __webpack_require__) { - if (args.length) { - addStream.apply(null, args) - } - return mergedStream -} +"use strict"; -// check and pause streams for pipe. -function pauseStreams (streams, options) { - if (!Array.isArray(streams)) { - // Backwards-compat with old-style streams - if (!streams._readableState && streams.pipe) { - streams = streams.pipe(PassThrough(options)) - } - if (!streams._readableState || !streams.pause || !streams.pipe) { - throw new Error('Only readable stream can be merged.') + +const stringify = __webpack_require__(305); +const compile = __webpack_require__(307); +const expand = __webpack_require__(311); +const parse = __webpack_require__(312); + +/** + * Expand the given pattern or create a regex-compatible string. + * + * ```js + * const braces = require('braces'); + * console.log(braces('{a,b,c}', { compile: true })); //=> ['(a|b|c)'] + * console.log(braces('{a,b,c}')); //=> ['a', 'b', 'c'] + * ``` + * @param {String} `str` + * @param {Object} `options` + * @return {String} + * @api public + */ + +const braces = (input, options = {}) => { + let output = []; + + if (Array.isArray(input)) { + for (let pattern of input) { + let result = braces.create(pattern, options); + if (Array.isArray(result)) { + output.push(...result); + } else { + output.push(result); + } } - streams.pause() } else { - for (let i = 0, len = streams.length; i < len; i++) { - streams[i] = pauseStreams(streams[i], options) - } + output = [].concat(braces.create(input, options)); } - return streams -} + if (options && options.expand === true && options.nodupes === true) { + output = [...new Set(output)]; + } + return output; +}; -/***/ }), -/* 300 */ -/***/ (function(module, exports, __webpack_require__) { +/** + * Parse the given `str` with the given `options`. + * + * ```js + * // braces.parse(pattern, [, options]); + * const ast = braces.parse('a/{b,c}/d'); + * console.log(ast); + * ``` + * @param {String} pattern Brace pattern to parse + * @param {Object} options + * @return {Object} Returns an AST + * @api public + */ -"use strict"; - -const taskManager = __webpack_require__(301); -const async_1 = __webpack_require__(330); -const stream_1 = __webpack_require__(365); -const sync_1 = __webpack_require__(366); -const settings_1 = __webpack_require__(368); -const utils = __webpack_require__(302); -async function FastGlob(source, options) { - assertPatternsInput(source); - const works = getWorks(source, async_1.default, options); - const result = await Promise.all(works); - return utils.array.flatten(result); -} -// https://github.com/typescript-eslint/typescript-eslint/issues/60 -// eslint-disable-next-line no-redeclare -(function (FastGlob) { - function sync(source, options) { - assertPatternsInput(source); - const works = getWorks(source, sync_1.default, options); - return utils.array.flatten(works); - } - FastGlob.sync = sync; - function stream(source, options) { - assertPatternsInput(source); - const works = getWorks(source, stream_1.default, options); - /** - * The stream returned by the provider cannot work with an asynchronous iterator. - * To support asynchronous iterators, regardless of the number of tasks, we always multiplex streams. - * This affects performance (+25%). I don't see best solution right now. - */ - return utils.stream.merge(works); - } - FastGlob.stream = stream; - function generateTasks(source, options) { - assertPatternsInput(source); - const patterns = [].concat(source); - const settings = new settings_1.default(options); - return taskManager.generate(patterns, settings); - } - FastGlob.generateTasks = generateTasks; - function isDynamicPattern(source, options) { - assertPatternsInput(source); - const settings = new settings_1.default(options); - return utils.pattern.isDynamicPattern(source, settings); - } - FastGlob.isDynamicPattern = isDynamicPattern; - function escapePath(source) { - assertPatternsInput(source); - return utils.path.escape(source); - } - FastGlob.escapePath = escapePath; -})(FastGlob || (FastGlob = {})); -function getWorks(source, _Provider, options) { - const patterns = [].concat(source); - const settings = new settings_1.default(options); - const tasks = taskManager.generate(patterns, settings); - const provider = new _Provider(settings); - return tasks.map(provider.read, provider); -} -function assertPatternsInput(input) { - const source = [].concat(input); - const isValidSource = source.every((item) => utils.string.isString(item) && !utils.string.isEmpty(item)); - if (!isValidSource) { - throw new TypeError('Patterns must be a string (non empty) or an array of strings'); - } -} -module.exports = FastGlob; +braces.parse = (input, options = {}) => parse(input, options); +/** + * Creates a braces string from an AST, or an AST node. + * + * ```js + * const braces = require('braces'); + * let ast = braces.parse('foo/{a,b}/bar'); + * console.log(stringify(ast.nodes[2])); //=> '{a,b}' + * ``` + * @param {String} `input` Brace pattern or AST. + * @param {Object} `options` + * @return {Array} Returns an array of expanded values. + * @api public + */ -/***/ }), -/* 301 */ -/***/ (function(module, exports, __webpack_require__) { +braces.stringify = (input, options = {}) => { + if (typeof input === 'string') { + return stringify(braces.parse(input, options), options); + } + return stringify(input, options); +}; -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const utils = __webpack_require__(302); -function generate(patterns, settings) { - const positivePatterns = getPositivePatterns(patterns); - const negativePatterns = getNegativePatternsAsPositive(patterns, settings.ignore); - const staticPatterns = positivePatterns.filter((pattern) => utils.pattern.isStaticPattern(pattern, settings)); - const dynamicPatterns = positivePatterns.filter((pattern) => utils.pattern.isDynamicPattern(pattern, settings)); - const staticTasks = convertPatternsToTasks(staticPatterns, negativePatterns, /* dynamic */ false); - const dynamicTasks = convertPatternsToTasks(dynamicPatterns, negativePatterns, /* dynamic */ true); - return staticTasks.concat(dynamicTasks); -} -exports.generate = generate; -function convertPatternsToTasks(positive, negative, dynamic) { - const positivePatternsGroup = groupPatternsByBaseDirectory(positive); - // When we have a global group – there is no reason to divide the patterns into independent tasks. - // In this case, the global task covers the rest. - if ('.' in positivePatternsGroup) { - const task = convertPatternGroupToTask('.', positive, negative, dynamic); - return [task]; - } - return convertPatternGroupsToTasks(positivePatternsGroup, negative, dynamic); -} -exports.convertPatternsToTasks = convertPatternsToTasks; -function getPositivePatterns(patterns) { - return utils.pattern.getPositivePatterns(patterns); -} -exports.getPositivePatterns = getPositivePatterns; -function getNegativePatternsAsPositive(patterns, ignore) { - const negative = utils.pattern.getNegativePatterns(patterns).concat(ignore); - const positive = negative.map(utils.pattern.convertToPositivePattern); - return positive; -} -exports.getNegativePatternsAsPositive = getNegativePatternsAsPositive; -function groupPatternsByBaseDirectory(patterns) { - const group = {}; - return patterns.reduce((collection, pattern) => { - const base = utils.pattern.getBaseDirectory(pattern); - if (base in collection) { - collection[base].push(pattern); - } - else { - collection[base] = [pattern]; - } - return collection; - }, group); -} -exports.groupPatternsByBaseDirectory = groupPatternsByBaseDirectory; -function convertPatternGroupsToTasks(positive, negative, dynamic) { - return Object.keys(positive).map((base) => { - return convertPatternGroupToTask(base, positive[base], negative, dynamic); - }); -} -exports.convertPatternGroupsToTasks = convertPatternGroupsToTasks; -function convertPatternGroupToTask(base, positive, negative, dynamic) { - return { - dynamic, - positive, - negative, - base, - patterns: [].concat(positive, negative.map(utils.pattern.convertToNegativePattern)) - }; -} -exports.convertPatternGroupToTask = convertPatternGroupToTask; +/** + * Compiles a brace pattern into a regex-compatible, optimized string. + * This method is called by the main [braces](#braces) function by default. + * + * ```js + * const braces = require('braces'); + * console.log(braces.compile('a/{b,c}/d')); + * //=> ['a/(b|c)/d'] + * ``` + * @param {String} `input` Brace pattern or AST. + * @param {Object} `options` + * @return {Array} Returns an array of expanded values. + * @api public + */ +braces.compile = (input, options = {}) => { + if (typeof input === 'string') { + input = braces.parse(input, options); + } + return compile(input, options); +}; -/***/ }), -/* 302 */ -/***/ (function(module, exports, __webpack_require__) { +/** + * Expands a brace pattern into an array. This method is called by the + * main [braces](#braces) function when `options.expand` is true. Before + * using this method it's recommended that you read the [performance notes](#performance)) + * and advantages of using [.compile](#compile) instead. + * + * ```js + * const braces = require('braces'); + * console.log(braces.expand('a/{b,c}/d')); + * //=> ['a/b/d', 'a/c/d']; + * ``` + * @param {String} `pattern` Brace pattern + * @param {Object} `options` + * @return {Array} Returns an array of expanded values. + * @api public + */ -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const array = __webpack_require__(303); -exports.array = array; -const errno = __webpack_require__(304); -exports.errno = errno; -const fs = __webpack_require__(305); -exports.fs = fs; -const path = __webpack_require__(306); -exports.path = path; -const pattern = __webpack_require__(307); -exports.pattern = pattern; -const stream = __webpack_require__(328); -exports.stream = stream; -const string = __webpack_require__(329); -exports.string = string; +braces.expand = (input, options = {}) => { + if (typeof input === 'string') { + input = braces.parse(input, options); + } + let result = expand(input, options); -/***/ }), -/* 303 */ -/***/ (function(module, exports, __webpack_require__) { + // filter out empty strings if specified + if (options.noempty === true) { + result = result.filter(Boolean); + } -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -function flatten(items) { - return items.reduce((collection, item) => [].concat(collection, item), []); -} -exports.flatten = flatten; -function splitWhen(items, predicate) { - const result = [[]]; - let groupIndex = 0; - for (const item of items) { - if (predicate(item)) { - groupIndex++; - result[groupIndex] = []; - } - else { - result[groupIndex].push(item); - } - } - return result; -} -exports.splitWhen = splitWhen; + // filter out duplicates if specified + if (options.nodupes === true) { + result = [...new Set(result)]; + } + return result; +}; -/***/ }), -/* 304 */ -/***/ (function(module, exports, __webpack_require__) { +/** + * Processes a brace pattern and returns either an expanded array + * (if `options.expand` is true), a highly optimized regex-compatible string. + * This method is called by the main [braces](#braces) function. + * + * ```js + * const braces = require('braces'); + * console.log(braces.create('user-{200..300}/project-{a,b,c}-{1..10}')) + * //=> 'user-(20[0-9]|2[1-9][0-9]|300)/project-(a|b|c)-([1-9]|10)' + * ``` + * @param {String} `pattern` Brace pattern + * @param {Object} `options` + * @return {Array} Returns an array of expanded values. + * @api public + */ -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -function isEnoentCodeError(error) { - return error.code === 'ENOENT'; -} -exports.isEnoentCodeError = isEnoentCodeError; +braces.create = (input, options = {}) => { + if (input === '' || input.length < 3) { + return [input]; + } + + return options.expand !== true + ? braces.compile(input, options) + : braces.expand(input, options); +}; + +/** + * Expose "braces" + */ + +module.exports = braces; /***/ }), @@ -41854,6159 +41298,6203 @@ exports.isEnoentCodeError = isEnoentCodeError; /***/ (function(module, exports, __webpack_require__) { "use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -class DirentFromStats { - constructor(name, stats) { - this.name = name; - this.isBlockDevice = stats.isBlockDevice.bind(stats); - this.isCharacterDevice = stats.isCharacterDevice.bind(stats); - this.isDirectory = stats.isDirectory.bind(stats); - this.isFIFO = stats.isFIFO.bind(stats); - this.isFile = stats.isFile.bind(stats); - this.isSocket = stats.isSocket.bind(stats); - this.isSymbolicLink = stats.isSymbolicLink.bind(stats); - } -} -function createDirentFromStats(name, stats) { - return new DirentFromStats(name, stats); -} -exports.createDirentFromStats = createDirentFromStats; -/***/ }), -/* 306 */ -/***/ (function(module, exports, __webpack_require__) { +const utils = __webpack_require__(306); -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const path = __webpack_require__(4); -const LEADING_DOT_SEGMENT_CHARACTERS_COUNT = 2; // ./ or .\\ -const UNESCAPED_GLOB_SYMBOLS_RE = /(\\?)([()*?[\]{|}]|^!|[!+@](?=\())/g; -/** - * Designed to work only with simple paths: `dir\\file`. - */ -function unixify(filepath) { - return filepath.replace(/\\/g, '/'); -} -exports.unixify = unixify; -function makeAbsolute(cwd, filepath) { - return path.resolve(cwd, filepath); -} -exports.makeAbsolute = makeAbsolute; -function escape(pattern) { - return pattern.replace(UNESCAPED_GLOB_SYMBOLS_RE, '\\$2'); -} -exports.escape = escape; -function removeLeadingDotSegment(entry) { - // We do not use `startsWith` because this is 10x slower than current implementation for some cases. - // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with - if (entry.charAt(0) === '.') { - const secondCharactery = entry.charAt(1); - if (secondCharactery === '/' || secondCharactery === '\\') { - return entry.slice(LEADING_DOT_SEGMENT_CHARACTERS_COUNT); - } - } - return entry; -} -exports.removeLeadingDotSegment = removeLeadingDotSegment; +module.exports = (ast, options = {}) => { + let stringify = (node, parent = {}) => { + let invalidBlock = options.escapeInvalid && utils.isInvalidBrace(parent); + let invalidNode = node.invalid === true && options.escapeInvalid === true; + let output = ''; + if (node.value) { + if ((invalidBlock || invalidNode) && utils.isOpenOrClose(node)) { + return '\\' + node.value; + } + return node.value; + } -/***/ }), -/* 307 */ -/***/ (function(module, exports, __webpack_require__) { + if (node.value) { + return node.value; + } + + if (node.nodes) { + for (let child of node.nodes) { + output += stringify(child); + } + } + return output; + }; + + return stringify(ast); +}; -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const path = __webpack_require__(4); -const globParent = __webpack_require__(308); -const micromatch = __webpack_require__(311); -const picomatch = __webpack_require__(322); -const GLOBSTAR = '**'; -const ESCAPE_SYMBOL = '\\'; -const COMMON_GLOB_SYMBOLS_RE = /[*?]|^!/; -const REGEX_CHARACTER_CLASS_SYMBOLS_RE = /\[.*]/; -const REGEX_GROUP_SYMBOLS_RE = /(?:^|[^!*+?@])\(.*\|.*\)/; -const GLOB_EXTENSION_SYMBOLS_RE = /[!*+?@]\(.*\)/; -const BRACE_EXPANSIONS_SYMBOLS_RE = /{.*(?:,|\.\.).*}/; -function isStaticPattern(pattern, options = {}) { - return !isDynamicPattern(pattern, options); -} -exports.isStaticPattern = isStaticPattern; -function isDynamicPattern(pattern, options = {}) { - /** - * When the `caseSensitiveMatch` option is disabled, all patterns must be marked as dynamic, because we cannot check - * filepath directly (without read directory). - */ - if (options.caseSensitiveMatch === false || pattern.includes(ESCAPE_SYMBOL)) { - return true; - } - if (COMMON_GLOB_SYMBOLS_RE.test(pattern) || REGEX_CHARACTER_CLASS_SYMBOLS_RE.test(pattern) || REGEX_GROUP_SYMBOLS_RE.test(pattern)) { - return true; - } - if (options.extglob !== false && GLOB_EXTENSION_SYMBOLS_RE.test(pattern)) { - return true; - } - if (options.braceExpansion !== false && BRACE_EXPANSIONS_SYMBOLS_RE.test(pattern)) { - return true; - } - return false; -} -exports.isDynamicPattern = isDynamicPattern; -function convertToPositivePattern(pattern) { - return isNegativePattern(pattern) ? pattern.slice(1) : pattern; -} -exports.convertToPositivePattern = convertToPositivePattern; -function convertToNegativePattern(pattern) { - return '!' + pattern; -} -exports.convertToNegativePattern = convertToNegativePattern; -function isNegativePattern(pattern) { - return pattern.startsWith('!') && pattern[1] !== '('; -} -exports.isNegativePattern = isNegativePattern; -function isPositivePattern(pattern) { - return !isNegativePattern(pattern); -} -exports.isPositivePattern = isPositivePattern; -function getNegativePatterns(patterns) { - return patterns.filter(isNegativePattern); -} -exports.getNegativePatterns = getNegativePatterns; -function getPositivePatterns(patterns) { - return patterns.filter(isPositivePattern); -} -exports.getPositivePatterns = getPositivePatterns; -function getBaseDirectory(pattern) { - return globParent(pattern, { flipBackslashes: false }); -} -exports.getBaseDirectory = getBaseDirectory; -function hasGlobStar(pattern) { - return pattern.includes(GLOBSTAR); -} -exports.hasGlobStar = hasGlobStar; -function endsWithSlashGlobStar(pattern) { - return pattern.endsWith('/' + GLOBSTAR); -} -exports.endsWithSlashGlobStar = endsWithSlashGlobStar; -function isAffectDepthOfReadingPattern(pattern) { - const basename = path.basename(pattern); - return endsWithSlashGlobStar(pattern) || isStaticPattern(basename); -} -exports.isAffectDepthOfReadingPattern = isAffectDepthOfReadingPattern; -function expandPatternsWithBraceExpansion(patterns) { - return patterns.reduce((collection, pattern) => { - return collection.concat(expandBraceExpansion(pattern)); - }, []); -} -exports.expandPatternsWithBraceExpansion = expandPatternsWithBraceExpansion; -function expandBraceExpansion(pattern) { - return micromatch.braces(pattern, { - expand: true, - nodupes: true - }); -} -exports.expandBraceExpansion = expandBraceExpansion; -function getPatternParts(pattern, options) { - const info = picomatch.scan(pattern, Object.assign(Object.assign({}, options), { parts: true })); - // See micromatch/picomatch#58 for more details - if (info.parts.length === 0) { - return [pattern]; - } - return info.parts; -} -exports.getPatternParts = getPatternParts; -function makeRe(pattern, options) { - return micromatch.makeRe(pattern, options); -} -exports.makeRe = makeRe; -function convertPatternsToRe(patterns, options) { - return patterns.map((pattern) => makeRe(pattern, options)); -} -exports.convertPatternsToRe = convertPatternsToRe; -function matchAny(entry, patternsRe) { - return patternsRe.some((patternRe) => patternRe.test(entry)); -} -exports.matchAny = matchAny; /***/ }), -/* 308 */ +/* 306 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isGlob = __webpack_require__(309); -var pathPosixDirname = __webpack_require__(4).posix.dirname; -var isWin32 = __webpack_require__(120).platform() === 'win32'; - -var slash = '/'; -var backslash = /\\/g; -var enclosure = /[\{\[].*[\/]*.*[\}\]]$/; -var globby = /(^|[^\\])([\{\[]|\([^\)]+$)/; -var escaped = /\\([\!\*\?\|\[\]\(\)\{\}])/g; +exports.isInteger = num => { + if (typeof num === 'number') { + return Number.isInteger(num); + } + if (typeof num === 'string' && num.trim() !== '') { + return Number.isInteger(Number(num)); + } + return false; +}; /** - * @param {string} str - * @param {Object} opts - * @param {boolean} [opts.flipBackslashes=true] + * Find a node of the given type */ -module.exports = function globParent(str, opts) { - var options = Object.assign({ flipBackslashes: true }, opts); - - // flip windows path separators - if (options.flipBackslashes && isWin32 && str.indexOf(slash) < 0) { - str = str.replace(backslash, slash); - } - - // special case for strings ending in enclosure containing path separator - if (enclosure.test(str)) { - str += slash; - } - // preserves full path in case of trailing path separator - str += 'a'; +exports.find = (node, type) => node.nodes.find(node => node.type === type); - // remove path parts that are globby - do { - str = pathPosixDirname(str); - } while (isGlob(str) || globby.test(str)); +/** + * Find a node of the given type + */ - // remove escape chars and return result - return str.replace(escaped, '$1'); +exports.exceedsLimit = (min, max, step = 1, limit) => { + if (limit === false) return false; + if (!exports.isInteger(min) || !exports.isInteger(max)) return false; + return ((Number(max) - Number(min)) / Number(step)) >= limit; }; - -/***/ }), -/* 309 */ -/***/ (function(module, exports, __webpack_require__) { - -/*! - * is-glob - * - * Copyright (c) 2014-2017, Jon Schlinkert. - * Released under the MIT License. +/** + * Escape the given node with '\\' before node.value */ -var isExtglob = __webpack_require__(310); -var chars = { '{': '}', '(': ')', '[': ']'}; -var strictRegex = /\\(.)|(^!|\*|[\].+)]\?|\[[^\\\]]+\]|\{[^\\}]+\}|\(\?[:!=][^\\)]+\)|\([^|]+\|[^\\)]+\))/; -var relaxedRegex = /\\(.)|(^!|[*?{}()[\]]|\(\?)/; +exports.escapeNode = (block, n = 0, type) => { + let node = block.nodes[n]; + if (!node) return; -module.exports = function isGlob(str, options) { - if (typeof str !== 'string' || str === '') { - return false; + if ((type && node.type === type) || node.type === 'open' || node.type === 'close') { + if (node.escaped !== true) { + node.value = '\\' + node.value; + node.escaped = true; + } } +}; - if (isExtglob(str)) { +/** + * Returns true if the given brace node should be enclosed in literal braces + */ + +exports.encloseBrace = node => { + if (node.type !== 'brace') return false; + if ((node.commas >> 0 + node.ranges >> 0) === 0) { + node.invalid = true; return true; } + return false; +}; - var regex = strictRegex; - var match; +/** + * Returns true if a brace node is invalid. + */ - // optionally relax regex - if (options && options.strict === false) { - regex = relaxedRegex; +exports.isInvalidBrace = block => { + if (block.type !== 'brace') return false; + if (block.invalid === true || block.dollar) return true; + if ((block.commas >> 0 + block.ranges >> 0) === 0) { + block.invalid = true; + return true; } - - while ((match = regex.exec(str))) { - if (match[2]) return true; - var idx = match.index + match[0].length; - - // if an open bracket/brace/paren is escaped, - // set the index to the next closing character - var open = match[1]; - var close = open ? chars[open] : null; - if (open && close) { - var n = str.indexOf(close, idx); - if (n !== -1) { - idx = n + 1; - } - } - - str = str.slice(idx); + if (block.open !== true || block.close !== true) { + block.invalid = true; + return true; } return false; }; +/** + * Returns true if a node is an open or close node + */ -/***/ }), -/* 310 */ -/***/ (function(module, exports) { +exports.isOpenOrClose = node => { + if (node.type === 'open' || node.type === 'close') { + return true; + } + return node.open === true || node.close === true; +}; -/*! - * is-extglob - * - * Copyright (c) 2014-2016, Jon Schlinkert. - * Licensed under the MIT License. +/** + * Reduce an array of text nodes. */ -module.exports = function isExtglob(str) { - if (typeof str !== 'string' || str === '') { - return false; - } +exports.reduce = nodes => nodes.reduce((acc, node) => { + if (node.type === 'text') acc.push(node.value); + if (node.type === 'range') node.type = 'text'; + return acc; +}, []); - var match; - while ((match = /(\\).|([@?!+*]\(.*\))/g.exec(str))) { - if (match[2]) return true; - str = str.slice(match.index + match[0].length); - } +/** + * Flatten an array + */ - return false; +exports.flatten = (...args) => { + const result = []; + const flat = arr => { + for (let i = 0; i < arr.length; i++) { + let ele = arr[i]; + Array.isArray(ele) ? flat(ele, result) : ele !== void 0 && result.push(ele); + } + return result; + }; + flat(args); + return result; }; /***/ }), -/* 311 */ +/* 307 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const util = __webpack_require__(111); -const braces = __webpack_require__(312); -const picomatch = __webpack_require__(322); -const utils = __webpack_require__(325); -const isEmptyString = val => typeof val === 'string' && (val === '' || val === './'); - -/** - * Returns an array of strings that match one or more glob patterns. - * - * ```js - * const mm = require('micromatch'); - * // mm(list, patterns[, options]); - * - * console.log(mm(['a.js', 'a.txt'], ['*.js'])); - * //=> [ 'a.js' ] - * ``` - * @param {String|Array} list List of strings to match. - * @param {String|Array} patterns One or more glob patterns to use for matching. - * @param {Object} options See available [options](#options) - * @return {Array} Returns an array of matches - * @summary false - * @api public - */ - -const micromatch = (list, patterns, options) => { - patterns = [].concat(patterns); - list = [].concat(list); +const fill = __webpack_require__(308); +const utils = __webpack_require__(306); - let omit = new Set(); - let keep = new Set(); - let items = new Set(); - let negatives = 0; +const compile = (ast, options = {}) => { + let walk = (node, parent = {}) => { + let invalidBlock = utils.isInvalidBrace(parent); + let invalidNode = node.invalid === true && options.escapeInvalid === true; + let invalid = invalidBlock === true || invalidNode === true; + let prefix = options.escapeInvalid === true ? '\\' : ''; + let output = ''; - let onResult = state => { - items.add(state.output); - if (options && options.onResult) { - options.onResult(state); + if (node.isOpen === true) { + return prefix + node.value; + } + if (node.isClose === true) { + return prefix + node.value; } - }; - for (let i = 0; i < patterns.length; i++) { - let isMatch = picomatch(String(patterns[i]), { ...options, onResult }, true); - let negated = isMatch.state.negated || isMatch.state.negatedExtglob; - if (negated) negatives++; + if (node.type === 'open') { + return invalid ? (prefix + node.value) : '('; + } - for (let item of list) { - let matched = isMatch(item, true); + if (node.type === 'close') { + return invalid ? (prefix + node.value) : ')'; + } - let match = negated ? !matched.isMatch : matched.isMatch; - if (!match) continue; + if (node.type === 'comma') { + return node.prev.type === 'comma' ? '' : (invalid ? node.value : '|'); + } - if (negated) { - omit.add(matched.output); - } else { - omit.delete(matched.output); - keep.add(matched.output); - } + if (node.value) { + return node.value; } - } - let result = negatives === patterns.length ? [...items] : [...keep]; - let matches = result.filter(item => !omit.has(item)); + if (node.nodes && node.ranges > 0) { + let args = utils.reduce(node.nodes); + let range = fill(...args, { ...options, wrap: false, toRegex: true }); - if (options && matches.length === 0) { - if (options.failglob === true) { - throw new Error(`No matches found for "${patterns.join(', ')}"`); + if (range.length !== 0) { + return args.length > 1 && range.length > 1 ? `(${range})` : range; + } } - if (options.nonull === true || options.nullglob === true) { - return options.unescape ? patterns.map(p => p.replace(/\\/g, '')) : patterns; + if (node.nodes) { + for (let child of node.nodes) { + output += walk(child, node); + } } - } + return output; + }; - return matches; + return walk(ast); }; -/** - * Backwards compatibility - */ +module.exports = compile; -micromatch.match = micromatch; -/** - * Returns a matcher function from the given glob `pattern` and `options`. - * The returned function takes a string to match as its only argument and returns - * true if the string is a match. - * - * ```js - * const mm = require('micromatch'); - * // mm.matcher(pattern[, options]); +/***/ }), +/* 308 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/*! + * fill-range * - * const isMatch = mm.matcher('*.!(*a)'); - * console.log(isMatch('a.a')); //=> false - * console.log(isMatch('a.b')); //=> true - * ``` - * @param {String} `pattern` Glob pattern - * @param {Object} `options` - * @return {Function} Returns a matcher function. - * @api public + * Copyright (c) 2014-present, Jon Schlinkert. + * Licensed under the MIT License. */ -micromatch.matcher = (pattern, options) => picomatch(pattern, options); -/** - * Returns true if **any** of the given glob `patterns` match the specified `string`. - * - * ```js - * const mm = require('micromatch'); - * // mm.isMatch(string, patterns[, options]); - * - * console.log(mm.isMatch('a.a', ['b.*', '*.a'])); //=> true - * console.log(mm.isMatch('a.a', 'b.*')); //=> false - * ``` - * @param {String} str The string to test. - * @param {String|Array} patterns One or more glob patterns to use for matching. - * @param {Object} [options] See available [options](#options). - * @return {Boolean} Returns true if any patterns match `str` - * @api public - */ -micromatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str); +const util = __webpack_require__(111); +const toRegexRange = __webpack_require__(309); -/** - * Backwards compatibility - */ +const isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val); -micromatch.any = micromatch.isMatch; +const transform = toNumber => { + return value => toNumber === true ? Number(value) : String(value); +}; -/** - * Returns a list of strings that _**do not match any**_ of the given `patterns`. - * - * ```js - * const mm = require('micromatch'); - * // mm.not(list, patterns[, options]); - * - * console.log(mm.not(['a.a', 'b.b', 'c.c'], '*.a')); - * //=> ['b.b', 'c.c'] - * ``` - * @param {Array} `list` Array of strings to match. - * @param {String|Array} `patterns` One or more glob pattern to use for matching. - * @param {Object} `options` See available [options](#options) for changing how matches are performed - * @return {Array} Returns an array of strings that **do not match** the given patterns. - * @api public - */ +const isValidValue = value => { + return typeof value === 'number' || (typeof value === 'string' && value !== ''); +}; -micromatch.not = (list, patterns, options = {}) => { - patterns = [].concat(patterns).map(String); - let result = new Set(); - let items = []; +const isNumber = num => Number.isInteger(+num); - let onResult = state => { - if (options.onResult) options.onResult(state); - items.push(state.output); - }; +const zeros = input => { + let value = `${input}`; + let index = -1; + if (value[0] === '-') value = value.slice(1); + if (value === '0') return false; + while (value[++index] === '0'); + return index > 0; +}; - let matches = micromatch(list, patterns, { ...options, onResult }); +const stringify = (start, end, options) => { + if (typeof start === 'string' || typeof end === 'string') { + return true; + } + return options.stringify === true; +}; - for (let item of items) { - if (!matches.includes(item)) { - result.add(item); - } +const pad = (input, maxLength, toNumber) => { + if (maxLength > 0) { + let dash = input[0] === '-' ? '-' : ''; + if (dash) input = input.slice(1); + input = (dash + input.padStart(dash ? maxLength - 1 : maxLength, '0')); } - return [...result]; + if (toNumber === false) { + return String(input); + } + return input; }; -/** - * Returns true if the given `string` contains the given pattern. Similar - * to [.isMatch](#isMatch) but the pattern can match any part of the string. - * - * ```js - * var mm = require('micromatch'); - * // mm.contains(string, pattern[, options]); - * - * console.log(mm.contains('aa/bb/cc', '*b')); - * //=> true - * console.log(mm.contains('aa/bb/cc', '*d')); - * //=> false - * ``` - * @param {String} `str` The string to match. - * @param {String|Array} `patterns` Glob pattern to use for matching. - * @param {Object} `options` See available [options](#options) for changing how matches are performed - * @return {Boolean} Returns true if the patter matches any part of `str`. - * @api public - */ +const toMaxLen = (input, maxLength) => { + let negative = input[0] === '-' ? '-' : ''; + if (negative) { + input = input.slice(1); + maxLength--; + } + while (input.length < maxLength) input = '0' + input; + return negative ? ('-' + input) : input; +}; -micromatch.contains = (str, pattern, options) => { - if (typeof str !== 'string') { - throw new TypeError(`Expected a string: "${util.inspect(str)}"`); +const toSequence = (parts, options) => { + parts.negatives.sort((a, b) => a < b ? -1 : a > b ? 1 : 0); + parts.positives.sort((a, b) => a < b ? -1 : a > b ? 1 : 0); + + let prefix = options.capture ? '' : '?:'; + let positives = ''; + let negatives = ''; + let result; + + if (parts.positives.length) { + positives = parts.positives.join('|'); } - if (Array.isArray(pattern)) { - return pattern.some(p => micromatch.contains(str, p, options)); + if (parts.negatives.length) { + negatives = `-(${prefix}${parts.negatives.join('|')})`; } - if (typeof pattern === 'string') { - if (isEmptyString(str) || isEmptyString(pattern)) { - return false; - } + if (positives && negatives) { + result = `${positives}|${negatives}`; + } else { + result = positives || negatives; + } - if (str.includes(pattern) || (str.startsWith('./') && str.slice(2).includes(pattern))) { - return true; - } + if (options.wrap) { + return `(${prefix}${result})`; } - return micromatch.isMatch(str, pattern, { ...options, contains: true }); + return result; }; -/** - * Filter the keys of the given object with the given `glob` pattern - * and `options`. Does not attempt to match nested keys. If you need this feature, - * use [glob-object][] instead. - * - * ```js - * const mm = require('micromatch'); - * // mm.matchKeys(object, patterns[, options]); - * - * const obj = { aa: 'a', ab: 'b', ac: 'c' }; - * console.log(mm.matchKeys(obj, '*b')); - * //=> { ab: 'b' } - * ``` - * @param {Object} `object` The object with keys to filter. - * @param {String|Array} `patterns` One or more glob patterns to use for matching. - * @param {Object} `options` See available [options](#options) for changing how matches are performed - * @return {Object} Returns an object with only keys that match the given patterns. - * @api public - */ - -micromatch.matchKeys = (obj, patterns, options) => { - if (!utils.isObject(obj)) { - throw new TypeError('Expected the first argument to be an object'); +const toRange = (a, b, isNumbers, options) => { + if (isNumbers) { + return toRegexRange(a, b, { wrap: false, ...options }); } - let keys = micromatch(Object.keys(obj), patterns, options); - let res = {}; - for (let key of keys) res[key] = obj[key]; - return res; -}; -/** - * Returns true if some of the strings in the given `list` match any of the given glob `patterns`. - * - * ```js - * const mm = require('micromatch'); - * // mm.some(list, patterns[, options]); - * - * console.log(mm.some(['foo.js', 'bar.js'], ['*.js', '!foo.js'])); - * // true - * console.log(mm.some(['foo.js'], ['*.js', '!foo.js'])); - * // false - * ``` - * @param {String|Array} `list` The string or array of strings to test. Returns as soon as the first match is found. - * @param {String|Array} `patterns` One or more glob patterns to use for matching. - * @param {Object} `options` See available [options](#options) for changing how matches are performed - * @return {Boolean} Returns true if any patterns match `str` - * @api public - */ + let start = String.fromCharCode(a); + if (a === b) return start; -micromatch.some = (list, patterns, options) => { - let items = [].concat(list); + let stop = String.fromCharCode(b); + return `[${start}-${stop}]`; +}; - for (let pattern of [].concat(patterns)) { - let isMatch = picomatch(String(pattern), options); - if (items.some(item => isMatch(item))) { - return true; - } +const toRegex = (start, end, options) => { + if (Array.isArray(start)) { + let wrap = options.wrap === true; + let prefix = options.capture ? '' : '?:'; + return wrap ? `(${prefix}${start.join('|')})` : start.join('|'); } - return false; + return toRegexRange(start, end, options); }; -/** - * Returns true if every string in the given `list` matches - * any of the given glob `patterns`. - * - * ```js - * const mm = require('micromatch'); - * // mm.every(list, patterns[, options]); - * - * console.log(mm.every('foo.js', ['foo.js'])); - * // true - * console.log(mm.every(['foo.js', 'bar.js'], ['*.js'])); - * // true - * console.log(mm.every(['foo.js', 'bar.js'], ['*.js', '!foo.js'])); - * // false - * console.log(mm.every(['foo.js'], ['*.js', '!foo.js'])); - * // false - * ``` - * @param {String|Array} `list` The string or array of strings to test. - * @param {String|Array} `patterns` One or more glob patterns to use for matching. - * @param {Object} `options` See available [options](#options) for changing how matches are performed - * @return {Boolean} Returns true if any patterns match `str` - * @api public - */ +const rangeError = (...args) => { + return new RangeError('Invalid range arguments: ' + util.inspect(...args)); +}; -micromatch.every = (list, patterns, options) => { - let items = [].concat(list); +const invalidRange = (start, end, options) => { + if (options.strictRanges === true) throw rangeError([start, end]); + return []; +}; - for (let pattern of [].concat(patterns)) { - let isMatch = picomatch(String(pattern), options); - if (!items.every(item => isMatch(item))) { - return false; - } +const invalidStep = (step, options) => { + if (options.strictRanges === true) { + throw new TypeError(`Expected step "${step}" to be a number`); } - return true; + return []; }; -/** - * Returns true if **all** of the given `patterns` match - * the specified string. - * - * ```js - * const mm = require('micromatch'); - * // mm.all(string, patterns[, options]); - * - * console.log(mm.all('foo.js', ['foo.js'])); - * // true - * - * console.log(mm.all('foo.js', ['*.js', '!foo.js'])); - * // false - * - * console.log(mm.all('foo.js', ['*.js', 'foo.js'])); - * // true - * - * console.log(mm.all('foo.js', ['*.js', 'f*', '*o*', '*o.js'])); - * // true - * ``` - * @param {String|Array} `str` The string to test. - * @param {String|Array} `patterns` One or more glob patterns to use for matching. - * @param {Object} `options` See available [options](#options) for changing how matches are performed - * @return {Boolean} Returns true if any patterns match `str` - * @api public - */ +const fillNumbers = (start, end, step = 1, options = {}) => { + let a = Number(start); + let b = Number(end); -micromatch.all = (str, patterns, options) => { - if (typeof str !== 'string') { - throw new TypeError(`Expected a string: "${util.inspect(str)}"`); + if (!Number.isInteger(a) || !Number.isInteger(b)) { + if (options.strictRanges === true) throw rangeError([start, end]); + return []; } - return [].concat(patterns).every(p => picomatch(p, options)(str)); -}; + // fix negative zero + if (a === 0) a = 0; + if (b === 0) b = 0; -/** - * Returns an array of matches captured by `pattern` in `string, or `null` if the pattern did not match. - * - * ```js - * const mm = require('micromatch'); - * // mm.capture(pattern, string[, options]); - * - * console.log(mm.capture('test/*.js', 'test/foo.js')); - * //=> ['foo'] - * console.log(mm.capture('test/*.js', 'foo/bar.css')); - * //=> null - * ``` - * @param {String} `glob` Glob pattern to use for matching. - * @param {String} `input` String to match - * @param {Object} `options` See available [options](#options) for changing how matches are performed - * @return {Boolean} Returns an array of captures if the input matches the glob pattern, otherwise `null`. - * @api public - */ + let descending = a > b; + let startString = String(start); + let endString = String(end); + let stepString = String(step); + step = Math.max(Math.abs(step), 1); -micromatch.capture = (glob, input, options) => { - let posix = utils.isWindows(options); - let regex = picomatch.makeRe(String(glob), { ...options, capture: true }); - let match = regex.exec(posix ? utils.toPosixSlashes(input) : input); + let padded = zeros(startString) || zeros(endString) || zeros(stepString); + let maxLen = padded ? Math.max(startString.length, endString.length, stepString.length) : 0; + let toNumber = padded === false && stringify(start, end, options) === false; + let format = options.transform || transform(toNumber); - if (match) { - return match.slice(1).map(v => v === void 0 ? '' : v); + if (options.toRegex && step === 1) { + return toRange(toMaxLen(start, maxLen), toMaxLen(end, maxLen), true, options); + } + + let parts = { negatives: [], positives: [] }; + let push = num => parts[num < 0 ? 'negatives' : 'positives'].push(Math.abs(num)); + let range = []; + let index = 0; + + while (descending ? a >= b : a <= b) { + if (options.toRegex === true && step > 1) { + push(a); + } else { + range.push(pad(format(a, index), maxLen, toNumber)); + } + a = descending ? a - step : a + step; + index++; + } + + if (options.toRegex === true) { + return step > 1 + ? toSequence(parts, options) + : toRegex(range, null, { wrap: false, ...options }); } + + return range; }; -/** - * Create a regular expression from the given glob `pattern`. - * - * ```js - * const mm = require('micromatch'); - * // mm.makeRe(pattern[, options]); - * - * console.log(mm.makeRe('*.js')); - * //=> /^(?:(\.[\\\/])?(?!\.)(?=.)[^\/]*?\.js)$/ - * ``` - * @param {String} `pattern` A glob pattern to convert to regex. - * @param {Object} `options` - * @return {RegExp} Returns a regex created from the given pattern. - * @api public - */ +const fillLetters = (start, end, step = 1, options = {}) => { + if ((!isNumber(start) && start.length > 1) || (!isNumber(end) && end.length > 1)) { + return invalidRange(start, end, options); + } -micromatch.makeRe = (...args) => picomatch.makeRe(...args); -/** - * Scan a glob pattern to separate the pattern into segments. Used - * by the [split](#split) method. - * - * ```js - * const mm = require('micromatch'); - * const state = mm.scan(pattern[, options]); - * ``` - * @param {String} `pattern` - * @param {Object} `options` - * @return {Object} Returns an object with - * @api public - */ + let format = options.transform || (val => String.fromCharCode(val)); + let a = `${start}`.charCodeAt(0); + let b = `${end}`.charCodeAt(0); -micromatch.scan = (...args) => picomatch.scan(...args); + let descending = a > b; + let min = Math.min(a, b); + let max = Math.max(a, b); -/** - * Parse a glob pattern to create the source string for a regular - * expression. - * - * ```js - * const mm = require('micromatch'); - * const state = mm(pattern[, options]); - * ``` - * @param {String} `glob` - * @param {Object} `options` - * @return {Object} Returns an object with useful properties and output to be used as regex source string. - * @api public - */ + if (options.toRegex && step === 1) { + return toRange(min, max, false, options); + } -micromatch.parse = (patterns, options) => { - let res = []; - for (let pattern of [].concat(patterns || [])) { - for (let str of braces(String(pattern), options)) { - res.push(picomatch.parse(str, options)); - } + let range = []; + let index = 0; + + while (descending ? a >= b : a <= b) { + range.push(format(a, index)); + a = descending ? a - step : a + step; + index++; } - return res; + + if (options.toRegex === true) { + return toRegex(range, null, { wrap: false, options }); + } + + return range; }; -/** - * Process the given brace `pattern`. - * - * ```js - * const { braces } = require('micromatch'); - * console.log(braces('foo/{a,b,c}/bar')); - * //=> [ 'foo/(a|b|c)/bar' ] - * - * console.log(braces('foo/{a,b,c}/bar', { expand: true })); - * //=> [ 'foo/a/bar', 'foo/b/bar', 'foo/c/bar' ] - * ``` - * @param {String} `pattern` String with brace pattern to process. - * @param {Object} `options` Any [options](#options) to change how expansion is performed. See the [braces][] library for all available options. - * @return {Array} - * @api public - */ +const fill = (start, end, step, options = {}) => { + if (end == null && isValidValue(start)) { + return [start]; + } -micromatch.braces = (pattern, options) => { - if (typeof pattern !== 'string') throw new TypeError('Expected a string'); - if ((options && options.nobrace === true) || !/\{.*\}/.test(pattern)) { - return [pattern]; + if (!isValidValue(start) || !isValidValue(end)) { + return invalidRange(start, end, options); } - return braces(pattern, options); -}; -/** - * Expand braces - */ + if (typeof step === 'function') { + return fill(start, end, 1, { transform: step }); + } -micromatch.braceExpand = (pattern, options) => { - if (typeof pattern !== 'string') throw new TypeError('Expected a string'); - return micromatch.braces(pattern, { ...options, expand: true }); -}; + if (isObject(step)) { + return fill(start, end, 0, step); + } -/** - * Expose micromatch - */ + let opts = { ...options }; + if (opts.capture === true) opts.wrap = true; + step = step || opts.step || 1; -module.exports = micromatch; + if (!isNumber(step)) { + if (step != null && !isObject(step)) return invalidStep(step, opts); + return fill(start, end, 1, step); + } + + if (isNumber(start) && isNumber(end)) { + return fillNumbers(start, end, step, opts); + } + + return fillLetters(start, end, Math.max(Math.abs(step), 1), opts); +}; + +module.exports = fill; /***/ }), -/* 312 */ +/* 309 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +/*! + * to-regex-range + * + * Copyright (c) 2015-present, Jon Schlinkert. + * Released under the MIT License. + */ -const stringify = __webpack_require__(313); -const compile = __webpack_require__(315); -const expand = __webpack_require__(319); -const parse = __webpack_require__(320); -/** - * Expand the given pattern or create a regex-compatible string. - * - * ```js - * const braces = require('braces'); - * console.log(braces('{a,b,c}', { compile: true })); //=> ['(a|b|c)'] - * console.log(braces('{a,b,c}')); //=> ['a', 'b', 'c'] - * ``` - * @param {String} `str` - * @param {Object} `options` - * @return {String} - * @api public - */ +const isNumber = __webpack_require__(310); -const braces = (input, options = {}) => { - let output = []; +const toRegexRange = (min, max, options) => { + if (isNumber(min) === false) { + throw new TypeError('toRegexRange: expected the first argument to be a number'); + } - if (Array.isArray(input)) { - for (let pattern of input) { - let result = braces.create(pattern, options); - if (Array.isArray(result)) { - output.push(...result); - } else { - output.push(result); - } - } - } else { - output = [].concat(braces.create(input, options)); + if (max === void 0 || min === max) { + return String(min); } - if (options && options.expand === true && options.nodupes === true) { - output = [...new Set(output)]; + if (isNumber(max) === false) { + throw new TypeError('toRegexRange: expected the second argument to be a number.'); } - return output; -}; -/** - * Parse the given `str` with the given `options`. - * - * ```js - * // braces.parse(pattern, [, options]); - * const ast = braces.parse('a/{b,c}/d'); - * console.log(ast); - * ``` - * @param {String} pattern Brace pattern to parse - * @param {Object} options - * @return {Object} Returns an AST - * @api public - */ - -braces.parse = (input, options = {}) => parse(input, options); + let opts = { relaxZeros: true, ...options }; + if (typeof opts.strictZeros === 'boolean') { + opts.relaxZeros = opts.strictZeros === false; + } -/** - * Creates a braces string from an AST, or an AST node. - * - * ```js - * const braces = require('braces'); - * let ast = braces.parse('foo/{a,b}/bar'); - * console.log(stringify(ast.nodes[2])); //=> '{a,b}' - * ``` - * @param {String} `input` Brace pattern or AST. - * @param {Object} `options` - * @return {Array} Returns an array of expanded values. - * @api public - */ + let relax = String(opts.relaxZeros); + let shorthand = String(opts.shorthand); + let capture = String(opts.capture); + let wrap = String(opts.wrap); + let cacheKey = min + ':' + max + '=' + relax + shorthand + capture + wrap; -braces.stringify = (input, options = {}) => { - if (typeof input === 'string') { - return stringify(braces.parse(input, options), options); + if (toRegexRange.cache.hasOwnProperty(cacheKey)) { + return toRegexRange.cache[cacheKey].result; } - return stringify(input, options); -}; -/** - * Compiles a brace pattern into a regex-compatible, optimized string. - * This method is called by the main [braces](#braces) function by default. - * - * ```js - * const braces = require('braces'); - * console.log(braces.compile('a/{b,c}/d')); - * //=> ['a/(b|c)/d'] - * ``` - * @param {String} `input` Brace pattern or AST. - * @param {Object} `options` - * @return {Array} Returns an array of expanded values. - * @api public - */ + let a = Math.min(min, max); + let b = Math.max(min, max); -braces.compile = (input, options = {}) => { - if (typeof input === 'string') { - input = braces.parse(input, options); + if (Math.abs(a - b) === 1) { + let result = min + '|' + max; + if (opts.capture) { + return `(${result})`; + } + if (opts.wrap === false) { + return result; + } + return `(?:${result})`; } - return compile(input, options); -}; -/** - * Expands a brace pattern into an array. This method is called by the - * main [braces](#braces) function when `options.expand` is true. Before - * using this method it's recommended that you read the [performance notes](#performance)) - * and advantages of using [.compile](#compile) instead. - * - * ```js - * const braces = require('braces'); - * console.log(braces.expand('a/{b,c}/d')); - * //=> ['a/b/d', 'a/c/d']; - * ``` - * @param {String} `pattern` Brace pattern - * @param {Object} `options` - * @return {Array} Returns an array of expanded values. - * @api public - */ + let isPadded = hasPadding(min) || hasPadding(max); + let state = { min, max, a, b }; + let positives = []; + let negatives = []; -braces.expand = (input, options = {}) => { - if (typeof input === 'string') { - input = braces.parse(input, options); + if (isPadded) { + state.isPadded = isPadded; + state.maxLen = String(state.max).length; } - let result = expand(input, options); + if (a < 0) { + let newMin = b < 0 ? Math.abs(b) : 1; + negatives = splitToPatterns(newMin, Math.abs(a), state, opts); + a = state.a = 0; + } - // filter out empty strings if specified - if (options.noempty === true) { - result = result.filter(Boolean); + if (b >= 0) { + positives = splitToPatterns(a, b, state, opts); } - // filter out duplicates if specified - if (options.nodupes === true) { - result = [...new Set(result)]; + state.negatives = negatives; + state.positives = positives; + state.result = collatePatterns(negatives, positives, opts); + + if (opts.capture === true) { + state.result = `(${state.result})`; + } else if (opts.wrap !== false && (positives.length + negatives.length) > 1) { + state.result = `(?:${state.result})`; } - return result; + toRegexRange.cache[cacheKey] = state; + return state.result; }; -/** - * Processes a brace pattern and returns either an expanded array - * (if `options.expand` is true), a highly optimized regex-compatible string. - * This method is called by the main [braces](#braces) function. - * - * ```js - * const braces = require('braces'); - * console.log(braces.create('user-{200..300}/project-{a,b,c}-{1..10}')) - * //=> 'user-(20[0-9]|2[1-9][0-9]|300)/project-(a|b|c)-([1-9]|10)' - * ``` - * @param {String} `pattern` Brace pattern - * @param {Object} `options` - * @return {Array} Returns an array of expanded values. - * @api public - */ +function collatePatterns(neg, pos, options) { + let onlyNegative = filterPatterns(neg, pos, '-', false, options) || []; + let onlyPositive = filterPatterns(pos, neg, '', false, options) || []; + let intersected = filterPatterns(neg, pos, '-?', true, options) || []; + let subpatterns = onlyNegative.concat(intersected).concat(onlyPositive); + return subpatterns.join('|'); +} -braces.create = (input, options = {}) => { - if (input === '' || input.length < 3) { - return [input]; +function splitToRanges(min, max) { + let nines = 1; + let zeros = 1; + + let stop = countNines(min, nines); + let stops = new Set([max]); + + while (min <= stop && stop <= max) { + stops.add(stop); + nines += 1; + stop = countNines(min, nines); } - return options.expand !== true - ? braces.compile(input, options) - : braces.expand(input, options); -}; + stop = countZeros(max + 1, zeros) - 1; + + while (min < stop && stop <= max) { + stops.add(stop); + zeros += 1; + stop = countZeros(max + 1, zeros) - 1; + } + + stops = [...stops]; + stops.sort(compare); + return stops; +} /** - * Expose "braces" + * Convert a range to a regex pattern + * @param {Number} `start` + * @param {Number} `stop` + * @return {String} */ -module.exports = braces; +function rangeToPattern(start, stop, options) { + if (start === stop) { + return { pattern: start, count: [], digits: 0 }; + } + + let zipped = zip(start, stop); + let digits = zipped.length; + let pattern = ''; + let count = 0; + for (let i = 0; i < digits; i++) { + let [startDigit, stopDigit] = zipped[i]; -/***/ }), -/* 313 */ -/***/ (function(module, exports, __webpack_require__) { + if (startDigit === stopDigit) { + pattern += startDigit; -"use strict"; + } else if (startDigit !== '0' || stopDigit !== '9') { + pattern += toCharacterClass(startDigit, stopDigit, options); + + } else { + count++; + } + } + if (count) { + pattern += options.shorthand === true ? '\\d' : '[0-9]'; + } -const utils = __webpack_require__(314); + return { pattern, count: [count], digits }; +} -module.exports = (ast, options = {}) => { - let stringify = (node, parent = {}) => { - let invalidBlock = options.escapeInvalid && utils.isInvalidBrace(parent); - let invalidNode = node.invalid === true && options.escapeInvalid === true; - let output = ''; +function splitToPatterns(min, max, tok, options) { + let ranges = splitToRanges(min, max); + let tokens = []; + let start = min; + let prev; - if (node.value) { - if ((invalidBlock || invalidNode) && utils.isOpenOrClose(node)) { - return '\\' + node.value; + for (let i = 0; i < ranges.length; i++) { + let max = ranges[i]; + let obj = rangeToPattern(String(start), String(max), options); + let zeros = ''; + + if (!tok.isPadded && prev && prev.pattern === obj.pattern) { + if (prev.count.length > 1) { + prev.count.pop(); } - return node.value; - } - if (node.value) { - return node.value; + prev.count.push(obj.count[0]); + prev.string = prev.pattern + toQuantifier(prev.count); + start = max + 1; + continue; } - if (node.nodes) { - for (let child of node.nodes) { - output += stringify(child); - } + if (tok.isPadded) { + zeros = padZeros(max, tok, options); } - return output; - }; - - return stringify(ast); -}; + obj.string = zeros + obj.pattern + toQuantifier(obj.count); + tokens.push(obj); + start = max + 1; + prev = obj; + } + return tokens; +} -/***/ }), -/* 314 */ -/***/ (function(module, exports, __webpack_require__) { +function filterPatterns(arr, comparison, prefix, intersection, options) { + let result = []; -"use strict"; + for (let ele of arr) { + let { string } = ele; + // only push if _both_ are negative... + if (!intersection && !contains(comparison, 'string', string)) { + result.push(prefix + string); + } -exports.isInteger = num => { - if (typeof num === 'number') { - return Number.isInteger(num); - } - if (typeof num === 'string' && num.trim() !== '') { - return Number.isInteger(Number(num)); + // or _both_ are positive + if (intersection && contains(comparison, 'string', string)) { + result.push(prefix + string); + } } - return false; -}; + return result; +} /** - * Find a node of the given type + * Zip strings */ -exports.find = (node, type) => node.nodes.find(node => node.type === type); +function zip(a, b) { + let arr = []; + for (let i = 0; i < a.length; i++) arr.push([a[i], b[i]]); + return arr; +} -/** - * Find a node of the given type - */ +function compare(a, b) { + return a > b ? 1 : b > a ? -1 : 0; +} -exports.exceedsLimit = (min, max, step = 1, limit) => { - if (limit === false) return false; - if (!exports.isInteger(min) || !exports.isInteger(max)) return false; - return ((Number(max) - Number(min)) / Number(step)) >= limit; -}; +function contains(arr, key, val) { + return arr.some(ele => ele[key] === val); +} -/** - * Escape the given node with '\\' before node.value - */ +function countNines(min, len) { + return Number(String(min).slice(0, -len) + '9'.repeat(len)); +} -exports.escapeNode = (block, n = 0, type) => { - let node = block.nodes[n]; - if (!node) return; +function countZeros(integer, zeros) { + return integer - (integer % Math.pow(10, zeros)); +} - if ((type && node.type === type) || node.type === 'open' || node.type === 'close') { - if (node.escaped !== true) { - node.value = '\\' + node.value; - node.escaped = true; - } +function toQuantifier(digits) { + let [start = 0, stop = ''] = digits; + if (stop || start > 1) { + return `{${start + (stop ? ',' + stop : '')}}`; } -}; + return ''; +} -/** - * Returns true if the given brace node should be enclosed in literal braces - */ +function toCharacterClass(a, b, options) { + return `[${a}${(b - a === 1) ? '' : '-'}${b}]`; +} -exports.encloseBrace = node => { - if (node.type !== 'brace') return false; - if ((node.commas >> 0 + node.ranges >> 0) === 0) { - node.invalid = true; - return true; +function hasPadding(str) { + return /^-?(0+)\d/.test(str); +} + +function padZeros(value, tok, options) { + if (!tok.isPadded) { + return value; } - return false; -}; -/** - * Returns true if a brace node is invalid. - */ + let diff = Math.abs(tok.maxLen - String(value).length); + let relax = options.relaxZeros !== false; -exports.isInvalidBrace = block => { - if (block.type !== 'brace') return false; - if (block.invalid === true || block.dollar) return true; - if ((block.commas >> 0 + block.ranges >> 0) === 0) { - block.invalid = true; - return true; - } - if (block.open !== true || block.close !== true) { - block.invalid = true; - return true; + switch (diff) { + case 0: + return ''; + case 1: + return relax ? '0?' : '0'; + case 2: + return relax ? '0{0,2}' : '00'; + default: { + return relax ? `0{0,${diff}}` : `0{${diff}}`; + } } - return false; -}; +} /** - * Returns true if a node is an open or close node + * Cache */ -exports.isOpenOrClose = node => { - if (node.type === 'open' || node.type === 'close') { - return true; - } - return node.open === true || node.close === true; -}; +toRegexRange.cache = {}; +toRegexRange.clearCache = () => (toRegexRange.cache = {}); /** - * Reduce an array of text nodes. + * Expose `toRegexRange` */ -exports.reduce = nodes => nodes.reduce((acc, node) => { - if (node.type === 'text') acc.push(node.value); - if (node.type === 'range') node.type = 'text'; - return acc; -}, []); +module.exports = toRegexRange; -/** - * Flatten an array + +/***/ }), +/* 310 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/*! + * is-number + * + * Copyright (c) 2014-present, Jon Schlinkert. + * Released under the MIT License. */ -exports.flatten = (...args) => { - const result = []; - const flat = arr => { - for (let i = 0; i < arr.length; i++) { - let ele = arr[i]; - Array.isArray(ele) ? flat(ele, result) : ele !== void 0 && result.push(ele); - } - return result; - }; - flat(args); - return result; + + +module.exports = function(num) { + if (typeof num === 'number') { + return num - num === 0; + } + if (typeof num === 'string' && num.trim() !== '') { + return Number.isFinite ? Number.isFinite(+num) : isFinite(+num); + } + return false; }; /***/ }), -/* 315 */ +/* 311 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const fill = __webpack_require__(316); -const utils = __webpack_require__(314); +const fill = __webpack_require__(308); +const stringify = __webpack_require__(305); +const utils = __webpack_require__(306); -const compile = (ast, options = {}) => { - let walk = (node, parent = {}) => { - let invalidBlock = utils.isInvalidBrace(parent); - let invalidNode = node.invalid === true && options.escapeInvalid === true; - let invalid = invalidBlock === true || invalidNode === true; - let prefix = options.escapeInvalid === true ? '\\' : ''; - let output = ''; +const append = (queue = '', stash = '', enclose = false) => { + let result = []; - if (node.isOpen === true) { - return prefix + node.value; - } - if (node.isClose === true) { - return prefix + node.value; - } + queue = [].concat(queue); + stash = [].concat(stash); - if (node.type === 'open') { - return invalid ? (prefix + node.value) : '('; + if (!stash.length) return queue; + if (!queue.length) { + return enclose ? utils.flatten(stash).map(ele => `{${ele}}`) : stash; + } + + for (let item of queue) { + if (Array.isArray(item)) { + for (let value of item) { + result.push(append(value, stash, enclose)); + } + } else { + for (let ele of stash) { + if (enclose === true && typeof ele === 'string') ele = `{${ele}}`; + result.push(Array.isArray(ele) ? append(item, ele, enclose) : (item + ele)); + } } + } + return utils.flatten(result); +}; - if (node.type === 'close') { - return invalid ? (prefix + node.value) : ')'; +const expand = (ast, options = {}) => { + let rangeLimit = options.rangeLimit === void 0 ? 1000 : options.rangeLimit; + + let walk = (node, parent = {}) => { + node.queue = []; + + let p = parent; + let q = parent.queue; + + while (p.type !== 'brace' && p.type !== 'root' && p.parent) { + p = p.parent; + q = p.queue; } - if (node.type === 'comma') { - return node.prev.type === 'comma' ? '' : (invalid ? node.value : '|'); + if (node.invalid || node.dollar) { + q.push(append(q.pop(), stringify(node, options))); + return; } - if (node.value) { - return node.value; + if (node.type === 'brace' && node.invalid !== true && node.nodes.length === 2) { + q.push(append(q.pop(), ['{}'])); + return; } if (node.nodes && node.ranges > 0) { let args = utils.reduce(node.nodes); - let range = fill(...args, { ...options, wrap: false, toRegex: true }); - if (range.length !== 0) { - return args.length > 1 && range.length > 1 ? `(${range})` : range; + if (utils.exceedsLimit(...args, options.step, rangeLimit)) { + throw new RangeError('expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.'); } - } - if (node.nodes) { - for (let child of node.nodes) { - output += walk(child, node); + let range = fill(...args, options); + if (range.length === 0) { + range = stringify(node, options); } + + q.push(append(q.pop(), range)); + node.nodes = []; + return; } - return output; - }; - return walk(ast); -}; + let enclose = utils.encloseBrace(node); + let queue = node.queue; + let block = node; -module.exports = compile; + while (block.type !== 'brace' && block.type !== 'root' && block.parent) { + block = block.parent; + queue = block.queue; + } + for (let i = 0; i < node.nodes.length; i++) { + let child = node.nodes[i]; -/***/ }), -/* 316 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * fill-range - * - * Copyright (c) 2014-present, Jon Schlinkert. - * Licensed under the MIT License. - */ + if (child.type === 'comma' && node.type === 'brace') { + if (i === 1) queue.push(''); + queue.push(''); + continue; + } + if (child.type === 'close') { + q.push(append(q.pop(), queue, enclose)); + continue; + } + if (child.value && child.type !== 'open') { + queue.push(append(queue.pop(), child.value)); + continue; + } -const util = __webpack_require__(111); -const toRegexRange = __webpack_require__(317); + if (child.nodes) { + walk(child, node); + } + } -const isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val); + return queue; + }; -const transform = toNumber => { - return value => toNumber === true ? Number(value) : String(value); + return utils.flatten(walk(ast)); }; -const isValidValue = value => { - return typeof value === 'number' || (typeof value === 'string' && value !== ''); -}; +module.exports = expand; -const isNumber = num => Number.isInteger(+num); -const zeros = input => { - let value = `${input}`; - let index = -1; - if (value[0] === '-') value = value.slice(1); - if (value === '0') return false; - while (value[++index] === '0'); - return index > 0; -}; +/***/ }), +/* 312 */ +/***/ (function(module, exports, __webpack_require__) { -const stringify = (start, end, options) => { - if (typeof start === 'string' || typeof end === 'string') { - return true; - } - return options.stringify === true; -}; +"use strict"; -const pad = (input, maxLength, toNumber) => { - if (maxLength > 0) { - let dash = input[0] === '-' ? '-' : ''; - if (dash) input = input.slice(1); - input = (dash + input.padStart(dash ? maxLength - 1 : maxLength, '0')); - } - if (toNumber === false) { - return String(input); - } - return input; -}; -const toMaxLen = (input, maxLength) => { - let negative = input[0] === '-' ? '-' : ''; - if (negative) { - input = input.slice(1); - maxLength--; - } - while (input.length < maxLength) input = '0' + input; - return negative ? ('-' + input) : input; -}; +const stringify = __webpack_require__(305); -const toSequence = (parts, options) => { - parts.negatives.sort((a, b) => a < b ? -1 : a > b ? 1 : 0); - parts.positives.sort((a, b) => a < b ? -1 : a > b ? 1 : 0); +/** + * Constants + */ - let prefix = options.capture ? '' : '?:'; - let positives = ''; - let negatives = ''; - let result; +const { + MAX_LENGTH, + CHAR_BACKSLASH, /* \ */ + CHAR_BACKTICK, /* ` */ + CHAR_COMMA, /* , */ + CHAR_DOT, /* . */ + CHAR_LEFT_PARENTHESES, /* ( */ + CHAR_RIGHT_PARENTHESES, /* ) */ + CHAR_LEFT_CURLY_BRACE, /* { */ + CHAR_RIGHT_CURLY_BRACE, /* } */ + CHAR_LEFT_SQUARE_BRACKET, /* [ */ + CHAR_RIGHT_SQUARE_BRACKET, /* ] */ + CHAR_DOUBLE_QUOTE, /* " */ + CHAR_SINGLE_QUOTE, /* ' */ + CHAR_NO_BREAK_SPACE, + CHAR_ZERO_WIDTH_NOBREAK_SPACE +} = __webpack_require__(313); - if (parts.positives.length) { - positives = parts.positives.join('|'); - } +/** + * parse + */ - if (parts.negatives.length) { - negatives = `-(${prefix}${parts.negatives.join('|')})`; +const parse = (input, options = {}) => { + if (typeof input !== 'string') { + throw new TypeError('Expected a string'); } - if (positives && negatives) { - result = `${positives}|${negatives}`; - } else { - result = positives || negatives; + let opts = options || {}; + let max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; + if (input.length > max) { + throw new SyntaxError(`Input length (${input.length}), exceeds max characters (${max})`); } - if (options.wrap) { - return `(${prefix}${result})`; - } + let ast = { type: 'root', input, nodes: [] }; + let stack = [ast]; + let block = ast; + let prev = ast; + let brackets = 0; + let length = input.length; + let index = 0; + let depth = 0; + let value; + let memo = {}; - return result; -}; + /** + * Helpers + */ -const toRange = (a, b, isNumbers, options) => { - if (isNumbers) { - return toRegexRange(a, b, { wrap: false, ...options }); - } + const advance = () => input[index++]; + const push = node => { + if (node.type === 'text' && prev.type === 'dot') { + prev.type = 'text'; + } - let start = String.fromCharCode(a); - if (a === b) return start; + if (prev && prev.type === 'text' && node.type === 'text') { + prev.value += node.value; + return; + } - let stop = String.fromCharCode(b); - return `[${start}-${stop}]`; -}; + block.nodes.push(node); + node.parent = block; + node.prev = prev; + prev = node; + return node; + }; -const toRegex = (start, end, options) => { - if (Array.isArray(start)) { - let wrap = options.wrap === true; - let prefix = options.capture ? '' : '?:'; - return wrap ? `(${prefix}${start.join('|')})` : start.join('|'); - } - return toRegexRange(start, end, options); -}; + push({ type: 'bos' }); -const rangeError = (...args) => { - return new RangeError('Invalid range arguments: ' + util.inspect(...args)); -}; + while (index < length) { + block = stack[stack.length - 1]; + value = advance(); -const invalidRange = (start, end, options) => { - if (options.strictRanges === true) throw rangeError([start, end]); - return []; -}; + /** + * Invalid chars + */ -const invalidStep = (step, options) => { - if (options.strictRanges === true) { - throw new TypeError(`Expected step "${step}" to be a number`); - } - return []; -}; + if (value === CHAR_ZERO_WIDTH_NOBREAK_SPACE || value === CHAR_NO_BREAK_SPACE) { + continue; + } -const fillNumbers = (start, end, step = 1, options = {}) => { - let a = Number(start); - let b = Number(end); + /** + * Escaped chars + */ - if (!Number.isInteger(a) || !Number.isInteger(b)) { - if (options.strictRanges === true) throw rangeError([start, end]); - return []; - } + if (value === CHAR_BACKSLASH) { + push({ type: 'text', value: (options.keepEscaping ? value : '') + advance() }); + continue; + } - // fix negative zero - if (a === 0) a = 0; - if (b === 0) b = 0; + /** + * Right square bracket (literal): ']' + */ - let descending = a > b; - let startString = String(start); - let endString = String(end); - let stepString = String(step); - step = Math.max(Math.abs(step), 1); + if (value === CHAR_RIGHT_SQUARE_BRACKET) { + push({ type: 'text', value: '\\' + value }); + continue; + } - let padded = zeros(startString) || zeros(endString) || zeros(stepString); - let maxLen = padded ? Math.max(startString.length, endString.length, stepString.length) : 0; - let toNumber = padded === false && stringify(start, end, options) === false; - let format = options.transform || transform(toNumber); + /** + * Left square bracket: '[' + */ - if (options.toRegex && step === 1) { - return toRange(toMaxLen(start, maxLen), toMaxLen(end, maxLen), true, options); - } + if (value === CHAR_LEFT_SQUARE_BRACKET) { + brackets++; - let parts = { negatives: [], positives: [] }; - let push = num => parts[num < 0 ? 'negatives' : 'positives'].push(Math.abs(num)); - let range = []; - let index = 0; + let closed = true; + let next; - while (descending ? a >= b : a <= b) { - if (options.toRegex === true && step > 1) { - push(a); - } else { - range.push(pad(format(a, index), maxLen, toNumber)); - } - a = descending ? a - step : a + step; - index++; - } + while (index < length && (next = advance())) { + value += next; - if (options.toRegex === true) { - return step > 1 - ? toSequence(parts, options) - : toRegex(range, null, { wrap: false, ...options }); - } + if (next === CHAR_LEFT_SQUARE_BRACKET) { + brackets++; + continue; + } - return range; -}; + if (next === CHAR_BACKSLASH) { + value += advance(); + continue; + } -const fillLetters = (start, end, step = 1, options = {}) => { - if ((!isNumber(start) && start.length > 1) || (!isNumber(end) && end.length > 1)) { - return invalidRange(start, end, options); - } + if (next === CHAR_RIGHT_SQUARE_BRACKET) { + brackets--; + if (brackets === 0) { + break; + } + } + } - let format = options.transform || (val => String.fromCharCode(val)); - let a = `${start}`.charCodeAt(0); - let b = `${end}`.charCodeAt(0); + push({ type: 'text', value }); + continue; + } - let descending = a > b; - let min = Math.min(a, b); - let max = Math.max(a, b); + /** + * Parentheses + */ - if (options.toRegex && step === 1) { - return toRange(min, max, false, options); - } + if (value === CHAR_LEFT_PARENTHESES) { + block = push({ type: 'paren', nodes: [] }); + stack.push(block); + push({ type: 'text', value }); + continue; + } - let range = []; - let index = 0; + if (value === CHAR_RIGHT_PARENTHESES) { + if (block.type !== 'paren') { + push({ type: 'text', value }); + continue; + } + block = stack.pop(); + push({ type: 'text', value }); + block = stack[stack.length - 1]; + continue; + } - while (descending ? a >= b : a <= b) { - range.push(format(a, index)); - a = descending ? a - step : a + step; - index++; - } + /** + * Quotes: '|"|` + */ - if (options.toRegex === true) { - return toRegex(range, null, { wrap: false, options }); - } + if (value === CHAR_DOUBLE_QUOTE || value === CHAR_SINGLE_QUOTE || value === CHAR_BACKTICK) { + let open = value; + let next; - return range; -}; + if (options.keepQuotes !== true) { + value = ''; + } -const fill = (start, end, step, options = {}) => { - if (end == null && isValidValue(start)) { - return [start]; - } + while (index < length && (next = advance())) { + if (next === CHAR_BACKSLASH) { + value += next + advance(); + continue; + } - if (!isValidValue(start) || !isValidValue(end)) { - return invalidRange(start, end, options); - } + if (next === open) { + if (options.keepQuotes === true) value += next; + break; + } - if (typeof step === 'function') { - return fill(start, end, 1, { transform: step }); - } + value += next; + } - if (isObject(step)) { - return fill(start, end, 0, step); - } + push({ type: 'text', value }); + continue; + } - let opts = { ...options }; - if (opts.capture === true) opts.wrap = true; - step = step || opts.step || 1; + /** + * Left curly brace: '{' + */ - if (!isNumber(step)) { - if (step != null && !isObject(step)) return invalidStep(step, opts); - return fill(start, end, 1, step); - } + if (value === CHAR_LEFT_CURLY_BRACE) { + depth++; - if (isNumber(start) && isNumber(end)) { - return fillNumbers(start, end, step, opts); - } + let dollar = prev.value && prev.value.slice(-1) === '$' || block.dollar === true; + let brace = { + type: 'brace', + open: true, + close: false, + dollar, + depth, + commas: 0, + ranges: 0, + nodes: [] + }; - return fillLetters(start, end, Math.max(Math.abs(step), 1), opts); -}; + block = push(brace); + stack.push(block); + push({ type: 'open', value }); + continue; + } -module.exports = fill; + /** + * Right curly brace: '}' + */ + if (value === CHAR_RIGHT_CURLY_BRACE) { + if (block.type !== 'brace') { + push({ type: 'text', value }); + continue; + } -/***/ }), -/* 317 */ -/***/ (function(module, exports, __webpack_require__) { + let type = 'close'; + block = stack.pop(); + block.close = true; -"use strict"; -/*! - * to-regex-range - * - * Copyright (c) 2015-present, Jon Schlinkert. - * Released under the MIT License. - */ + push({ type, value }); + depth--; + block = stack[stack.length - 1]; + continue; + } + /** + * Comma: ',' + */ -const isNumber = __webpack_require__(318); + if (value === CHAR_COMMA && depth > 0) { + if (block.ranges > 0) { + block.ranges = 0; + let open = block.nodes.shift(); + block.nodes = [open, { type: 'text', value: stringify(block) }]; + } -const toRegexRange = (min, max, options) => { - if (isNumber(min) === false) { - throw new TypeError('toRegexRange: expected the first argument to be a number'); - } + push({ type: 'comma', value }); + block.commas++; + continue; + } - if (max === void 0 || min === max) { - return String(min); - } + /** + * Dot: '.' + */ - if (isNumber(max) === false) { - throw new TypeError('toRegexRange: expected the second argument to be a number.'); - } + if (value === CHAR_DOT && depth > 0 && block.commas === 0) { + let siblings = block.nodes; - let opts = { relaxZeros: true, ...options }; - if (typeof opts.strictZeros === 'boolean') { - opts.relaxZeros = opts.strictZeros === false; - } + if (depth === 0 || siblings.length === 0) { + push({ type: 'text', value }); + continue; + } - let relax = String(opts.relaxZeros); - let shorthand = String(opts.shorthand); - let capture = String(opts.capture); - let wrap = String(opts.wrap); - let cacheKey = min + ':' + max + '=' + relax + shorthand + capture + wrap; + if (prev.type === 'dot') { + block.range = []; + prev.value += value; + prev.type = 'range'; - if (toRegexRange.cache.hasOwnProperty(cacheKey)) { - return toRegexRange.cache[cacheKey].result; - } + if (block.nodes.length !== 3 && block.nodes.length !== 5) { + block.invalid = true; + block.ranges = 0; + prev.type = 'text'; + continue; + } - let a = Math.min(min, max); - let b = Math.max(min, max); + block.ranges++; + block.args = []; + continue; + } - if (Math.abs(a - b) === 1) { - let result = min + '|' + max; - if (opts.capture) { - return `(${result})`; - } - if (opts.wrap === false) { - return result; + if (prev.type === 'range') { + siblings.pop(); + + let before = siblings[siblings.length - 1]; + before.value += prev.value + value; + prev = before; + block.ranges--; + continue; + } + + push({ type: 'dot', value }); + continue; } - return `(?:${result})`; - } - let isPadded = hasPadding(min) || hasPadding(max); - let state = { min, max, a, b }; - let positives = []; - let negatives = []; + /** + * Text + */ - if (isPadded) { - state.isPadded = isPadded; - state.maxLen = String(state.max).length; + push({ type: 'text', value }); } - if (a < 0) { - let newMin = b < 0 ? Math.abs(b) : 1; - negatives = splitToPatterns(newMin, Math.abs(a), state, opts); - a = state.a = 0; - } - - if (b >= 0) { - positives = splitToPatterns(a, b, state, opts); - } + // Mark imbalanced braces and brackets as invalid + do { + block = stack.pop(); - state.negatives = negatives; - state.positives = positives; - state.result = collatePatterns(negatives, positives, opts); + if (block.type !== 'root') { + block.nodes.forEach(node => { + if (!node.nodes) { + if (node.type === 'open') node.isOpen = true; + if (node.type === 'close') node.isClose = true; + if (!node.nodes) node.type = 'text'; + node.invalid = true; + } + }); - if (opts.capture === true) { - state.result = `(${state.result})`; - } else if (opts.wrap !== false && (positives.length + negatives.length) > 1) { - state.result = `(?:${state.result})`; - } + // get the location of the block on parent.nodes (block's siblings) + let parent = stack[stack.length - 1]; + let index = parent.nodes.indexOf(block); + // replace the (invalid) block with it's nodes + parent.nodes.splice(index, 1, ...block.nodes); + } + } while (stack.length > 0); - toRegexRange.cache[cacheKey] = state; - return state.result; + push({ type: 'eos' }); + return ast; }; -function collatePatterns(neg, pos, options) { - let onlyNegative = filterPatterns(neg, pos, '-', false, options) || []; - let onlyPositive = filterPatterns(pos, neg, '', false, options) || []; - let intersected = filterPatterns(neg, pos, '-?', true, options) || []; - let subpatterns = onlyNegative.concat(intersected).concat(onlyPositive); - return subpatterns.join('|'); -} +module.exports = parse; -function splitToRanges(min, max) { - let nines = 1; - let zeros = 1; - let stop = countNines(min, nines); - let stops = new Set([max]); +/***/ }), +/* 313 */ +/***/ (function(module, exports, __webpack_require__) { - while (min <= stop && stop <= max) { - stops.add(stop); - nines += 1; - stop = countNines(min, nines); - } +"use strict"; - stop = countZeros(max + 1, zeros) - 1; - while (min < stop && stop <= max) { - stops.add(stop); - zeros += 1; - stop = countZeros(max + 1, zeros) - 1; - } +module.exports = { + MAX_LENGTH: 1024 * 64, - stops = [...stops]; - stops.sort(compare); - return stops; -} + // Digits + CHAR_0: '0', /* 0 */ + CHAR_9: '9', /* 9 */ -/** - * Convert a range to a regex pattern - * @param {Number} `start` - * @param {Number} `stop` - * @return {String} - */ + // Alphabet chars. + CHAR_UPPERCASE_A: 'A', /* A */ + CHAR_LOWERCASE_A: 'a', /* a */ + CHAR_UPPERCASE_Z: 'Z', /* Z */ + CHAR_LOWERCASE_Z: 'z', /* z */ -function rangeToPattern(start, stop, options) { - if (start === stop) { - return { pattern: start, count: [], digits: 0 }; - } + CHAR_LEFT_PARENTHESES: '(', /* ( */ + CHAR_RIGHT_PARENTHESES: ')', /* ) */ - let zipped = zip(start, stop); - let digits = zipped.length; - let pattern = ''; - let count = 0; + CHAR_ASTERISK: '*', /* * */ - for (let i = 0; i < digits; i++) { - let [startDigit, stopDigit] = zipped[i]; + // Non-alphabetic chars. + CHAR_AMPERSAND: '&', /* & */ + CHAR_AT: '@', /* @ */ + CHAR_BACKSLASH: '\\', /* \ */ + CHAR_BACKTICK: '`', /* ` */ + CHAR_CARRIAGE_RETURN: '\r', /* \r */ + CHAR_CIRCUMFLEX_ACCENT: '^', /* ^ */ + CHAR_COLON: ':', /* : */ + CHAR_COMMA: ',', /* , */ + CHAR_DOLLAR: '$', /* . */ + CHAR_DOT: '.', /* . */ + CHAR_DOUBLE_QUOTE: '"', /* " */ + CHAR_EQUAL: '=', /* = */ + CHAR_EXCLAMATION_MARK: '!', /* ! */ + CHAR_FORM_FEED: '\f', /* \f */ + CHAR_FORWARD_SLASH: '/', /* / */ + CHAR_HASH: '#', /* # */ + CHAR_HYPHEN_MINUS: '-', /* - */ + CHAR_LEFT_ANGLE_BRACKET: '<', /* < */ + CHAR_LEFT_CURLY_BRACE: '{', /* { */ + CHAR_LEFT_SQUARE_BRACKET: '[', /* [ */ + CHAR_LINE_FEED: '\n', /* \n */ + CHAR_NO_BREAK_SPACE: '\u00A0', /* \u00A0 */ + CHAR_PERCENT: '%', /* % */ + CHAR_PLUS: '+', /* + */ + CHAR_QUESTION_MARK: '?', /* ? */ + CHAR_RIGHT_ANGLE_BRACKET: '>', /* > */ + CHAR_RIGHT_CURLY_BRACE: '}', /* } */ + CHAR_RIGHT_SQUARE_BRACKET: ']', /* ] */ + CHAR_SEMICOLON: ';', /* ; */ + CHAR_SINGLE_QUOTE: '\'', /* ' */ + CHAR_SPACE: ' ', /* */ + CHAR_TAB: '\t', /* \t */ + CHAR_UNDERSCORE: '_', /* _ */ + CHAR_VERTICAL_LINE: '|', /* | */ + CHAR_ZERO_WIDTH_NOBREAK_SPACE: '\uFEFF' /* \uFEFF */ +}; - if (startDigit === stopDigit) { - pattern += startDigit; - } else if (startDigit !== '0' || stopDigit !== '9') { - pattern += toCharacterClass(startDigit, stopDigit, options); +/***/ }), +/* 314 */ +/***/ (function(module, exports, __webpack_require__) { - } else { - count++; - } - } +"use strict"; - if (count) { - pattern += options.shorthand === true ? '\\d' : '[0-9]'; - } - return { pattern, count: [count], digits }; -} +module.exports = __webpack_require__(315); -function splitToPatterns(min, max, tok, options) { - let ranges = splitToRanges(min, max); - let tokens = []; - let start = min; - let prev; - for (let i = 0; i < ranges.length; i++) { - let max = ranges[i]; - let obj = rangeToPattern(String(start), String(max), options); - let zeros = ''; +/***/ }), +/* 315 */ +/***/ (function(module, exports, __webpack_require__) { - if (!tok.isPadded && prev && prev.pattern === obj.pattern) { - if (prev.count.length > 1) { - prev.count.pop(); - } +"use strict"; - prev.count.push(obj.count[0]); - prev.string = prev.pattern + toQuantifier(prev.count); - start = max + 1; - continue; - } - if (tok.isPadded) { - zeros = padZeros(max, tok, options); - } +const path = __webpack_require__(4); +const scan = __webpack_require__(316); +const parse = __webpack_require__(319); +const utils = __webpack_require__(317); +const constants = __webpack_require__(318); +const isObject = val => val && typeof val === 'object' && !Array.isArray(val); - obj.string = zeros + obj.pattern + toQuantifier(obj.count); - tokens.push(obj); - start = max + 1; - prev = obj; +/** + * Creates a matcher function from one or more glob patterns. The + * returned function takes a string to match as its first argument, + * and returns true if the string is a match. The returned matcher + * function also takes a boolean as the second argument that, when true, + * returns an object with additional information. + * + * ```js + * const picomatch = require('picomatch'); + * // picomatch(glob[, options]); + * + * const isMatch = picomatch('*.!(*a)'); + * console.log(isMatch('a.a')); //=> false + * console.log(isMatch('a.b')); //=> true + * ``` + * @name picomatch + * @param {String|Array} `globs` One or more glob patterns. + * @param {Object=} `options` + * @return {Function=} Returns a matcher function. + * @api public + */ + +const picomatch = (glob, options, returnState = false) => { + if (Array.isArray(glob)) { + const fns = glob.map(input => picomatch(input, options, returnState)); + const arrayMatcher = str => { + for (const isMatch of fns) { + const state = isMatch(str); + if (state) return state; + } + return false; + }; + return arrayMatcher; } - return tokens; -} + const isState = isObject(glob) && glob.tokens && glob.input; -function filterPatterns(arr, comparison, prefix, intersection, options) { - let result = []; + if (glob === '' || (typeof glob !== 'string' && !isState)) { + throw new TypeError('Expected pattern to be a non-empty string'); + } - for (let ele of arr) { - let { string } = ele; + const opts = options || {}; + const posix = utils.isWindows(options); + const regex = isState + ? picomatch.compileRe(glob, options) + : picomatch.makeRe(glob, options, false, true); - // only push if _both_ are negative... - if (!intersection && !contains(comparison, 'string', string)) { - result.push(prefix + string); - } + const state = regex.state; + delete regex.state; - // or _both_ are positive - if (intersection && contains(comparison, 'string', string)) { - result.push(prefix + string); - } + let isIgnored = () => false; + if (opts.ignore) { + const ignoreOpts = { ...options, ignore: null, onMatch: null, onResult: null }; + isIgnored = picomatch(opts.ignore, ignoreOpts, returnState); } - return result; -} - -/** - * Zip strings - */ -function zip(a, b) { - let arr = []; - for (let i = 0; i < a.length; i++) arr.push([a[i], b[i]]); - return arr; -} + const matcher = (input, returnObject = false) => { + const { isMatch, match, output } = picomatch.test(input, regex, options, { glob, posix }); + const result = { glob, state, regex, posix, input, output, match, isMatch }; -function compare(a, b) { - return a > b ? 1 : b > a ? -1 : 0; -} + if (typeof opts.onResult === 'function') { + opts.onResult(result); + } -function contains(arr, key, val) { - return arr.some(ele => ele[key] === val); -} + if (isMatch === false) { + result.isMatch = false; + return returnObject ? result : false; + } -function countNines(min, len) { - return Number(String(min).slice(0, -len) + '9'.repeat(len)); -} + if (isIgnored(input)) { + if (typeof opts.onIgnore === 'function') { + opts.onIgnore(result); + } + result.isMatch = false; + return returnObject ? result : false; + } -function countZeros(integer, zeros) { - return integer - (integer % Math.pow(10, zeros)); -} + if (typeof opts.onMatch === 'function') { + opts.onMatch(result); + } + return returnObject ? result : true; + }; -function toQuantifier(digits) { - let [start = 0, stop = ''] = digits; - if (stop || start > 1) { - return `{${start + (stop ? ',' + stop : '')}}`; + if (returnState) { + matcher.state = state; } - return ''; -} -function toCharacterClass(a, b, options) { - return `[${a}${(b - a === 1) ? '' : '-'}${b}]`; -} + return matcher; +}; -function hasPadding(str) { - return /^-?(0+)\d/.test(str); -} +/** + * Test `input` with the given `regex`. This is used by the main + * `picomatch()` function to test the input string. + * + * ```js + * const picomatch = require('picomatch'); + * // picomatch.test(input, regex[, options]); + * + * console.log(picomatch.test('foo/bar', /^(?:([^/]*?)\/([^/]*?))$/)); + * // { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' } + * ``` + * @param {String} `input` String to test. + * @param {RegExp} `regex` + * @return {Object} Returns an object with matching info. + * @api public + */ -function padZeros(value, tok, options) { - if (!tok.isPadded) { - return value; +picomatch.test = (input, regex, options, { glob, posix } = {}) => { + if (typeof input !== 'string') { + throw new TypeError('Expected input to be a string'); } - let diff = Math.abs(tok.maxLen - String(value).length); - let relax = options.relaxZeros !== false; + if (input === '') { + return { isMatch: false, output: '' }; + } - switch (diff) { - case 0: - return ''; - case 1: - return relax ? '0?' : '0'; - case 2: - return relax ? '0{0,2}' : '00'; - default: { - return relax ? `0{0,${diff}}` : `0{${diff}}`; + const opts = options || {}; + const format = opts.format || (posix ? utils.toPosixSlashes : null); + let match = input === glob; + let output = (match && format) ? format(input) : input; + + if (match === false) { + output = format ? format(input) : input; + match = output === glob; + } + + if (match === false || opts.capture === true) { + if (opts.matchBase === true || opts.basename === true) { + match = picomatch.matchBase(input, regex, options, posix); + } else { + match = regex.exec(output); } } -} + + return { isMatch: Boolean(match), match, output }; +}; /** - * Cache + * Match the basename of a filepath. + * + * ```js + * const picomatch = require('picomatch'); + * // picomatch.matchBase(input, glob[, options]); + * console.log(picomatch.matchBase('foo/bar.js', '*.js'); // true + * ``` + * @param {String} `input` String to test. + * @param {RegExp|String} `glob` Glob pattern or regex created by [.makeRe](#makeRe). + * @return {Boolean} + * @api public */ -toRegexRange.cache = {}; -toRegexRange.clearCache = () => (toRegexRange.cache = {}); +picomatch.matchBase = (input, glob, options, posix = utils.isWindows(options)) => { + const regex = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options); + return regex.test(path.basename(input)); +}; /** - * Expose `toRegexRange` + * Returns true if **any** of the given glob `patterns` match the specified `string`. + * + * ```js + * const picomatch = require('picomatch'); + * // picomatch.isMatch(string, patterns[, options]); + * + * console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true + * console.log(picomatch.isMatch('a.a', 'b.*')); //=> false + * ``` + * @param {String|Array} str The string to test. + * @param {String|Array} patterns One or more glob patterns to use for matching. + * @param {Object} [options] See available [options](#options). + * @return {Boolean} Returns true if any patterns match `str` + * @api public */ -module.exports = toRegexRange; +picomatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str); +/** + * Parse a glob pattern to create the source string for a regular + * expression. + * + * ```js + * const picomatch = require('picomatch'); + * const result = picomatch.parse(pattern[, options]); + * ``` + * @param {String} `pattern` + * @param {Object} `options` + * @return {Object} Returns an object with useful properties and output to be used as a regex source string. + * @api public + */ -/***/ }), -/* 318 */ -/***/ (function(module, exports, __webpack_require__) { +picomatch.parse = (pattern, options) => { + if (Array.isArray(pattern)) return pattern.map(p => picomatch.parse(p, options)); + return parse(pattern, { ...options, fastpaths: false }); +}; -"use strict"; -/*! - * is-number +/** + * Scan a glob pattern to separate the pattern into segments. * - * Copyright (c) 2014-present, Jon Schlinkert. - * Released under the MIT License. + * ```js + * const picomatch = require('picomatch'); + * // picomatch.scan(input[, options]); + * + * const result = picomatch.scan('!./foo/*.js'); + * console.log(result); + * { prefix: '!./', + * input: '!./foo/*.js', + * start: 3, + * base: 'foo', + * glob: '*.js', + * isBrace: false, + * isBracket: false, + * isGlob: true, + * isExtglob: false, + * isGlobstar: false, + * negated: true } + * ``` + * @param {String} `input` Glob pattern to scan. + * @param {Object} `options` + * @return {Object} Returns an object with + * @api public */ +picomatch.scan = (input, options) => scan(input, options); +/** + * Create a regular expression from a parsed glob pattern. + * + * ```js + * const picomatch = require('picomatch'); + * const state = picomatch.parse('*.js'); + * // picomatch.compileRe(state[, options]); + * + * console.log(picomatch.compileRe(state)); + * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ + * ``` + * @param {String} `state` The object returned from the `.parse` method. + * @param {Object} `options` + * @return {RegExp} Returns a regex created from the given pattern. + * @api public + */ -module.exports = function(num) { - if (typeof num === 'number') { - return num - num === 0; - } - if (typeof num === 'string' && num.trim() !== '') { - return Number.isFinite ? Number.isFinite(+num) : isFinite(+num); +picomatch.compileRe = (parsed, options, returnOutput = false, returnState = false) => { + if (returnOutput === true) { + return parsed.output; } - return false; -}; - -/***/ }), -/* 319 */ -/***/ (function(module, exports, __webpack_require__) { + const opts = options || {}; + const prepend = opts.contains ? '' : '^'; + const append = opts.contains ? '' : '$'; -"use strict"; + let source = `${prepend}(?:${parsed.output})${append}`; + if (parsed && parsed.negated === true) { + source = `^(?!${source}).*$`; + } + const regex = picomatch.toRegex(source, options); + if (returnState === true) { + regex.state = parsed; + } -const fill = __webpack_require__(316); -const stringify = __webpack_require__(313); -const utils = __webpack_require__(314); + return regex; +}; -const append = (queue = '', stash = '', enclose = false) => { - let result = []; +picomatch.makeRe = (input, options, returnOutput = false, returnState = false) => { + if (!input || typeof input !== 'string') { + throw new TypeError('Expected a non-empty string'); + } - queue = [].concat(queue); - stash = [].concat(stash); + const opts = options || {}; + let parsed = { negated: false, fastpaths: true }; + let prefix = ''; + let output; - if (!stash.length) return queue; - if (!queue.length) { - return enclose ? utils.flatten(stash).map(ele => `{${ele}}`) : stash; + if (input.startsWith('./')) { + input = input.slice(2); + prefix = parsed.prefix = './'; } - for (let item of queue) { - if (Array.isArray(item)) { - for (let value of item) { - result.push(append(value, stash, enclose)); - } - } else { - for (let ele of stash) { - if (enclose === true && typeof ele === 'string') ele = `{${ele}}`; - result.push(Array.isArray(ele) ? append(item, ele, enclose) : (item + ele)); - } - } + if (opts.fastpaths !== false && (input[0] === '.' || input[0] === '*')) { + output = parse.fastpaths(input, options); } - return utils.flatten(result); -}; - -const expand = (ast, options = {}) => { - let rangeLimit = options.rangeLimit === void 0 ? 1000 : options.rangeLimit; - - let walk = (node, parent = {}) => { - node.queue = []; - - let p = parent; - let q = parent.queue; - - while (p.type !== 'brace' && p.type !== 'root' && p.parent) { - p = p.parent; - q = p.queue; - } - - if (node.invalid || node.dollar) { - q.push(append(q.pop(), stringify(node, options))); - return; - } - - if (node.type === 'brace' && node.invalid !== true && node.nodes.length === 2) { - q.push(append(q.pop(), ['{}'])); - return; - } - - if (node.nodes && node.ranges > 0) { - let args = utils.reduce(node.nodes); - - if (utils.exceedsLimit(...args, options.step, rangeLimit)) { - throw new RangeError('expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.'); - } - - let range = fill(...args, options); - if (range.length === 0) { - range = stringify(node, options); - } - - q.push(append(q.pop(), range)); - node.nodes = []; - return; - } - - let enclose = utils.encloseBrace(node); - let queue = node.queue; - let block = node; - - while (block.type !== 'brace' && block.type !== 'root' && block.parent) { - block = block.parent; - queue = block.queue; - } - for (let i = 0; i < node.nodes.length; i++) { - let child = node.nodes[i]; + if (output === undefined) { + parsed = parse(input, options); + parsed.prefix = prefix + (parsed.prefix || ''); + } else { + parsed.output = output; + } - if (child.type === 'comma' && node.type === 'brace') { - if (i === 1) queue.push(''); - queue.push(''); - continue; - } + return picomatch.compileRe(parsed, options, returnOutput, returnState); +}; - if (child.type === 'close') { - q.push(append(q.pop(), queue, enclose)); - continue; - } +/** + * Create a regular expression from the given regex source string. + * + * ```js + * const picomatch = require('picomatch'); + * // picomatch.toRegex(source[, options]); + * + * const { output } = picomatch.parse('*.js'); + * console.log(picomatch.toRegex(output)); + * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ + * ``` + * @param {String} `source` Regular expression source string. + * @param {Object} `options` + * @return {RegExp} + * @api public + */ - if (child.value && child.type !== 'open') { - queue.push(append(queue.pop(), child.value)); - continue; - } +picomatch.toRegex = (source, options) => { + try { + const opts = options || {}; + return new RegExp(source, opts.flags || (opts.nocase ? 'i' : '')); + } catch (err) { + if (options && options.debug === true) throw err; + return /$^/; + } +}; - if (child.nodes) { - walk(child, node); - } - } +/** + * Picomatch constants. + * @return {Object} + */ - return queue; - }; +picomatch.constants = constants; - return utils.flatten(walk(ast)); -}; +/** + * Expose "picomatch" + */ -module.exports = expand; +module.exports = picomatch; /***/ }), -/* 320 */ +/* 316 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const stringify = __webpack_require__(313); - -/** - * Constants - */ - +const utils = __webpack_require__(317); const { - MAX_LENGTH, - CHAR_BACKSLASH, /* \ */ - CHAR_BACKTICK, /* ` */ - CHAR_COMMA, /* , */ - CHAR_DOT, /* . */ - CHAR_LEFT_PARENTHESES, /* ( */ - CHAR_RIGHT_PARENTHESES, /* ) */ - CHAR_LEFT_CURLY_BRACE, /* { */ - CHAR_RIGHT_CURLY_BRACE, /* } */ - CHAR_LEFT_SQUARE_BRACKET, /* [ */ - CHAR_RIGHT_SQUARE_BRACKET, /* ] */ - CHAR_DOUBLE_QUOTE, /* " */ - CHAR_SINGLE_QUOTE, /* ' */ - CHAR_NO_BREAK_SPACE, - CHAR_ZERO_WIDTH_NOBREAK_SPACE -} = __webpack_require__(321); - -/** - * parse - */ + CHAR_ASTERISK, /* * */ + CHAR_AT, /* @ */ + CHAR_BACKWARD_SLASH, /* \ */ + CHAR_COMMA, /* , */ + CHAR_DOT, /* . */ + CHAR_EXCLAMATION_MARK, /* ! */ + CHAR_FORWARD_SLASH, /* / */ + CHAR_LEFT_CURLY_BRACE, /* { */ + CHAR_LEFT_PARENTHESES, /* ( */ + CHAR_LEFT_SQUARE_BRACKET, /* [ */ + CHAR_PLUS, /* + */ + CHAR_QUESTION_MARK, /* ? */ + CHAR_RIGHT_CURLY_BRACE, /* } */ + CHAR_RIGHT_PARENTHESES, /* ) */ + CHAR_RIGHT_SQUARE_BRACKET /* ] */ +} = __webpack_require__(318); -const parse = (input, options = {}) => { - if (typeof input !== 'string') { - throw new TypeError('Expected a string'); - } +const isPathSeparator = code => { + return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH; +}; - let opts = options || {}; - let max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; - if (input.length > max) { - throw new SyntaxError(`Input length (${input.length}), exceeds max characters (${max})`); +const depth = token => { + if (token.isPrefix !== true) { + token.depth = token.isGlobstar ? Infinity : 1; } +}; - let ast = { type: 'root', input, nodes: [] }; - let stack = [ast]; - let block = ast; - let prev = ast; - let brackets = 0; - let length = input.length; - let index = 0; - let depth = 0; - let value; - let memo = {}; +/** + * Quickly scans a glob pattern and returns an object with a handful of + * useful properties, like `isGlob`, `path` (the leading non-glob, if it exists), + * `glob` (the actual pattern), and `negated` (true if the path starts with `!`). + * + * ```js + * const pm = require('picomatch'); + * console.log(pm.scan('foo/bar/*.js')); + * { isGlob: true, input: 'foo/bar/*.js', base: 'foo/bar', glob: '*.js' } + * ``` + * @param {String} `str` + * @param {Object} `options` + * @return {Object} Returns an object with tokens and regex source string. + * @api public + */ - /** - * Helpers - */ +const scan = (input, options) => { + const opts = options || {}; - const advance = () => input[index++]; - const push = node => { - if (node.type === 'text' && prev.type === 'dot') { - prev.type = 'text'; - } + const length = input.length - 1; + const scanToEnd = opts.parts === true || opts.scanToEnd === true; + const slashes = []; + const tokens = []; + const parts = []; - if (prev && prev.type === 'text' && node.type === 'text') { - prev.value += node.value; - return; - } + let str = input; + let index = -1; + let start = 0; + let lastIndex = 0; + let isBrace = false; + let isBracket = false; + let isGlob = false; + let isExtglob = false; + let isGlobstar = false; + let braceEscaped = false; + let backslashes = false; + let negated = false; + let finished = false; + let braces = 0; + let prev; + let code; + let token = { value: '', depth: 0, isGlob: false }; - block.nodes.push(node); - node.parent = block; - node.prev = prev; - prev = node; - return node; + const eos = () => index >= length; + const peek = () => str.charCodeAt(index + 1); + const advance = () => { + prev = code; + return str.charCodeAt(++index); }; - push({ type: 'bos' }); - while (index < length) { - block = stack[stack.length - 1]; - value = advance(); + code = advance(); + let next; - /** - * Invalid chars - */ + if (code === CHAR_BACKWARD_SLASH) { + backslashes = token.backslashes = true; + code = advance(); - if (value === CHAR_ZERO_WIDTH_NOBREAK_SPACE || value === CHAR_NO_BREAK_SPACE) { + if (code === CHAR_LEFT_CURLY_BRACE) { + braceEscaped = true; + } continue; } - /** - * Escaped chars - */ - - if (value === CHAR_BACKSLASH) { - push({ type: 'text', value: (options.keepEscaping ? value : '') + advance() }); - continue; - } + if (braceEscaped === true || code === CHAR_LEFT_CURLY_BRACE) { + braces++; - /** - * Right square bracket (literal): ']' - */ + while (eos() !== true && (code = advance())) { + if (code === CHAR_BACKWARD_SLASH) { + backslashes = token.backslashes = true; + advance(); + continue; + } - if (value === CHAR_RIGHT_SQUARE_BRACKET) { - push({ type: 'text', value: '\\' + value }); - continue; - } + if (code === CHAR_LEFT_CURLY_BRACE) { + braces++; + continue; + } - /** - * Left square bracket: '[' - */ + if (braceEscaped !== true && code === CHAR_DOT && (code = advance()) === CHAR_DOT) { + isBrace = token.isBrace = true; + isGlob = token.isGlob = true; + finished = true; - if (value === CHAR_LEFT_SQUARE_BRACKET) { - brackets++; + if (scanToEnd === true) { + continue; + } - let closed = true; - let next; + break; + } - while (index < length && (next = advance())) { - value += next; + if (braceEscaped !== true && code === CHAR_COMMA) { + isBrace = token.isBrace = true; + isGlob = token.isGlob = true; + finished = true; - if (next === CHAR_LEFT_SQUARE_BRACKET) { - brackets++; - continue; - } + if (scanToEnd === true) { + continue; + } - if (next === CHAR_BACKSLASH) { - value += advance(); - continue; + break; } - if (next === CHAR_RIGHT_SQUARE_BRACKET) { - brackets--; + if (code === CHAR_RIGHT_CURLY_BRACE) { + braces--; - if (brackets === 0) { + if (braces === 0) { + braceEscaped = false; + isBrace = token.isBrace = true; + finished = true; break; } } } - push({ type: 'text', value }); - continue; - } - - /** - * Parentheses - */ + if (scanToEnd === true) { + continue; + } - if (value === CHAR_LEFT_PARENTHESES) { - block = push({ type: 'paren', nodes: [] }); - stack.push(block); - push({ type: 'text', value }); - continue; + break; } - if (value === CHAR_RIGHT_PARENTHESES) { - if (block.type !== 'paren') { - push({ type: 'text', value }); + if (code === CHAR_FORWARD_SLASH) { + slashes.push(index); + tokens.push(token); + token = { value: '', depth: 0, isGlob: false }; + + if (finished === true) continue; + if (prev === CHAR_DOT && index === (start + 1)) { + start += 2; continue; } - block = stack.pop(); - push({ type: 'text', value }); - block = stack[stack.length - 1]; + + lastIndex = index + 1; continue; } - /** - * Quotes: '|"|` - */ + if (opts.noext !== true) { + const isExtglobChar = code === CHAR_PLUS + || code === CHAR_AT + || code === CHAR_ASTERISK + || code === CHAR_QUESTION_MARK + || code === CHAR_EXCLAMATION_MARK; - if (value === CHAR_DOUBLE_QUOTE || value === CHAR_SINGLE_QUOTE || value === CHAR_BACKTICK) { - let open = value; - let next; + if (isExtglobChar === true && peek() === CHAR_LEFT_PARENTHESES) { + isGlob = token.isGlob = true; + isExtglob = token.isExtglob = true; + finished = true; - if (options.keepQuotes !== true) { - value = ''; - } + if (scanToEnd === true) { + while (eos() !== true && (code = advance())) { + if (code === CHAR_BACKWARD_SLASH) { + backslashes = token.backslashes = true; + code = advance(); + continue; + } - while (index < length && (next = advance())) { - if (next === CHAR_BACKSLASH) { - value += next + advance(); + if (code === CHAR_RIGHT_PARENTHESES) { + isGlob = token.isGlob = true; + finished = true; + break; + } + } continue; } + break; + } + } - if (next === open) { - if (options.keepQuotes === true) value += next; - break; - } + if (code === CHAR_ASTERISK) { + if (prev === CHAR_ASTERISK) isGlobstar = token.isGlobstar = true; + isGlob = token.isGlob = true; + finished = true; - value += next; + if (scanToEnd === true) { + continue; } + break; + } - push({ type: 'text', value }); - continue; + if (code === CHAR_QUESTION_MARK) { + isGlob = token.isGlob = true; + finished = true; + + if (scanToEnd === true) { + continue; + } + break; } - /** - * Left curly brace: '{' - */ + if (code === CHAR_LEFT_SQUARE_BRACKET) { + while (eos() !== true && (next = advance())) { + if (next === CHAR_BACKWARD_SLASH) { + backslashes = token.backslashes = true; + advance(); + continue; + } - if (value === CHAR_LEFT_CURLY_BRACE) { - depth++; + if (next === CHAR_RIGHT_SQUARE_BRACKET) { + isBracket = token.isBracket = true; + isGlob = token.isGlob = true; + finished = true; - let dollar = prev.value && prev.value.slice(-1) === '$' || block.dollar === true; - let brace = { - type: 'brace', - open: true, - close: false, - dollar, - depth, - commas: 0, - ranges: 0, - nodes: [] - }; + if (scanToEnd === true) { + continue; + } + break; + } + } + } - block = push(brace); - stack.push(block); - push({ type: 'open', value }); + if (opts.nonegate !== true && code === CHAR_EXCLAMATION_MARK && index === start) { + negated = token.negated = true; + start++; continue; } - /** - * Right curly brace: '}' - */ + if (opts.noparen !== true && code === CHAR_LEFT_PARENTHESES) { + isGlob = token.isGlob = true; - if (value === CHAR_RIGHT_CURLY_BRACE) { - if (block.type !== 'brace') { - push({ type: 'text', value }); + if (scanToEnd === true) { + while (eos() !== true && (code = advance())) { + if (code === CHAR_LEFT_PARENTHESES) { + backslashes = token.backslashes = true; + code = advance(); + continue; + } + + if (code === CHAR_RIGHT_PARENTHESES) { + finished = true; + break; + } + } continue; } + break; + } - let type = 'close'; - block = stack.pop(); - block.close = true; + if (isGlob === true) { + finished = true; - push({ type, value }); - depth--; + if (scanToEnd === true) { + continue; + } - block = stack[stack.length - 1]; - continue; + break; } + } - /** - * Comma: ',' - */ + if (opts.noext === true) { + isExtglob = false; + isGlob = false; + } - if (value === CHAR_COMMA && depth > 0) { - if (block.ranges > 0) { - block.ranges = 0; - let open = block.nodes.shift(); - block.nodes = [open, { type: 'text', value: stringify(block) }]; - } + let base = str; + let prefix = ''; + let glob = ''; - push({ type: 'comma', value }); - block.commas++; - continue; + if (start > 0) { + prefix = str.slice(0, start); + str = str.slice(start); + lastIndex -= start; + } + + if (base && isGlob === true && lastIndex > 0) { + base = str.slice(0, lastIndex); + glob = str.slice(lastIndex); + } else if (isGlob === true) { + base = ''; + glob = str; + } else { + base = str; + } + + if (base && base !== '' && base !== '/' && base !== str) { + if (isPathSeparator(base.charCodeAt(base.length - 1))) { + base = base.slice(0, -1); } + } - /** - * Dot: '.' - */ + if (opts.unescape === true) { + if (glob) glob = utils.removeBackslashes(glob); - if (value === CHAR_DOT && depth > 0 && block.commas === 0) { - let siblings = block.nodes; + if (base && backslashes === true) { + base = utils.removeBackslashes(base); + } + } - if (depth === 0 || siblings.length === 0) { - push({ type: 'text', value }); - continue; - } + const state = { + prefix, + input, + start, + base, + glob, + isBrace, + isBracket, + isGlob, + isExtglob, + isGlobstar, + negated + }; - if (prev.type === 'dot') { - block.range = []; - prev.value += value; - prev.type = 'range'; + if (opts.tokens === true) { + state.maxDepth = 0; + if (!isPathSeparator(code)) { + tokens.push(token); + } + state.tokens = tokens; + } - if (block.nodes.length !== 3 && block.nodes.length !== 5) { - block.invalid = true; - block.ranges = 0; - prev.type = 'text'; - continue; - } + if (opts.parts === true || opts.tokens === true) { + let prevIndex; - block.ranges++; - block.args = []; - continue; + for (let idx = 0; idx < slashes.length; idx++) { + const n = prevIndex ? prevIndex + 1 : start; + const i = slashes[idx]; + const value = input.slice(n, i); + if (opts.tokens) { + if (idx === 0 && start !== 0) { + tokens[idx].isPrefix = true; + tokens[idx].value = prefix; + } else { + tokens[idx].value = value; + } + depth(tokens[idx]); + state.maxDepth += tokens[idx].depth; + } + if (idx !== 0 || value !== '') { + parts.push(value); } + prevIndex = i; + } - if (prev.type === 'range') { - siblings.pop(); + if (prevIndex && prevIndex + 1 < input.length) { + const value = input.slice(prevIndex + 1); + parts.push(value); - let before = siblings[siblings.length - 1]; - before.value += prev.value + value; - prev = before; - block.ranges--; - continue; + if (opts.tokens) { + tokens[tokens.length - 1].value = value; + depth(tokens[tokens.length - 1]); + state.maxDepth += tokens[tokens.length - 1].depth; } - - push({ type: 'dot', value }); - continue; } - /** - * Text - */ - - push({ type: 'text', value }); + state.slashes = slashes; + state.parts = parts; } - // Mark imbalanced braces and brackets as invalid - do { - block = stack.pop(); - - if (block.type !== 'root') { - block.nodes.forEach(node => { - if (!node.nodes) { - if (node.type === 'open') node.isOpen = true; - if (node.type === 'close') node.isClose = true; - if (!node.nodes) node.type = 'text'; - node.invalid = true; - } - }); - - // get the location of the block on parent.nodes (block's siblings) - let parent = stack[stack.length - 1]; - let index = parent.nodes.indexOf(block); - // replace the (invalid) block with it's nodes - parent.nodes.splice(index, 1, ...block.nodes); - } - } while (stack.length > 0); - - push({ type: 'eos' }); - return ast; + return state; }; -module.exports = parse; +module.exports = scan; /***/ }), -/* 321 */ +/* 317 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -module.exports = { - MAX_LENGTH: 1024 * 64, - - // Digits - CHAR_0: '0', /* 0 */ - CHAR_9: '9', /* 9 */ - - // Alphabet chars. - CHAR_UPPERCASE_A: 'A', /* A */ - CHAR_LOWERCASE_A: 'a', /* a */ - CHAR_UPPERCASE_Z: 'Z', /* Z */ - CHAR_LOWERCASE_Z: 'z', /* z */ +const path = __webpack_require__(4); +const win32 = process.platform === 'win32'; +const { + REGEX_BACKSLASH, + REGEX_REMOVE_BACKSLASH, + REGEX_SPECIAL_CHARS, + REGEX_SPECIAL_CHARS_GLOBAL +} = __webpack_require__(318); - CHAR_LEFT_PARENTHESES: '(', /* ( */ - CHAR_RIGHT_PARENTHESES: ')', /* ) */ +exports.isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val); +exports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str); +exports.isRegexChar = str => str.length === 1 && exports.hasRegexChars(str); +exports.escapeRegex = str => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, '\\$1'); +exports.toPosixSlashes = str => str.replace(REGEX_BACKSLASH, '/'); - CHAR_ASTERISK: '*', /* * */ +exports.removeBackslashes = str => { + return str.replace(REGEX_REMOVE_BACKSLASH, match => { + return match === '\\' ? '' : match; + }); +}; - // Non-alphabetic chars. - CHAR_AMPERSAND: '&', /* & */ - CHAR_AT: '@', /* @ */ - CHAR_BACKSLASH: '\\', /* \ */ - CHAR_BACKTICK: '`', /* ` */ - CHAR_CARRIAGE_RETURN: '\r', /* \r */ - CHAR_CIRCUMFLEX_ACCENT: '^', /* ^ */ - CHAR_COLON: ':', /* : */ - CHAR_COMMA: ',', /* , */ - CHAR_DOLLAR: '$', /* . */ - CHAR_DOT: '.', /* . */ - CHAR_DOUBLE_QUOTE: '"', /* " */ - CHAR_EQUAL: '=', /* = */ - CHAR_EXCLAMATION_MARK: '!', /* ! */ - CHAR_FORM_FEED: '\f', /* \f */ - CHAR_FORWARD_SLASH: '/', /* / */ - CHAR_HASH: '#', /* # */ - CHAR_HYPHEN_MINUS: '-', /* - */ - CHAR_LEFT_ANGLE_BRACKET: '<', /* < */ - CHAR_LEFT_CURLY_BRACE: '{', /* { */ - CHAR_LEFT_SQUARE_BRACKET: '[', /* [ */ - CHAR_LINE_FEED: '\n', /* \n */ - CHAR_NO_BREAK_SPACE: '\u00A0', /* \u00A0 */ - CHAR_PERCENT: '%', /* % */ - CHAR_PLUS: '+', /* + */ - CHAR_QUESTION_MARK: '?', /* ? */ - CHAR_RIGHT_ANGLE_BRACKET: '>', /* > */ - CHAR_RIGHT_CURLY_BRACE: '}', /* } */ - CHAR_RIGHT_SQUARE_BRACKET: ']', /* ] */ - CHAR_SEMICOLON: ';', /* ; */ - CHAR_SINGLE_QUOTE: '\'', /* ' */ - CHAR_SPACE: ' ', /* */ - CHAR_TAB: '\t', /* \t */ - CHAR_UNDERSCORE: '_', /* _ */ - CHAR_VERTICAL_LINE: '|', /* | */ - CHAR_ZERO_WIDTH_NOBREAK_SPACE: '\uFEFF' /* \uFEFF */ +exports.supportsLookbehinds = () => { + const segs = process.version.slice(1).split('.').map(Number); + if (segs.length === 3 && segs[0] >= 9 || (segs[0] === 8 && segs[1] >= 10)) { + return true; + } + return false; }; +exports.isWindows = options => { + if (options && typeof options.windows === 'boolean') { + return options.windows; + } + return win32 === true || path.sep === '\\'; +}; -/***/ }), -/* 322 */ -/***/ (function(module, exports, __webpack_require__) { +exports.escapeLast = (input, char, lastIdx) => { + const idx = input.lastIndexOf(char, lastIdx); + if (idx === -1) return input; + if (input[idx - 1] === '\\') return exports.escapeLast(input, char, idx - 1); + return `${input.slice(0, idx)}\\${input.slice(idx)}`; +}; -"use strict"; +exports.removePrefix = (input, state = {}) => { + let output = input; + if (output.startsWith('./')) { + output = output.slice(2); + state.prefix = './'; + } + return output; +}; +exports.wrapOutput = (input, state = {}, options = {}) => { + const prepend = options.contains ? '' : '^'; + const append = options.contains ? '' : '$'; -module.exports = __webpack_require__(323); + let output = `${prepend}(?:${input})${append}`; + if (state.negated === true) { + output = `(?:^(?!${output}).*$)`; + } + return output; +}; /***/ }), -/* 323 */ +/* 318 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const path = __webpack_require__(4); -const scan = __webpack_require__(324); -const parse = __webpack_require__(327); -const utils = __webpack_require__(325); -const constants = __webpack_require__(326); -const isObject = val => val && typeof val === 'object' && !Array.isArray(val); +const WIN_SLASH = '\\\\/'; +const WIN_NO_SLASH = `[^${WIN_SLASH}]`; /** - * Creates a matcher function from one or more glob patterns. The - * returned function takes a string to match as its first argument, - * and returns true if the string is a match. The returned matcher - * function also takes a boolean as the second argument that, when true, - * returns an object with additional information. - * - * ```js - * const picomatch = require('picomatch'); - * // picomatch(glob[, options]); - * - * const isMatch = picomatch('*.!(*a)'); - * console.log(isMatch('a.a')); //=> false - * console.log(isMatch('a.b')); //=> true - * ``` - * @name picomatch - * @param {String|Array} `globs` One or more glob patterns. - * @param {Object=} `options` - * @return {Function=} Returns a matcher function. - * @api public + * Posix glob regex */ -const picomatch = (glob, options, returnState = false) => { - if (Array.isArray(glob)) { - const fns = glob.map(input => picomatch(input, options, returnState)); - const arrayMatcher = str => { - for (const isMatch of fns) { - const state = isMatch(str); - if (state) return state; - } - return false; - }; - return arrayMatcher; - } - - const isState = isObject(glob) && glob.tokens && glob.input; - - if (glob === '' || (typeof glob !== 'string' && !isState)) { - throw new TypeError('Expected pattern to be a non-empty string'); - } - - const opts = options || {}; - const posix = utils.isWindows(options); - const regex = isState - ? picomatch.compileRe(glob, options) - : picomatch.makeRe(glob, options, false, true); - - const state = regex.state; - delete regex.state; - - let isIgnored = () => false; - if (opts.ignore) { - const ignoreOpts = { ...options, ignore: null, onMatch: null, onResult: null }; - isIgnored = picomatch(opts.ignore, ignoreOpts, returnState); - } - - const matcher = (input, returnObject = false) => { - const { isMatch, match, output } = picomatch.test(input, regex, options, { glob, posix }); - const result = { glob, state, regex, posix, input, output, match, isMatch }; - - if (typeof opts.onResult === 'function') { - opts.onResult(result); - } - - if (isMatch === false) { - result.isMatch = false; - return returnObject ? result : false; - } +const DOT_LITERAL = '\\.'; +const PLUS_LITERAL = '\\+'; +const QMARK_LITERAL = '\\?'; +const SLASH_LITERAL = '\\/'; +const ONE_CHAR = '(?=.)'; +const QMARK = '[^/]'; +const END_ANCHOR = `(?:${SLASH_LITERAL}|$)`; +const START_ANCHOR = `(?:^|${SLASH_LITERAL})`; +const DOTS_SLASH = `${DOT_LITERAL}{1,2}${END_ANCHOR}`; +const NO_DOT = `(?!${DOT_LITERAL})`; +const NO_DOTS = `(?!${START_ANCHOR}${DOTS_SLASH})`; +const NO_DOT_SLASH = `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`; +const NO_DOTS_SLASH = `(?!${DOTS_SLASH})`; +const QMARK_NO_DOT = `[^.${SLASH_LITERAL}]`; +const STAR = `${QMARK}*?`; - if (isIgnored(input)) { - if (typeof opts.onIgnore === 'function') { - opts.onIgnore(result); - } - result.isMatch = false; - return returnObject ? result : false; - } +const POSIX_CHARS = { + DOT_LITERAL, + PLUS_LITERAL, + QMARK_LITERAL, + SLASH_LITERAL, + ONE_CHAR, + QMARK, + END_ANCHOR, + DOTS_SLASH, + NO_DOT, + NO_DOTS, + NO_DOT_SLASH, + NO_DOTS_SLASH, + QMARK_NO_DOT, + STAR, + START_ANCHOR +}; - if (typeof opts.onMatch === 'function') { - opts.onMatch(result); - } - return returnObject ? result : true; - }; +/** + * Windows glob regex + */ - if (returnState) { - matcher.state = state; - } +const WINDOWS_CHARS = { + ...POSIX_CHARS, - return matcher; + SLASH_LITERAL: `[${WIN_SLASH}]`, + QMARK: WIN_NO_SLASH, + STAR: `${WIN_NO_SLASH}*?`, + DOTS_SLASH: `${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$)`, + NO_DOT: `(?!${DOT_LITERAL})`, + NO_DOTS: `(?!(?:^|[${WIN_SLASH}])${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`, + NO_DOT_SLASH: `(?!${DOT_LITERAL}{0,1}(?:[${WIN_SLASH}]|$))`, + NO_DOTS_SLASH: `(?!${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`, + QMARK_NO_DOT: `[^.${WIN_SLASH}]`, + START_ANCHOR: `(?:^|[${WIN_SLASH}])`, + END_ANCHOR: `(?:[${WIN_SLASH}]|$)` }; /** - * Test `input` with the given `regex`. This is used by the main - * `picomatch()` function to test the input string. - * - * ```js - * const picomatch = require('picomatch'); - * // picomatch.test(input, regex[, options]); - * - * console.log(picomatch.test('foo/bar', /^(?:([^/]*?)\/([^/]*?))$/)); - * // { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' } - * ``` - * @param {String} `input` String to test. - * @param {RegExp} `regex` - * @return {Object} Returns an object with matching info. - * @api public + * POSIX Bracket Regex */ -picomatch.test = (input, regex, options, { glob, posix } = {}) => { - if (typeof input !== 'string') { - throw new TypeError('Expected input to be a string'); - } +const POSIX_REGEX_SOURCE = { + alnum: 'a-zA-Z0-9', + alpha: 'a-zA-Z', + ascii: '\\x00-\\x7F', + blank: ' \\t', + cntrl: '\\x00-\\x1F\\x7F', + digit: '0-9', + graph: '\\x21-\\x7E', + lower: 'a-z', + print: '\\x20-\\x7E ', + punct: '\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~', + space: ' \\t\\r\\n\\v\\f', + upper: 'A-Z', + word: 'A-Za-z0-9_', + xdigit: 'A-Fa-f0-9' +}; - if (input === '') { - return { isMatch: false, output: '' }; - } +module.exports = { + MAX_LENGTH: 1024 * 64, + POSIX_REGEX_SOURCE, - const opts = options || {}; - const format = opts.format || (posix ? utils.toPosixSlashes : null); - let match = input === glob; - let output = (match && format) ? format(input) : input; + // regular expressions + REGEX_BACKSLASH: /\\(?![*+?^${}(|)[\]])/g, + REGEX_NON_SPECIAL_CHARS: /^[^@![\].,$*+?^{}()|\\/]+/, + REGEX_SPECIAL_CHARS: /[-*+?.^${}(|)[\]]/, + REGEX_SPECIAL_CHARS_BACKREF: /(\\?)((\W)(\3*))/g, + REGEX_SPECIAL_CHARS_GLOBAL: /([-*+?.^${}(|)[\]])/g, + REGEX_REMOVE_BACKSLASH: /(?:\[.*?[^\\]\]|\\(?=.))/g, - if (match === false) { - output = format ? format(input) : input; - match = output === glob; - } + // Replace globs with equivalent patterns to reduce parsing time. + REPLACEMENTS: { + '***': '*', + '**/**': '**', + '**/**/**': '**' + }, - if (match === false || opts.capture === true) { - if (opts.matchBase === true || opts.basename === true) { - match = picomatch.matchBase(input, regex, options, posix); - } else { - match = regex.exec(output); - } - } + // Digits + CHAR_0: 48, /* 0 */ + CHAR_9: 57, /* 9 */ - return { isMatch: Boolean(match), match, output }; -}; + // Alphabet chars. + CHAR_UPPERCASE_A: 65, /* A */ + CHAR_LOWERCASE_A: 97, /* a */ + CHAR_UPPERCASE_Z: 90, /* Z */ + CHAR_LOWERCASE_Z: 122, /* z */ -/** - * Match the basename of a filepath. - * - * ```js - * const picomatch = require('picomatch'); - * // picomatch.matchBase(input, glob[, options]); - * console.log(picomatch.matchBase('foo/bar.js', '*.js'); // true - * ``` - * @param {String} `input` String to test. - * @param {RegExp|String} `glob` Glob pattern or regex created by [.makeRe](#makeRe). - * @return {Boolean} - * @api public - */ + CHAR_LEFT_PARENTHESES: 40, /* ( */ + CHAR_RIGHT_PARENTHESES: 41, /* ) */ -picomatch.matchBase = (input, glob, options, posix = utils.isWindows(options)) => { - const regex = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options); - return regex.test(path.basename(input)); -}; + CHAR_ASTERISK: 42, /* * */ -/** - * Returns true if **any** of the given glob `patterns` match the specified `string`. - * - * ```js - * const picomatch = require('picomatch'); - * // picomatch.isMatch(string, patterns[, options]); - * - * console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true - * console.log(picomatch.isMatch('a.a', 'b.*')); //=> false - * ``` - * @param {String|Array} str The string to test. - * @param {String|Array} patterns One or more glob patterns to use for matching. - * @param {Object} [options] See available [options](#options). - * @return {Boolean} Returns true if any patterns match `str` - * @api public - */ + // Non-alphabetic chars. + CHAR_AMPERSAND: 38, /* & */ + CHAR_AT: 64, /* @ */ + CHAR_BACKWARD_SLASH: 92, /* \ */ + CHAR_CARRIAGE_RETURN: 13, /* \r */ + CHAR_CIRCUMFLEX_ACCENT: 94, /* ^ */ + CHAR_COLON: 58, /* : */ + CHAR_COMMA: 44, /* , */ + CHAR_DOT: 46, /* . */ + CHAR_DOUBLE_QUOTE: 34, /* " */ + CHAR_EQUAL: 61, /* = */ + CHAR_EXCLAMATION_MARK: 33, /* ! */ + CHAR_FORM_FEED: 12, /* \f */ + CHAR_FORWARD_SLASH: 47, /* / */ + CHAR_GRAVE_ACCENT: 96, /* ` */ + CHAR_HASH: 35, /* # */ + CHAR_HYPHEN_MINUS: 45, /* - */ + CHAR_LEFT_ANGLE_BRACKET: 60, /* < */ + CHAR_LEFT_CURLY_BRACE: 123, /* { */ + CHAR_LEFT_SQUARE_BRACKET: 91, /* [ */ + CHAR_LINE_FEED: 10, /* \n */ + CHAR_NO_BREAK_SPACE: 160, /* \u00A0 */ + CHAR_PERCENT: 37, /* % */ + CHAR_PLUS: 43, /* + */ + CHAR_QUESTION_MARK: 63, /* ? */ + CHAR_RIGHT_ANGLE_BRACKET: 62, /* > */ + CHAR_RIGHT_CURLY_BRACE: 125, /* } */ + CHAR_RIGHT_SQUARE_BRACKET: 93, /* ] */ + CHAR_SEMICOLON: 59, /* ; */ + CHAR_SINGLE_QUOTE: 39, /* ' */ + CHAR_SPACE: 32, /* */ + CHAR_TAB: 9, /* \t */ + CHAR_UNDERSCORE: 95, /* _ */ + CHAR_VERTICAL_LINE: 124, /* | */ + CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279, /* \uFEFF */ -picomatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str); + SEP: path.sep, -/** - * Parse a glob pattern to create the source string for a regular - * expression. - * - * ```js - * const picomatch = require('picomatch'); - * const result = picomatch.parse(pattern[, options]); - * ``` - * @param {String} `pattern` - * @param {Object} `options` - * @return {Object} Returns an object with useful properties and output to be used as a regex source string. - * @api public - */ + /** + * Create EXTGLOB_CHARS + */ -picomatch.parse = (pattern, options) => { - if (Array.isArray(pattern)) return pattern.map(p => picomatch.parse(p, options)); - return parse(pattern, { ...options, fastpaths: false }); -}; + extglobChars(chars) { + return { + '!': { type: 'negate', open: '(?:(?!(?:', close: `))${chars.STAR})` }, + '?': { type: 'qmark', open: '(?:', close: ')?' }, + '+': { type: 'plus', open: '(?:', close: ')+' }, + '*': { type: 'star', open: '(?:', close: ')*' }, + '@': { type: 'at', open: '(?:', close: ')' } + }; + }, -/** - * Scan a glob pattern to separate the pattern into segments. - * - * ```js - * const picomatch = require('picomatch'); - * // picomatch.scan(input[, options]); - * - * const result = picomatch.scan('!./foo/*.js'); - * console.log(result); - * { prefix: '!./', - * input: '!./foo/*.js', - * start: 3, - * base: 'foo', - * glob: '*.js', - * isBrace: false, - * isBracket: false, - * isGlob: true, - * isExtglob: false, - * isGlobstar: false, - * negated: true } - * ``` - * @param {String} `input` Glob pattern to scan. - * @param {Object} `options` - * @return {Object} Returns an object with - * @api public - */ + /** + * Create GLOB_CHARS + */ -picomatch.scan = (input, options) => scan(input, options); + globChars(win32) { + return win32 === true ? WINDOWS_CHARS : POSIX_CHARS; + } +}; -/** - * Create a regular expression from a parsed glob pattern. - * - * ```js - * const picomatch = require('picomatch'); - * const state = picomatch.parse('*.js'); - * // picomatch.compileRe(state[, options]); - * - * console.log(picomatch.compileRe(state)); - * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ - * ``` - * @param {String} `state` The object returned from the `.parse` method. - * @param {Object} `options` - * @return {RegExp} Returns a regex created from the given pattern. - * @api public - */ -picomatch.compileRe = (parsed, options, returnOutput = false, returnState = false) => { - if (returnOutput === true) { - return parsed.output; - } +/***/ }), +/* 319 */ +/***/ (function(module, exports, __webpack_require__) { - const opts = options || {}; - const prepend = opts.contains ? '' : '^'; - const append = opts.contains ? '' : '$'; +"use strict"; - let source = `${prepend}(?:${parsed.output})${append}`; - if (parsed && parsed.negated === true) { - source = `^(?!${source}).*$`; - } - const regex = picomatch.toRegex(source, options); - if (returnState === true) { - regex.state = parsed; - } +const constants = __webpack_require__(318); +const utils = __webpack_require__(317); - return regex; -}; +/** + * Constants + */ -picomatch.makeRe = (input, options, returnOutput = false, returnState = false) => { - if (!input || typeof input !== 'string') { - throw new TypeError('Expected a non-empty string'); - } +const { + MAX_LENGTH, + POSIX_REGEX_SOURCE, + REGEX_NON_SPECIAL_CHARS, + REGEX_SPECIAL_CHARS_BACKREF, + REPLACEMENTS +} = constants; - const opts = options || {}; - let parsed = { negated: false, fastpaths: true }; - let prefix = ''; - let output; +/** + * Helpers + */ - if (input.startsWith('./')) { - input = input.slice(2); - prefix = parsed.prefix = './'; +const expandRange = (args, options) => { + if (typeof options.expandRange === 'function') { + return options.expandRange(...args, options); } - if (opts.fastpaths !== false && (input[0] === '.' || input[0] === '*')) { - output = parse.fastpaths(input, options); - } + args.sort(); + const value = `[${args.join('-')}]`; - if (output === undefined) { - parsed = parse(input, options); - parsed.prefix = prefix + (parsed.prefix || ''); - } else { - parsed.output = output; + try { + /* eslint-disable-next-line no-new */ + new RegExp(value); + } catch (ex) { + return args.map(v => utils.escapeRegex(v)).join('..'); } - return picomatch.compileRe(parsed, options, returnOutput, returnState); + return value; }; /** - * Create a regular expression from the given regex source string. - * - * ```js - * const picomatch = require('picomatch'); - * // picomatch.toRegex(source[, options]); - * - * const { output } = picomatch.parse('*.js'); - * console.log(picomatch.toRegex(output)); - * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ - * ``` - * @param {String} `source` Regular expression source string. - * @param {Object} `options` - * @return {RegExp} - * @api public + * Create the message for a syntax error */ -picomatch.toRegex = (source, options) => { - try { - const opts = options || {}; - return new RegExp(source, opts.flags || (opts.nocase ? 'i' : '')); - } catch (err) { - if (options && options.debug === true) throw err; - return /$^/; - } +const syntaxError = (type, char) => { + return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`; }; /** - * Picomatch constants. + * Parse the given input string. + * @param {String} input + * @param {Object} options * @return {Object} */ -picomatch.constants = constants; +const parse = (input, options) => { + if (typeof input !== 'string') { + throw new TypeError('Expected a string'); + } -/** - * Expose "picomatch" - */ + input = REPLACEMENTS[input] || input; -module.exports = picomatch; + const opts = { ...options }; + const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; + let len = input.length; + if (len > max) { + throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); + } -/***/ }), -/* 324 */ -/***/ (function(module, exports, __webpack_require__) { + const bos = { type: 'bos', value: '', output: opts.prepend || '' }; + const tokens = [bos]; -"use strict"; + const capture = opts.capture ? '' : '?:'; + const win32 = utils.isWindows(options); + // create constants based on platform, for windows or posix + const PLATFORM_CHARS = constants.globChars(win32); + const EXTGLOB_CHARS = constants.extglobChars(PLATFORM_CHARS); -const utils = __webpack_require__(325); -const { - CHAR_ASTERISK, /* * */ - CHAR_AT, /* @ */ - CHAR_BACKWARD_SLASH, /* \ */ - CHAR_COMMA, /* , */ - CHAR_DOT, /* . */ - CHAR_EXCLAMATION_MARK, /* ! */ - CHAR_FORWARD_SLASH, /* / */ - CHAR_LEFT_CURLY_BRACE, /* { */ - CHAR_LEFT_PARENTHESES, /* ( */ - CHAR_LEFT_SQUARE_BRACKET, /* [ */ - CHAR_PLUS, /* + */ - CHAR_QUESTION_MARK, /* ? */ - CHAR_RIGHT_CURLY_BRACE, /* } */ - CHAR_RIGHT_PARENTHESES, /* ) */ - CHAR_RIGHT_SQUARE_BRACKET /* ] */ -} = __webpack_require__(326); + const { + DOT_LITERAL, + PLUS_LITERAL, + SLASH_LITERAL, + ONE_CHAR, + DOTS_SLASH, + NO_DOT, + NO_DOT_SLASH, + NO_DOTS_SLASH, + QMARK, + QMARK_NO_DOT, + STAR, + START_ANCHOR + } = PLATFORM_CHARS; -const isPathSeparator = code => { - return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH; -}; + const globstar = (opts) => { + return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; + }; -const depth = token => { - if (token.isPrefix !== true) { - token.depth = token.isGlobstar ? Infinity : 1; + const nodot = opts.dot ? '' : NO_DOT; + const qmarkNoDot = opts.dot ? QMARK : QMARK_NO_DOT; + let star = opts.bash === true ? globstar(opts) : STAR; + + if (opts.capture) { + star = `(${star})`; } -}; -/** - * Quickly scans a glob pattern and returns an object with a handful of - * useful properties, like `isGlob`, `path` (the leading non-glob, if it exists), - * `glob` (the actual pattern), and `negated` (true if the path starts with `!`). - * - * ```js - * const pm = require('picomatch'); - * console.log(pm.scan('foo/bar/*.js')); - * { isGlob: true, input: 'foo/bar/*.js', base: 'foo/bar', glob: '*.js' } - * ``` - * @param {String} `str` - * @param {Object} `options` - * @return {Object} Returns an object with tokens and regex source string. - * @api public - */ + // minimatch options support + if (typeof opts.noext === 'boolean') { + opts.noextglob = opts.noext; + } -const scan = (input, options) => { - const opts = options || {}; + const state = { + input, + index: -1, + start: 0, + dot: opts.dot === true, + consumed: '', + output: '', + prefix: '', + backtrack: false, + negated: false, + brackets: 0, + braces: 0, + parens: 0, + quotes: 0, + globstar: false, + tokens + }; - const length = input.length - 1; - const scanToEnd = opts.parts === true || opts.scanToEnd === true; - const slashes = []; - const tokens = []; - const parts = []; + input = utils.removePrefix(input, state); + len = input.length; - let str = input; - let index = -1; - let start = 0; - let lastIndex = 0; - let isBrace = false; - let isBracket = false; - let isGlob = false; - let isExtglob = false; - let isGlobstar = false; - let braceEscaped = false; - let backslashes = false; - let negated = false; - let finished = false; - let braces = 0; - let prev; - let code; - let token = { value: '', depth: 0, isGlob: false }; + const extglobs = []; + const braces = []; + const stack = []; + let prev = bos; + let value; - const eos = () => index >= length; - const peek = () => str.charCodeAt(index + 1); - const advance = () => { - prev = code; - return str.charCodeAt(++index); + /** + * Tokenizing helpers + */ + + const eos = () => state.index === len - 1; + const peek = state.peek = (n = 1) => input[state.index + n]; + const advance = state.advance = () => input[++state.index]; + const remaining = () => input.slice(state.index + 1); + const consume = (value = '', num = 0) => { + state.consumed += value; + state.index += num; + }; + const append = token => { + state.output += token.output != null ? token.output : token.value; + consume(token.value); }; - while (index < length) { - code = advance(); - let next; + const negate = () => { + let count = 1; - if (code === CHAR_BACKWARD_SLASH) { - backslashes = token.backslashes = true; - code = advance(); + while (peek() === '!' && (peek(2) !== '(' || peek(3) === '?')) { + advance(); + state.start++; + count++; + } - if (code === CHAR_LEFT_CURLY_BRACE) { - braceEscaped = true; - } - continue; + if (count % 2 === 0) { + return false; } - if (braceEscaped === true || code === CHAR_LEFT_CURLY_BRACE) { - braces++; + state.negated = true; + state.start++; + return true; + }; - while (eos() !== true && (code = advance())) { - if (code === CHAR_BACKWARD_SLASH) { - backslashes = token.backslashes = true; - advance(); - continue; - } + const increment = type => { + state[type]++; + stack.push(type); + }; - if (code === CHAR_LEFT_CURLY_BRACE) { - braces++; - continue; - } + const decrement = type => { + state[type]--; + stack.pop(); + }; - if (braceEscaped !== true && code === CHAR_DOT && (code = advance()) === CHAR_DOT) { - isBrace = token.isBrace = true; - isGlob = token.isGlob = true; - finished = true; + /** + * Push tokens onto the tokens array. This helper speeds up + * tokenizing by 1) helping us avoid backtracking as much as possible, + * and 2) helping us avoid creating extra tokens when consecutive + * characters are plain text. This improves performance and simplifies + * lookbehinds. + */ - if (scanToEnd === true) { - continue; - } + const push = tok => { + if (prev.type === 'globstar') { + const isBrace = state.braces > 0 && (tok.type === 'comma' || tok.type === 'brace'); + const isExtglob = tok.extglob === true || (extglobs.length && (tok.type === 'pipe' || tok.type === 'paren')); - break; - } + if (tok.type !== 'slash' && tok.type !== 'paren' && !isBrace && !isExtglob) { + state.output = state.output.slice(0, -prev.output.length); + prev.type = 'star'; + prev.value = '*'; + prev.output = star; + state.output += prev.output; + } + } - if (braceEscaped !== true && code === CHAR_COMMA) { - isBrace = token.isBrace = true; - isGlob = token.isGlob = true; - finished = true; + if (extglobs.length && tok.type !== 'paren' && !EXTGLOB_CHARS[tok.value]) { + extglobs[extglobs.length - 1].inner += tok.value; + } - if (scanToEnd === true) { - continue; - } + if (tok.value || tok.output) append(tok); + if (prev && prev.type === 'text' && tok.type === 'text') { + prev.value += tok.value; + prev.output = (prev.output || '') + tok.value; + return; + } - break; - } + tok.prev = prev; + tokens.push(tok); + prev = tok; + }; - if (code === CHAR_RIGHT_CURLY_BRACE) { - braces--; + const extglobOpen = (type, value) => { + const token = { ...EXTGLOB_CHARS[value], conditions: 1, inner: '' }; - if (braces === 0) { - braceEscaped = false; - isBrace = token.isBrace = true; - finished = true; - break; - } - } - } + token.prev = prev; + token.parens = state.parens; + token.output = state.output; + const output = (opts.capture ? '(' : '') + token.open; - if (scanToEnd === true) { - continue; - } + increment('parens'); + push({ type, value, output: state.output ? '' : ONE_CHAR }); + push({ type: 'paren', extglob: true, value: advance(), output }); + extglobs.push(token); + }; - break; - } + const extglobClose = token => { + let output = token.close + (opts.capture ? ')' : ''); - if (code === CHAR_FORWARD_SLASH) { - slashes.push(index); - tokens.push(token); - token = { value: '', depth: 0, isGlob: false }; + if (token.type === 'negate') { + let extglobStar = star; - if (finished === true) continue; - if (prev === CHAR_DOT && index === (start + 1)) { - start += 2; - continue; + if (token.inner && token.inner.length > 1 && token.inner.includes('/')) { + extglobStar = globstar(opts); } - lastIndex = index + 1; - continue; - } - - if (opts.noext !== true) { - const isExtglobChar = code === CHAR_PLUS - || code === CHAR_AT - || code === CHAR_ASTERISK - || code === CHAR_QUESTION_MARK - || code === CHAR_EXCLAMATION_MARK; - - if (isExtglobChar === true && peek() === CHAR_LEFT_PARENTHESES) { - isGlob = token.isGlob = true; - isExtglob = token.isExtglob = true; - finished = true; - - if (scanToEnd === true) { - while (eos() !== true && (code = advance())) { - if (code === CHAR_BACKWARD_SLASH) { - backslashes = token.backslashes = true; - code = advance(); - continue; - } + if (extglobStar !== star || eos() || /^\)+$/.test(remaining())) { + output = token.close = `)$))${extglobStar}`; + } - if (code === CHAR_RIGHT_PARENTHESES) { - isGlob = token.isGlob = true; - finished = true; - break; - } - } - continue; - } - break; + if (token.prev.type === 'bos' && eos()) { + state.negatedExtglob = true; } } - if (code === CHAR_ASTERISK) { - if (prev === CHAR_ASTERISK) isGlobstar = token.isGlobstar = true; - isGlob = token.isGlob = true; - finished = true; + push({ type: 'paren', extglob: true, value, output }); + decrement('parens'); + }; - if (scanToEnd === true) { - continue; - } - break; - } + /** + * Fast paths + */ - if (code === CHAR_QUESTION_MARK) { - isGlob = token.isGlob = true; - finished = true; + if (opts.fastpaths !== false && !/(^[*!]|[/()[\]{}"])/.test(input)) { + let backslashes = false; - if (scanToEnd === true) { - continue; + let output = input.replace(REGEX_SPECIAL_CHARS_BACKREF, (m, esc, chars, first, rest, index) => { + if (first === '\\') { + backslashes = true; + return m; } - break; - } - if (code === CHAR_LEFT_SQUARE_BRACKET) { - while (eos() !== true && (next = advance())) { - if (next === CHAR_BACKWARD_SLASH) { - backslashes = token.backslashes = true; - advance(); - continue; + if (first === '?') { + if (esc) { + return esc + first + (rest ? QMARK.repeat(rest.length) : ''); + } + if (index === 0) { + return qmarkNoDot + (rest ? QMARK.repeat(rest.length) : ''); } + return QMARK.repeat(chars.length); + } - if (next === CHAR_RIGHT_SQUARE_BRACKET) { - isBracket = token.isBracket = true; - isGlob = token.isGlob = true; - finished = true; + if (first === '.') { + return DOT_LITERAL.repeat(chars.length); + } - if (scanToEnd === true) { - continue; - } - break; + if (first === '*') { + if (esc) { + return esc + first + (rest ? star : ''); } + return star; + } + return esc ? m : `\\${m}`; + }); + + if (backslashes === true) { + if (opts.unescape === true) { + output = output.replace(/\\/g, ''); + } else { + output = output.replace(/\\+/g, m => { + return m.length % 2 === 0 ? '\\\\' : (m ? '\\' : ''); + }); } } - if (opts.nonegate !== true && code === CHAR_EXCLAMATION_MARK && index === start) { - negated = token.negated = true; - start++; + if (output === input && opts.contains === true) { + state.output = input; + return state; + } + + state.output = utils.wrapOutput(output, state, options); + return state; + } + + /** + * Tokenize input until we reach end-of-string + */ + + while (!eos()) { + value = advance(); + + if (value === '\u0000') { continue; } - if (opts.noparen !== true && code === CHAR_LEFT_PARENTHESES) { - isGlob = token.isGlob = true; + /** + * Escaped characters + */ - if (scanToEnd === true) { - while (eos() !== true && (code = advance())) { - if (code === CHAR_LEFT_PARENTHESES) { - backslashes = token.backslashes = true; - code = advance(); - continue; - } + if (value === '\\') { + const next = peek(); - if (code === CHAR_RIGHT_PARENTHESES) { - finished = true; - break; - } - } + if (next === '/' && opts.bash !== true) { continue; } - break; - } - if (isGlob === true) { - finished = true; + if (next === '.' || next === ';') { + continue; + } - if (scanToEnd === true) { + if (!next) { + value += '\\'; + push({ type: 'text', value }); continue; } - break; + // collapse slashes to reduce potential for exploits + const match = /^\\+/.exec(remaining()); + let slashes = 0; + + if (match && match[0].length > 2) { + slashes = match[0].length; + state.index += slashes; + if (slashes % 2 !== 0) { + value += '\\'; + } + } + + if (opts.unescape === true) { + value = advance() || ''; + } else { + value += advance() || ''; + } + + if (state.brackets === 0) { + push({ type: 'text', value }); + continue; + } } - } - if (opts.noext === true) { - isExtglob = false; - isGlob = false; - } + /** + * If we're inside a regex character class, continue + * until we reach the closing bracket. + */ - let base = str; - let prefix = ''; - let glob = ''; + if (state.brackets > 0 && (value !== ']' || prev.value === '[' || prev.value === '[^')) { + if (opts.posix !== false && value === ':') { + const inner = prev.value.slice(1); + if (inner.includes('[')) { + prev.posix = true; - if (start > 0) { - prefix = str.slice(0, start); - str = str.slice(start); - lastIndex -= start; - } + if (inner.includes(':')) { + const idx = prev.value.lastIndexOf('['); + const pre = prev.value.slice(0, idx); + const rest = prev.value.slice(idx + 2); + const posix = POSIX_REGEX_SOURCE[rest]; + if (posix) { + prev.value = pre + posix; + state.backtrack = true; + advance(); - if (base && isGlob === true && lastIndex > 0) { - base = str.slice(0, lastIndex); - glob = str.slice(lastIndex); - } else if (isGlob === true) { - base = ''; - glob = str; - } else { - base = str; - } + if (!bos.output && tokens.indexOf(prev) === 1) { + bos.output = ONE_CHAR; + } + continue; + } + } + } + } - if (base && base !== '' && base !== '/' && base !== str) { - if (isPathSeparator(base.charCodeAt(base.length - 1))) { - base = base.slice(0, -1); + if ((value === '[' && peek() !== ':') || (value === '-' && peek() === ']')) { + value = `\\${value}`; + } + + if (value === ']' && (prev.value === '[' || prev.value === '[^')) { + value = `\\${value}`; + } + + if (opts.posix === true && value === '!' && prev.value === '[') { + value = '^'; + } + + prev.value += value; + append({ value }); + continue; } - } - if (opts.unescape === true) { - if (glob) glob = utils.removeBackslashes(glob); + /** + * If we're inside a quoted string, continue + * until we reach the closing double quote. + */ - if (base && backslashes === true) { - base = utils.removeBackslashes(base); + if (state.quotes === 1 && value !== '"') { + value = utils.escapeRegex(value); + prev.value += value; + append({ value }); + continue; } - } - const state = { - prefix, - input, - start, - base, - glob, - isBrace, - isBracket, - isGlob, - isExtglob, - isGlobstar, - negated - }; + /** + * Double quotes + */ - if (opts.tokens === true) { - state.maxDepth = 0; - if (!isPathSeparator(code)) { - tokens.push(token); + if (value === '"') { + state.quotes = state.quotes === 1 ? 0 : 1; + if (opts.keepQuotes === true) { + push({ type: 'text', value }); + } + continue; } - state.tokens = tokens; - } - if (opts.parts === true || opts.tokens === true) { - let prevIndex; + /** + * Parentheses + */ - for (let idx = 0; idx < slashes.length; idx++) { - const n = prevIndex ? prevIndex + 1 : start; - const i = slashes[idx]; - const value = input.slice(n, i); - if (opts.tokens) { - if (idx === 0 && start !== 0) { - tokens[idx].isPrefix = true; - tokens[idx].value = prefix; - } else { - tokens[idx].value = value; - } - depth(tokens[idx]); - state.maxDepth += tokens[idx].depth; + if (value === '(') { + increment('parens'); + push({ type: 'paren', value }); + continue; + } + + if (value === ')') { + if (state.parens === 0 && opts.strictBrackets === true) { + throw new SyntaxError(syntaxError('opening', '(')); } - if (idx !== 0 || value !== '') { - parts.push(value); + + const extglob = extglobs[extglobs.length - 1]; + if (extglob && state.parens === extglob.parens + 1) { + extglobClose(extglobs.pop()); + continue; } - prevIndex = i; + + push({ type: 'paren', value, output: state.parens ? ')' : '\\)' }); + decrement('parens'); + continue; } - if (prevIndex && prevIndex + 1 < input.length) { - const value = input.slice(prevIndex + 1); - parts.push(value); + /** + * Square brackets + */ - if (opts.tokens) { - tokens[tokens.length - 1].value = value; - depth(tokens[tokens.length - 1]); - state.maxDepth += tokens[tokens.length - 1].depth; + if (value === '[') { + if (opts.nobracket === true || !remaining().includes(']')) { + if (opts.nobracket !== true && opts.strictBrackets === true) { + throw new SyntaxError(syntaxError('closing', ']')); + } + + value = `\\${value}`; + } else { + increment('brackets'); } + + push({ type: 'bracket', value }); + continue; } - state.slashes = slashes; - state.parts = parts; - } + if (value === ']') { + if (opts.nobracket === true || (prev && prev.type === 'bracket' && prev.value.length === 1)) { + push({ type: 'text', value, output: `\\${value}` }); + continue; + } - return state; -}; + if (state.brackets === 0) { + if (opts.strictBrackets === true) { + throw new SyntaxError(syntaxError('opening', '[')); + } -module.exports = scan; + push({ type: 'text', value, output: `\\${value}` }); + continue; + } + decrement('brackets'); -/***/ }), -/* 325 */ -/***/ (function(module, exports, __webpack_require__) { + const prevValue = prev.value.slice(1); + if (prev.posix !== true && prevValue[0] === '^' && !prevValue.includes('/')) { + value = `/${value}`; + } -"use strict"; + prev.value += value; + append({ value }); + // when literal brackets are explicitly disabled + // assume we should match with a regex character class + if (opts.literalBrackets === false || utils.hasRegexChars(prevValue)) { + continue; + } -const path = __webpack_require__(4); -const win32 = process.platform === 'win32'; -const { - REGEX_BACKSLASH, - REGEX_REMOVE_BACKSLASH, - REGEX_SPECIAL_CHARS, - REGEX_SPECIAL_CHARS_GLOBAL -} = __webpack_require__(326); + const escaped = utils.escapeRegex(prev.value); + state.output = state.output.slice(0, -prev.value.length); -exports.isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val); -exports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str); -exports.isRegexChar = str => str.length === 1 && exports.hasRegexChars(str); -exports.escapeRegex = str => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, '\\$1'); -exports.toPosixSlashes = str => str.replace(REGEX_BACKSLASH, '/'); + // when literal brackets are explicitly enabled + // assume we should escape the brackets to match literal characters + if (opts.literalBrackets === true) { + state.output += escaped; + prev.value = escaped; + continue; + } -exports.removeBackslashes = str => { - return str.replace(REGEX_REMOVE_BACKSLASH, match => { - return match === '\\' ? '' : match; - }); -}; + // when the user specifies nothing, try to match both + prev.value = `(${capture}${escaped}|${prev.value})`; + state.output += prev.value; + continue; + } -exports.supportsLookbehinds = () => { - const segs = process.version.slice(1).split('.').map(Number); - if (segs.length === 3 && segs[0] >= 9 || (segs[0] === 8 && segs[1] >= 10)) { - return true; - } - return false; -}; + /** + * Braces + */ -exports.isWindows = options => { - if (options && typeof options.windows === 'boolean') { - return options.windows; - } - return win32 === true || path.sep === '\\'; -}; + if (value === '{' && opts.nobrace !== true) { + increment('braces'); -exports.escapeLast = (input, char, lastIdx) => { - const idx = input.lastIndexOf(char, lastIdx); - if (idx === -1) return input; - if (input[idx - 1] === '\\') return exports.escapeLast(input, char, idx - 1); - return `${input.slice(0, idx)}\\${input.slice(idx)}`; -}; + const open = { + type: 'brace', + value, + output: '(', + outputIndex: state.output.length, + tokensIndex: state.tokens.length + }; -exports.removePrefix = (input, state = {}) => { - let output = input; - if (output.startsWith('./')) { - output = output.slice(2); - state.prefix = './'; - } - return output; -}; + braces.push(open); + push(open); + continue; + } -exports.wrapOutput = (input, state = {}, options = {}) => { - const prepend = options.contains ? '' : '^'; - const append = options.contains ? '' : '$'; + if (value === '}') { + const brace = braces[braces.length - 1]; - let output = `${prepend}(?:${input})${append}`; - if (state.negated === true) { - output = `(?:^(?!${output}).*$)`; - } - return output; -}; + if (opts.nobrace === true || !brace) { + push({ type: 'text', value, output: value }); + continue; + } + let output = ')'; -/***/ }), -/* 326 */ -/***/ (function(module, exports, __webpack_require__) { + if (brace.dots === true) { + const arr = tokens.slice(); + const range = []; -"use strict"; + for (let i = arr.length - 1; i >= 0; i--) { + tokens.pop(); + if (arr[i].type === 'brace') { + break; + } + if (arr[i].type !== 'dots') { + range.unshift(arr[i].value); + } + } + output = expandRange(range, opts); + state.backtrack = true; + } -const path = __webpack_require__(4); -const WIN_SLASH = '\\\\/'; -const WIN_NO_SLASH = `[^${WIN_SLASH}]`; + if (brace.comma !== true && brace.dots !== true) { + const out = state.output.slice(0, brace.outputIndex); + const toks = state.tokens.slice(brace.tokensIndex); + brace.value = brace.output = '\\{'; + value = output = '\\}'; + state.output = out; + for (const t of toks) { + state.output += (t.output || t.value); + } + } -/** - * Posix glob regex - */ + push({ type: 'brace', value, output }); + decrement('braces'); + braces.pop(); + continue; + } -const DOT_LITERAL = '\\.'; -const PLUS_LITERAL = '\\+'; -const QMARK_LITERAL = '\\?'; -const SLASH_LITERAL = '\\/'; -const ONE_CHAR = '(?=.)'; -const QMARK = '[^/]'; -const END_ANCHOR = `(?:${SLASH_LITERAL}|$)`; -const START_ANCHOR = `(?:^|${SLASH_LITERAL})`; -const DOTS_SLASH = `${DOT_LITERAL}{1,2}${END_ANCHOR}`; -const NO_DOT = `(?!${DOT_LITERAL})`; -const NO_DOTS = `(?!${START_ANCHOR}${DOTS_SLASH})`; -const NO_DOT_SLASH = `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`; -const NO_DOTS_SLASH = `(?!${DOTS_SLASH})`; -const QMARK_NO_DOT = `[^.${SLASH_LITERAL}]`; -const STAR = `${QMARK}*?`; - -const POSIX_CHARS = { - DOT_LITERAL, - PLUS_LITERAL, - QMARK_LITERAL, - SLASH_LITERAL, - ONE_CHAR, - QMARK, - END_ANCHOR, - DOTS_SLASH, - NO_DOT, - NO_DOTS, - NO_DOT_SLASH, - NO_DOTS_SLASH, - QMARK_NO_DOT, - STAR, - START_ANCHOR -}; + /** + * Pipes + */ -/** - * Windows glob regex - */ + if (value === '|') { + if (extglobs.length > 0) { + extglobs[extglobs.length - 1].conditions++; + } + push({ type: 'text', value }); + continue; + } -const WINDOWS_CHARS = { - ...POSIX_CHARS, + /** + * Commas + */ - SLASH_LITERAL: `[${WIN_SLASH}]`, - QMARK: WIN_NO_SLASH, - STAR: `${WIN_NO_SLASH}*?`, - DOTS_SLASH: `${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$)`, - NO_DOT: `(?!${DOT_LITERAL})`, - NO_DOTS: `(?!(?:^|[${WIN_SLASH}])${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`, - NO_DOT_SLASH: `(?!${DOT_LITERAL}{0,1}(?:[${WIN_SLASH}]|$))`, - NO_DOTS_SLASH: `(?!${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`, - QMARK_NO_DOT: `[^.${WIN_SLASH}]`, - START_ANCHOR: `(?:^|[${WIN_SLASH}])`, - END_ANCHOR: `(?:[${WIN_SLASH}]|$)` -}; + if (value === ',') { + let output = value; -/** - * POSIX Bracket Regex - */ + const brace = braces[braces.length - 1]; + if (brace && stack[stack.length - 1] === 'braces') { + brace.comma = true; + output = '|'; + } -const POSIX_REGEX_SOURCE = { - alnum: 'a-zA-Z0-9', - alpha: 'a-zA-Z', - ascii: '\\x00-\\x7F', - blank: ' \\t', - cntrl: '\\x00-\\x1F\\x7F', - digit: '0-9', - graph: '\\x21-\\x7E', - lower: 'a-z', - print: '\\x20-\\x7E ', - punct: '\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~', - space: ' \\t\\r\\n\\v\\f', - upper: 'A-Z', - word: 'A-Za-z0-9_', - xdigit: 'A-Fa-f0-9' -}; + push({ type: 'comma', value, output }); + continue; + } -module.exports = { - MAX_LENGTH: 1024 * 64, - POSIX_REGEX_SOURCE, + /** + * Slashes + */ - // regular expressions - REGEX_BACKSLASH: /\\(?![*+?^${}(|)[\]])/g, - REGEX_NON_SPECIAL_CHARS: /^[^@![\].,$*+?^{}()|\\/]+/, - REGEX_SPECIAL_CHARS: /[-*+?.^${}(|)[\]]/, - REGEX_SPECIAL_CHARS_BACKREF: /(\\?)((\W)(\3*))/g, - REGEX_SPECIAL_CHARS_GLOBAL: /([-*+?.^${}(|)[\]])/g, - REGEX_REMOVE_BACKSLASH: /(?:\[.*?[^\\]\]|\\(?=.))/g, + if (value === '/') { + // if the beginning of the glob is "./", advance the start + // to the current index, and don't add the "./" characters + // to the state. This greatly simplifies lookbehinds when + // checking for BOS characters like "!" and "." (not "./") + if (prev.type === 'dot' && state.index === state.start + 1) { + state.start = state.index + 1; + state.consumed = ''; + state.output = ''; + tokens.pop(); + prev = bos; // reset "prev" to the first token + continue; + } - // Replace globs with equivalent patterns to reduce parsing time. - REPLACEMENTS: { - '***': '*', - '**/**': '**', - '**/**/**': '**' - }, + push({ type: 'slash', value, output: SLASH_LITERAL }); + continue; + } - // Digits - CHAR_0: 48, /* 0 */ - CHAR_9: 57, /* 9 */ + /** + * Dots + */ - // Alphabet chars. - CHAR_UPPERCASE_A: 65, /* A */ - CHAR_LOWERCASE_A: 97, /* a */ - CHAR_UPPERCASE_Z: 90, /* Z */ - CHAR_LOWERCASE_Z: 122, /* z */ + if (value === '.') { + if (state.braces > 0 && prev.type === 'dot') { + if (prev.value === '.') prev.output = DOT_LITERAL; + const brace = braces[braces.length - 1]; + prev.type = 'dots'; + prev.output += value; + prev.value += value; + brace.dots = true; + continue; + } - CHAR_LEFT_PARENTHESES: 40, /* ( */ - CHAR_RIGHT_PARENTHESES: 41, /* ) */ + if ((state.braces + state.parens) === 0 && prev.type !== 'bos' && prev.type !== 'slash') { + push({ type: 'text', value, output: DOT_LITERAL }); + continue; + } - CHAR_ASTERISK: 42, /* * */ + push({ type: 'dot', value, output: DOT_LITERAL }); + continue; + } - // Non-alphabetic chars. - CHAR_AMPERSAND: 38, /* & */ - CHAR_AT: 64, /* @ */ - CHAR_BACKWARD_SLASH: 92, /* \ */ - CHAR_CARRIAGE_RETURN: 13, /* \r */ - CHAR_CIRCUMFLEX_ACCENT: 94, /* ^ */ - CHAR_COLON: 58, /* : */ - CHAR_COMMA: 44, /* , */ - CHAR_DOT: 46, /* . */ - CHAR_DOUBLE_QUOTE: 34, /* " */ - CHAR_EQUAL: 61, /* = */ - CHAR_EXCLAMATION_MARK: 33, /* ! */ - CHAR_FORM_FEED: 12, /* \f */ - CHAR_FORWARD_SLASH: 47, /* / */ - CHAR_GRAVE_ACCENT: 96, /* ` */ - CHAR_HASH: 35, /* # */ - CHAR_HYPHEN_MINUS: 45, /* - */ - CHAR_LEFT_ANGLE_BRACKET: 60, /* < */ - CHAR_LEFT_CURLY_BRACE: 123, /* { */ - CHAR_LEFT_SQUARE_BRACKET: 91, /* [ */ - CHAR_LINE_FEED: 10, /* \n */ - CHAR_NO_BREAK_SPACE: 160, /* \u00A0 */ - CHAR_PERCENT: 37, /* % */ - CHAR_PLUS: 43, /* + */ - CHAR_QUESTION_MARK: 63, /* ? */ - CHAR_RIGHT_ANGLE_BRACKET: 62, /* > */ - CHAR_RIGHT_CURLY_BRACE: 125, /* } */ - CHAR_RIGHT_SQUARE_BRACKET: 93, /* ] */ - CHAR_SEMICOLON: 59, /* ; */ - CHAR_SINGLE_QUOTE: 39, /* ' */ - CHAR_SPACE: 32, /* */ - CHAR_TAB: 9, /* \t */ - CHAR_UNDERSCORE: 95, /* _ */ - CHAR_VERTICAL_LINE: 124, /* | */ - CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279, /* \uFEFF */ + /** + * Question marks + */ - SEP: path.sep, + if (value === '?') { + const isGroup = prev && prev.value === '('; + if (!isGroup && opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { + extglobOpen('qmark', value); + continue; + } - /** - * Create EXTGLOB_CHARS - */ + if (prev && prev.type === 'paren') { + const next = peek(); + let output = value; - extglobChars(chars) { - return { - '!': { type: 'negate', open: '(?:(?!(?:', close: `))${chars.STAR})` }, - '?': { type: 'qmark', open: '(?:', close: ')?' }, - '+': { type: 'plus', open: '(?:', close: ')+' }, - '*': { type: 'star', open: '(?:', close: ')*' }, - '@': { type: 'at', open: '(?:', close: ')' } - }; - }, + if (next === '<' && !utils.supportsLookbehinds()) { + throw new Error('Node.js v10 or higher is required for regex lookbehinds'); + } - /** - * Create GLOB_CHARS - */ + if ((prev.value === '(' && !/[!=<:]/.test(next)) || (next === '<' && !/<([!=]|\w+>)/.test(remaining()))) { + output = `\\${value}`; + } - globChars(win32) { - return win32 === true ? WINDOWS_CHARS : POSIX_CHARS; - } -}; + push({ type: 'text', value, output }); + continue; + } + if (opts.dot !== true && (prev.type === 'slash' || prev.type === 'bos')) { + push({ type: 'qmark', value, output: QMARK_NO_DOT }); + continue; + } -/***/ }), -/* 327 */ -/***/ (function(module, exports, __webpack_require__) { + push({ type: 'qmark', value, output: QMARK }); + continue; + } -"use strict"; + /** + * Exclamation + */ + if (value === '!') { + if (opts.noextglob !== true && peek() === '(') { + if (peek(2) !== '?' || !/[!=<:]/.test(peek(3))) { + extglobOpen('negate', value); + continue; + } + } -const constants = __webpack_require__(326); -const utils = __webpack_require__(325); + if (opts.nonegate !== true && state.index === 0) { + negate(); + continue; + } + } -/** - * Constants - */ + /** + * Plus + */ -const { - MAX_LENGTH, - POSIX_REGEX_SOURCE, - REGEX_NON_SPECIAL_CHARS, - REGEX_SPECIAL_CHARS_BACKREF, - REPLACEMENTS -} = constants; + if (value === '+') { + if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { + extglobOpen('plus', value); + continue; + } -/** - * Helpers - */ + if ((prev && prev.value === '(') || opts.regex === false) { + push({ type: 'plus', value, output: PLUS_LITERAL }); + continue; + } -const expandRange = (args, options) => { - if (typeof options.expandRange === 'function') { - return options.expandRange(...args, options); - } + if ((prev && (prev.type === 'bracket' || prev.type === 'paren' || prev.type === 'brace')) || state.parens > 0) { + push({ type: 'plus', value }); + continue; + } - args.sort(); - const value = `[${args.join('-')}]`; + push({ type: 'plus', value: PLUS_LITERAL }); + continue; + } - try { - /* eslint-disable-next-line no-new */ - new RegExp(value); - } catch (ex) { - return args.map(v => utils.escapeRegex(v)).join('..'); - } + /** + * Plain text + */ - return value; -}; + if (value === '@') { + if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { + push({ type: 'at', extglob: true, value, output: '' }); + continue; + } -/** - * Create the message for a syntax error - */ + push({ type: 'text', value }); + continue; + } -const syntaxError = (type, char) => { - return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`; -}; + /** + * Plain text + */ -/** - * Parse the given input string. - * @param {String} input - * @param {Object} options - * @return {Object} - */ + if (value !== '*') { + if (value === '$' || value === '^') { + value = `\\${value}`; + } -const parse = (input, options) => { - if (typeof input !== 'string') { - throw new TypeError('Expected a string'); - } + const match = REGEX_NON_SPECIAL_CHARS.exec(remaining()); + if (match) { + value += match[0]; + state.index += match[0].length; + } - input = REPLACEMENTS[input] || input; + push({ type: 'text', value }); + continue; + } - const opts = { ...options }; - const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; + /** + * Stars + */ - let len = input.length; - if (len > max) { - throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); - } + if (prev && (prev.type === 'globstar' || prev.star === true)) { + prev.type = 'star'; + prev.star = true; + prev.value += value; + prev.output = star; + state.backtrack = true; + state.globstar = true; + consume(value); + continue; + } - const bos = { type: 'bos', value: '', output: opts.prepend || '' }; - const tokens = [bos]; + let rest = remaining(); + if (opts.noextglob !== true && /^\([^?]/.test(rest)) { + extglobOpen('star', value); + continue; + } - const capture = opts.capture ? '' : '?:'; - const win32 = utils.isWindows(options); + if (prev.type === 'star') { + if (opts.noglobstar === true) { + consume(value); + continue; + } - // create constants based on platform, for windows or posix - const PLATFORM_CHARS = constants.globChars(win32); - const EXTGLOB_CHARS = constants.extglobChars(PLATFORM_CHARS); + const prior = prev.prev; + const before = prior.prev; + const isStart = prior.type === 'slash' || prior.type === 'bos'; + const afterStar = before && (before.type === 'star' || before.type === 'globstar'); - const { - DOT_LITERAL, - PLUS_LITERAL, - SLASH_LITERAL, - ONE_CHAR, - DOTS_SLASH, - NO_DOT, - NO_DOT_SLASH, - NO_DOTS_SLASH, - QMARK, - QMARK_NO_DOT, - STAR, - START_ANCHOR - } = PLATFORM_CHARS; + if (opts.bash === true && (!isStart || (rest[0] && rest[0] !== '/'))) { + push({ type: 'star', value, output: '' }); + continue; + } - const globstar = (opts) => { - return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; - }; + const isBrace = state.braces > 0 && (prior.type === 'comma' || prior.type === 'brace'); + const isExtglob = extglobs.length && (prior.type === 'pipe' || prior.type === 'paren'); + if (!isStart && prior.type !== 'paren' && !isBrace && !isExtglob) { + push({ type: 'star', value, output: '' }); + continue; + } - const nodot = opts.dot ? '' : NO_DOT; - const qmarkNoDot = opts.dot ? QMARK : QMARK_NO_DOT; - let star = opts.bash === true ? globstar(opts) : STAR; + // strip consecutive `/**/` + while (rest.slice(0, 3) === '/**') { + const after = input[state.index + 4]; + if (after && after !== '/') { + break; + } + rest = rest.slice(3); + consume('/**', 3); + } - if (opts.capture) { - star = `(${star})`; - } + if (prior.type === 'bos' && eos()) { + prev.type = 'globstar'; + prev.value += value; + prev.output = globstar(opts); + state.output = prev.output; + state.globstar = true; + consume(value); + continue; + } - // minimatch options support - if (typeof opts.noext === 'boolean') { - opts.noextglob = opts.noext; - } + if (prior.type === 'slash' && prior.prev.type !== 'bos' && !afterStar && eos()) { + state.output = state.output.slice(0, -(prior.output + prev.output).length); + prior.output = `(?:${prior.output}`; - const state = { - input, - index: -1, - start: 0, - dot: opts.dot === true, - consumed: '', - output: '', - prefix: '', - backtrack: false, - negated: false, - brackets: 0, - braces: 0, - parens: 0, - quotes: 0, - globstar: false, - tokens - }; + prev.type = 'globstar'; + prev.output = globstar(opts) + (opts.strictSlashes ? ')' : '|$)'); + prev.value += value; + state.globstar = true; + state.output += prior.output + prev.output; + consume(value); + continue; + } - input = utils.removePrefix(input, state); - len = input.length; + if (prior.type === 'slash' && prior.prev.type !== 'bos' && rest[0] === '/') { + const end = rest[1] !== void 0 ? '|$' : ''; - const extglobs = []; - const braces = []; - const stack = []; - let prev = bos; - let value; + state.output = state.output.slice(0, -(prior.output + prev.output).length); + prior.output = `(?:${prior.output}`; - /** - * Tokenizing helpers - */ + prev.type = 'globstar'; + prev.output = `${globstar(opts)}${SLASH_LITERAL}|${SLASH_LITERAL}${end})`; + prev.value += value; - const eos = () => state.index === len - 1; - const peek = state.peek = (n = 1) => input[state.index + n]; - const advance = state.advance = () => input[++state.index]; - const remaining = () => input.slice(state.index + 1); - const consume = (value = '', num = 0) => { - state.consumed += value; - state.index += num; - }; - const append = token => { - state.output += token.output != null ? token.output : token.value; - consume(token.value); - }; + state.output += prior.output + prev.output; + state.globstar = true; - const negate = () => { - let count = 1; + consume(value + advance()); - while (peek() === '!' && (peek(2) !== '(' || peek(3) === '?')) { - advance(); - state.start++; - count++; - } + push({ type: 'slash', value: '/', output: '' }); + continue; + } - if (count % 2 === 0) { - return false; - } - - state.negated = true; - state.start++; - return true; - }; + if (prior.type === 'bos' && rest[0] === '/') { + prev.type = 'globstar'; + prev.value += value; + prev.output = `(?:^|${SLASH_LITERAL}|${globstar(opts)}${SLASH_LITERAL})`; + state.output = prev.output; + state.globstar = true; + consume(value + advance()); + push({ type: 'slash', value: '/', output: '' }); + continue; + } - const increment = type => { - state[type]++; - stack.push(type); - }; + // remove single star from output + state.output = state.output.slice(0, -prev.output.length); - const decrement = type => { - state[type]--; - stack.pop(); - }; + // reset previous token to globstar + prev.type = 'globstar'; + prev.output = globstar(opts); + prev.value += value; - /** - * Push tokens onto the tokens array. This helper speeds up - * tokenizing by 1) helping us avoid backtracking as much as possible, - * and 2) helping us avoid creating extra tokens when consecutive - * characters are plain text. This improves performance and simplifies - * lookbehinds. - */ + // reset output with globstar + state.output += prev.output; + state.globstar = true; + consume(value); + continue; + } - const push = tok => { - if (prev.type === 'globstar') { - const isBrace = state.braces > 0 && (tok.type === 'comma' || tok.type === 'brace'); - const isExtglob = tok.extglob === true || (extglobs.length && (tok.type === 'pipe' || tok.type === 'paren')); + const token = { type: 'star', value, output: star }; - if (tok.type !== 'slash' && tok.type !== 'paren' && !isBrace && !isExtglob) { - state.output = state.output.slice(0, -prev.output.length); - prev.type = 'star'; - prev.value = '*'; - prev.output = star; - state.output += prev.output; + if (opts.bash === true) { + token.output = '.*?'; + if (prev.type === 'bos' || prev.type === 'slash') { + token.output = nodot + token.output; } + push(token); + continue; } - if (extglobs.length && tok.type !== 'paren' && !EXTGLOB_CHARS[tok.value]) { - extglobs[extglobs.length - 1].inner += tok.value; - } - - if (tok.value || tok.output) append(tok); - if (prev && prev.type === 'text' && tok.type === 'text') { - prev.value += tok.value; - prev.output = (prev.output || '') + tok.value; - return; + if (prev && (prev.type === 'bracket' || prev.type === 'paren') && opts.regex === true) { + token.output = value; + push(token); + continue; } - tok.prev = prev; - tokens.push(tok); - prev = tok; - }; - - const extglobOpen = (type, value) => { - const token = { ...EXTGLOB_CHARS[value], conditions: 1, inner: '' }; - - token.prev = prev; - token.parens = state.parens; - token.output = state.output; - const output = (opts.capture ? '(' : '') + token.open; - - increment('parens'); - push({ type, value, output: state.output ? '' : ONE_CHAR }); - push({ type: 'paren', extglob: true, value: advance(), output }); - extglobs.push(token); - }; - - const extglobClose = token => { - let output = token.close + (opts.capture ? ')' : ''); - - if (token.type === 'negate') { - let extglobStar = star; + if (state.index === state.start || prev.type === 'slash' || prev.type === 'dot') { + if (prev.type === 'dot') { + state.output += NO_DOT_SLASH; + prev.output += NO_DOT_SLASH; - if (token.inner && token.inner.length > 1 && token.inner.includes('/')) { - extglobStar = globstar(opts); - } + } else if (opts.dot === true) { + state.output += NO_DOTS_SLASH; + prev.output += NO_DOTS_SLASH; - if (extglobStar !== star || eos() || /^\)+$/.test(remaining())) { - output = token.close = `)$))${extglobStar}`; + } else { + state.output += nodot; + prev.output += nodot; } - if (token.prev.type === 'bos' && eos()) { - state.negatedExtglob = true; + if (peek() !== '*') { + state.output += ONE_CHAR; + prev.output += ONE_CHAR; } } - push({ type: 'paren', extglob: true, value, output }); - decrement('parens'); - }; + push(token); + } - /** - * Fast paths - */ + while (state.brackets > 0) { + if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ']')); + state.output = utils.escapeLast(state.output, '['); + decrement('brackets'); + } - if (opts.fastpaths !== false && !/(^[*!]|[/()[\]{}"])/.test(input)) { - let backslashes = false; + while (state.parens > 0) { + if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ')')); + state.output = utils.escapeLast(state.output, '('); + decrement('parens'); + } - let output = input.replace(REGEX_SPECIAL_CHARS_BACKREF, (m, esc, chars, first, rest, index) => { - if (first === '\\') { - backslashes = true; - return m; - } + while (state.braces > 0) { + if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', '}')); + state.output = utils.escapeLast(state.output, '{'); + decrement('braces'); + } - if (first === '?') { - if (esc) { - return esc + first + (rest ? QMARK.repeat(rest.length) : ''); - } - if (index === 0) { - return qmarkNoDot + (rest ? QMARK.repeat(rest.length) : ''); - } - return QMARK.repeat(chars.length); - } + if (opts.strictSlashes !== true && (prev.type === 'star' || prev.type === 'bracket')) { + push({ type: 'maybe_slash', value: '', output: `${SLASH_LITERAL}?` }); + } - if (first === '.') { - return DOT_LITERAL.repeat(chars.length); - } + // rebuild the output if we had to backtrack at any point + if (state.backtrack === true) { + state.output = ''; - if (first === '*') { - if (esc) { - return esc + first + (rest ? star : ''); - } - return star; - } - return esc ? m : `\\${m}`; - }); + for (const token of state.tokens) { + state.output += token.output != null ? token.output : token.value; - if (backslashes === true) { - if (opts.unescape === true) { - output = output.replace(/\\/g, ''); - } else { - output = output.replace(/\\+/g, m => { - return m.length % 2 === 0 ? '\\\\' : (m ? '\\' : ''); - }); + if (token.suffix) { + state.output += token.suffix; } } - - if (output === input && opts.contains === true) { - state.output = input; - return state; - } - - state.output = utils.wrapOutput(output, state, options); - return state; } - /** - * Tokenize input until we reach end-of-string - */ - - while (!eos()) { - value = advance(); - - if (value === '\u0000') { - continue; - } - - /** - * Escaped characters - */ - - if (value === '\\') { - const next = peek(); - - if (next === '/' && opts.bash !== true) { - continue; - } + return state; +}; - if (next === '.' || next === ';') { - continue; - } +/** + * Fast paths for creating regular expressions for common glob patterns. + * This can significantly speed up processing and has very little downside + * impact when none of the fast paths match. + */ - if (!next) { - value += '\\'; - push({ type: 'text', value }); - continue; - } +parse.fastpaths = (input, options) => { + const opts = { ...options }; + const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; + const len = input.length; + if (len > max) { + throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); + } - // collapse slashes to reduce potential for exploits - const match = /^\\+/.exec(remaining()); - let slashes = 0; + input = REPLACEMENTS[input] || input; + const win32 = utils.isWindows(options); - if (match && match[0].length > 2) { - slashes = match[0].length; - state.index += slashes; - if (slashes % 2 !== 0) { - value += '\\'; - } - } + // create constants based on platform, for windows or posix + const { + DOT_LITERAL, + SLASH_LITERAL, + ONE_CHAR, + DOTS_SLASH, + NO_DOT, + NO_DOTS, + NO_DOTS_SLASH, + STAR, + START_ANCHOR + } = constants.globChars(win32); - if (opts.unescape === true) { - value = advance() || ''; - } else { - value += advance() || ''; - } + const nodot = opts.dot ? NO_DOTS : NO_DOT; + const slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT; + const capture = opts.capture ? '' : '?:'; + const state = { negated: false, prefix: '' }; + let star = opts.bash === true ? '.*?' : STAR; - if (state.brackets === 0) { - push({ type: 'text', value }); - continue; - } - } + if (opts.capture) { + star = `(${star})`; + } - /** - * If we're inside a regex character class, continue - * until we reach the closing bracket. - */ + const globstar = (opts) => { + if (opts.noglobstar === true) return star; + return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; + }; - if (state.brackets > 0 && (value !== ']' || prev.value === '[' || prev.value === '[^')) { - if (opts.posix !== false && value === ':') { - const inner = prev.value.slice(1); - if (inner.includes('[')) { - prev.posix = true; + const create = str => { + switch (str) { + case '*': + return `${nodot}${ONE_CHAR}${star}`; - if (inner.includes(':')) { - const idx = prev.value.lastIndexOf('['); - const pre = prev.value.slice(0, idx); - const rest = prev.value.slice(idx + 2); - const posix = POSIX_REGEX_SOURCE[rest]; - if (posix) { - prev.value = pre + posix; - state.backtrack = true; - advance(); + case '.*': + return `${DOT_LITERAL}${ONE_CHAR}${star}`; - if (!bos.output && tokens.indexOf(prev) === 1) { - bos.output = ONE_CHAR; - } - continue; - } - } - } - } + case '*.*': + return `${nodot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; - if ((value === '[' && peek() !== ':') || (value === '-' && peek() === ']')) { - value = `\\${value}`; - } + case '*/*': + return `${nodot}${star}${SLASH_LITERAL}${ONE_CHAR}${slashDot}${star}`; - if (value === ']' && (prev.value === '[' || prev.value === '[^')) { - value = `\\${value}`; - } + case '**': + return nodot + globstar(opts); - if (opts.posix === true && value === '!' && prev.value === '[') { - value = '^'; - } + case '**/*': + return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${ONE_CHAR}${star}`; - prev.value += value; - append({ value }); - continue; - } + case '**/*.*': + return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; - /** - * If we're inside a quoted string, continue - * until we reach the closing double quote. - */ + case '**/.*': + return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${DOT_LITERAL}${ONE_CHAR}${star}`; - if (state.quotes === 1 && value !== '"') { - value = utils.escapeRegex(value); - prev.value += value; - append({ value }); - continue; - } + default: { + const match = /^(.*?)\.(\w+)$/.exec(str); + if (!match) return; - /** - * Double quotes - */ + const source = create(match[1]); + if (!source) return; - if (value === '"') { - state.quotes = state.quotes === 1 ? 0 : 1; - if (opts.keepQuotes === true) { - push({ type: 'text', value }); + return source + DOT_LITERAL + match[2]; } - continue; } + }; - /** - * Parentheses - */ + const output = utils.removePrefix(input, state); + let source = create(output); - if (value === '(') { - increment('parens'); - push({ type: 'paren', value }); - continue; - } + if (source && opts.strictSlashes !== true) { + source += `${SLASH_LITERAL}?`; + } - if (value === ')') { - if (state.parens === 0 && opts.strictBrackets === true) { - throw new SyntaxError(syntaxError('opening', '(')); - } + return source; +}; - const extglob = extglobs[extglobs.length - 1]; - if (extglob && state.parens === extglob.parens + 1) { - extglobClose(extglobs.pop()); - continue; - } +module.exports = parse; - push({ type: 'paren', value, output: state.parens ? ')' : '\\)' }); - decrement('parens'); - continue; - } - /** - * Square brackets - */ +/***/ }), +/* 320 */ +/***/ (function(module, exports, __webpack_require__) { - if (value === '[') { - if (opts.nobracket === true || !remaining().includes(']')) { - if (opts.nobracket !== true && opts.strictBrackets === true) { - throw new SyntaxError(syntaxError('closing', ']')); - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const merge2 = __webpack_require__(291); +function merge(streams) { + const mergedStream = merge2(streams); + streams.forEach((stream) => { + stream.once('error', (error) => mergedStream.emit('error', error)); + }); + mergedStream.once('close', () => propagateCloseEventToSources(streams)); + mergedStream.once('end', () => propagateCloseEventToSources(streams)); + return mergedStream; +} +exports.merge = merge; +function propagateCloseEventToSources(streams) { + streams.forEach((stream) => stream.emit('close')); +} - value = `\\${value}`; - } else { - increment('brackets'); - } - push({ type: 'bracket', value }); - continue; - } +/***/ }), +/* 321 */ +/***/ (function(module, exports, __webpack_require__) { - if (value === ']') { - if (opts.nobracket === true || (prev && prev.type === 'bracket' && prev.value.length === 1)) { - push({ type: 'text', value, output: `\\${value}` }); - continue; - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +function isString(input) { + return typeof input === 'string'; +} +exports.isString = isString; +function isEmpty(input) { + return input === ''; +} +exports.isEmpty = isEmpty; - if (state.brackets === 0) { - if (opts.strictBrackets === true) { - throw new SyntaxError(syntaxError('opening', '[')); - } - push({ type: 'text', value, output: `\\${value}` }); - continue; - } +/***/ }), +/* 322 */ +/***/ (function(module, exports, __webpack_require__) { - decrement('brackets'); +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const stream_1 = __webpack_require__(323); +const provider_1 = __webpack_require__(350); +class ProviderAsync extends provider_1.default { + constructor() { + super(...arguments); + this._reader = new stream_1.default(this._settings); + } + read(task) { + const root = this._getRootDirectory(task); + const options = this._getReaderOptions(task); + const entries = []; + return new Promise((resolve, reject) => { + const stream = this.api(root, task, options); + stream.once('error', reject); + stream.on('data', (entry) => entries.push(options.transform(entry))); + stream.once('end', () => resolve(entries)); + }); + } + api(root, task, options) { + if (task.dynamic) { + return this._reader.dynamic(root, options); + } + return this._reader.static(task.patterns, options); + } +} +exports.default = ProviderAsync; - const prevValue = prev.value.slice(1); - if (prev.posix !== true && prevValue[0] === '^' && !prevValue.includes('/')) { - value = `/${value}`; - } - prev.value += value; - append({ value }); +/***/ }), +/* 323 */ +/***/ (function(module, exports, __webpack_require__) { - // when literal brackets are explicitly disabled - // assume we should match with a regex character class - if (opts.literalBrackets === false || utils.hasRegexChars(prevValue)) { - continue; - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const stream_1 = __webpack_require__(137); +const fsStat = __webpack_require__(324); +const fsWalk = __webpack_require__(329); +const reader_1 = __webpack_require__(349); +class ReaderStream extends reader_1.default { + constructor() { + super(...arguments); + this._walkStream = fsWalk.walkStream; + this._stat = fsStat.stat; + } + dynamic(root, options) { + return this._walkStream(root, options); + } + static(patterns, options) { + const filepaths = patterns.map(this._getFullEntryPath, this); + const stream = new stream_1.PassThrough({ objectMode: true }); + stream._write = (index, _enc, done) => { + return this._getEntry(filepaths[index], patterns[index], options) + .then((entry) => { + if (entry !== null && options.entryFilter(entry)) { + stream.push(entry); + } + if (index === filepaths.length - 1) { + stream.end(); + } + done(); + }) + .catch(done); + }; + for (let i = 0; i < filepaths.length; i++) { + stream.write(i); + } + return stream; + } + _getEntry(filepath, pattern, options) { + return this._getStat(filepath) + .then((stats) => this._makeEntry(stats, pattern)) + .catch((error) => { + if (options.errorFilter(error)) { + return null; + } + throw error; + }); + } + _getStat(filepath) { + return new Promise((resolve, reject) => { + this._stat(filepath, this._fsStatSettings, (error, stats) => { + return error === null ? resolve(stats) : reject(error); + }); + }); + } +} +exports.default = ReaderStream; - const escaped = utils.escapeRegex(prev.value); - state.output = state.output.slice(0, -prev.value.length); - // when literal brackets are explicitly enabled - // assume we should escape the brackets to match literal characters - if (opts.literalBrackets === true) { - state.output += escaped; - prev.value = escaped; - continue; - } +/***/ }), +/* 324 */ +/***/ (function(module, exports, __webpack_require__) { - // when the user specifies nothing, try to match both - prev.value = `(${capture}${escaped}|${prev.value})`; - state.output += prev.value; - continue; - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const async = __webpack_require__(325); +const sync = __webpack_require__(326); +const settings_1 = __webpack_require__(327); +exports.Settings = settings_1.default; +function stat(path, optionsOrSettingsOrCallback, callback) { + if (typeof optionsOrSettingsOrCallback === 'function') { + return async.read(path, getSettings(), optionsOrSettingsOrCallback); + } + async.read(path, getSettings(optionsOrSettingsOrCallback), callback); +} +exports.stat = stat; +function statSync(path, optionsOrSettings) { + const settings = getSettings(optionsOrSettings); + return sync.read(path, settings); +} +exports.statSync = statSync; +function getSettings(settingsOrOptions = {}) { + if (settingsOrOptions instanceof settings_1.default) { + return settingsOrOptions; + } + return new settings_1.default(settingsOrOptions); +} - /** - * Braces - */ - if (value === '{' && opts.nobrace !== true) { - increment('braces'); +/***/ }), +/* 325 */ +/***/ (function(module, exports, __webpack_require__) { - const open = { - type: 'brace', - value, - output: '(', - outputIndex: state.output.length, - tokensIndex: state.tokens.length - }; +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +function read(path, settings, callback) { + settings.fs.lstat(path, (lstatError, lstat) => { + if (lstatError !== null) { + return callFailureCallback(callback, lstatError); + } + if (!lstat.isSymbolicLink() || !settings.followSymbolicLink) { + return callSuccessCallback(callback, lstat); + } + settings.fs.stat(path, (statError, stat) => { + if (statError !== null) { + if (settings.throwErrorOnBrokenSymbolicLink) { + return callFailureCallback(callback, statError); + } + return callSuccessCallback(callback, lstat); + } + if (settings.markSymbolicLink) { + stat.isSymbolicLink = () => true; + } + callSuccessCallback(callback, stat); + }); + }); +} +exports.read = read; +function callFailureCallback(callback, error) { + callback(error); +} +function callSuccessCallback(callback, result) { + callback(null, result); +} - braces.push(open); - push(open); - continue; - } - if (value === '}') { - const brace = braces[braces.length - 1]; +/***/ }), +/* 326 */ +/***/ (function(module, exports, __webpack_require__) { - if (opts.nobrace === true || !brace) { - push({ type: 'text', value, output: value }); - continue; - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +function read(path, settings) { + const lstat = settings.fs.lstatSync(path); + if (!lstat.isSymbolicLink() || !settings.followSymbolicLink) { + return lstat; + } + try { + const stat = settings.fs.statSync(path); + if (settings.markSymbolicLink) { + stat.isSymbolicLink = () => true; + } + return stat; + } + catch (error) { + if (!settings.throwErrorOnBrokenSymbolicLink) { + return lstat; + } + throw error; + } +} +exports.read = read; - let output = ')'; - if (brace.dots === true) { - const arr = tokens.slice(); - const range = []; +/***/ }), +/* 327 */ +/***/ (function(module, exports, __webpack_require__) { - for (let i = arr.length - 1; i >= 0; i--) { - tokens.pop(); - if (arr[i].type === 'brace') { - break; - } - if (arr[i].type !== 'dots') { - range.unshift(arr[i].value); - } - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const fs = __webpack_require__(328); +class Settings { + constructor(_options = {}) { + this._options = _options; + this.followSymbolicLink = this._getValue(this._options.followSymbolicLink, true); + this.fs = fs.createFileSystemAdapter(this._options.fs); + this.markSymbolicLink = this._getValue(this._options.markSymbolicLink, false); + this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, true); + } + _getValue(option, value) { + return option === undefined ? value : option; + } +} +exports.default = Settings; - output = expandRange(range, opts); - state.backtrack = true; - } - if (brace.comma !== true && brace.dots !== true) { - const out = state.output.slice(0, brace.outputIndex); - const toks = state.tokens.slice(brace.tokensIndex); - brace.value = brace.output = '\\{'; - value = output = '\\}'; - state.output = out; - for (const t of toks) { - state.output += (t.output || t.value); - } - } +/***/ }), +/* 328 */ +/***/ (function(module, exports, __webpack_require__) { - push({ type: 'brace', value, output }); - decrement('braces'); - braces.pop(); - continue; - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const fs = __webpack_require__(133); +exports.FILE_SYSTEM_ADAPTER = { + lstat: fs.lstat, + stat: fs.stat, + lstatSync: fs.lstatSync, + statSync: fs.statSync +}; +function createFileSystemAdapter(fsMethods) { + if (fsMethods === undefined) { + return exports.FILE_SYSTEM_ADAPTER; + } + return Object.assign(Object.assign({}, exports.FILE_SYSTEM_ADAPTER), fsMethods); +} +exports.createFileSystemAdapter = createFileSystemAdapter; - /** - * Pipes - */ - if (value === '|') { - if (extglobs.length > 0) { - extglobs[extglobs.length - 1].conditions++; - } - push({ type: 'text', value }); - continue; - } +/***/ }), +/* 329 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * Commas - */ +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const async_1 = __webpack_require__(330); +const stream_1 = __webpack_require__(345); +const sync_1 = __webpack_require__(346); +const settings_1 = __webpack_require__(348); +exports.Settings = settings_1.default; +function walk(directory, optionsOrSettingsOrCallback, callback) { + if (typeof optionsOrSettingsOrCallback === 'function') { + return new async_1.default(directory, getSettings()).read(optionsOrSettingsOrCallback); + } + new async_1.default(directory, getSettings(optionsOrSettingsOrCallback)).read(callback); +} +exports.walk = walk; +function walkSync(directory, optionsOrSettings) { + const settings = getSettings(optionsOrSettings); + const provider = new sync_1.default(directory, settings); + return provider.read(); +} +exports.walkSync = walkSync; +function walkStream(directory, optionsOrSettings) { + const settings = getSettings(optionsOrSettings); + const provider = new stream_1.default(directory, settings); + return provider.read(); +} +exports.walkStream = walkStream; +function getSettings(settingsOrOptions = {}) { + if (settingsOrOptions instanceof settings_1.default) { + return settingsOrOptions; + } + return new settings_1.default(settingsOrOptions); +} - if (value === ',') { - let output = value; - const brace = braces[braces.length - 1]; - if (brace && stack[stack.length - 1] === 'braces') { - brace.comma = true; - output = '|'; - } +/***/ }), +/* 330 */ +/***/ (function(module, exports, __webpack_require__) { - push({ type: 'comma', value, output }); - continue; - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const async_1 = __webpack_require__(331); +class AsyncProvider { + constructor(_root, _settings) { + this._root = _root; + this._settings = _settings; + this._reader = new async_1.default(this._root, this._settings); + this._storage = new Set(); + } + read(callback) { + this._reader.onError((error) => { + callFailureCallback(callback, error); + }); + this._reader.onEntry((entry) => { + this._storage.add(entry); + }); + this._reader.onEnd(() => { + callSuccessCallback(callback, [...this._storage]); + }); + this._reader.read(); + } +} +exports.default = AsyncProvider; +function callFailureCallback(callback, error) { + callback(error); +} +function callSuccessCallback(callback, entries) { + callback(null, entries); +} - /** - * Slashes - */ - if (value === '/') { - // if the beginning of the glob is "./", advance the start - // to the current index, and don't add the "./" characters - // to the state. This greatly simplifies lookbehinds when - // checking for BOS characters like "!" and "." (not "./") - if (prev.type === 'dot' && state.index === state.start + 1) { - state.start = state.index + 1; - state.consumed = ''; - state.output = ''; - tokens.pop(); - prev = bos; // reset "prev" to the first token - continue; - } +/***/ }), +/* 331 */ +/***/ (function(module, exports, __webpack_require__) { - push({ type: 'slash', value, output: SLASH_LITERAL }); - continue; - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const events_1 = __webpack_require__(155); +const fsScandir = __webpack_require__(332); +const fastq = __webpack_require__(341); +const common = __webpack_require__(343); +const reader_1 = __webpack_require__(344); +class AsyncReader extends reader_1.default { + constructor(_root, _settings) { + super(_root, _settings); + this._settings = _settings; + this._scandir = fsScandir.scandir; + this._emitter = new events_1.EventEmitter(); + this._queue = fastq(this._worker.bind(this), this._settings.concurrency); + this._isFatalError = false; + this._isDestroyed = false; + this._queue.drain = () => { + if (!this._isFatalError) { + this._emitter.emit('end'); + } + }; + } + read() { + this._isFatalError = false; + this._isDestroyed = false; + setImmediate(() => { + this._pushToQueue(this._root, this._settings.basePath); + }); + return this._emitter; + } + destroy() { + if (this._isDestroyed) { + throw new Error('The reader is already destroyed'); + } + this._isDestroyed = true; + this._queue.killAndDrain(); + } + onEntry(callback) { + this._emitter.on('entry', callback); + } + onError(callback) { + this._emitter.once('error', callback); + } + onEnd(callback) { + this._emitter.once('end', callback); + } + _pushToQueue(directory, base) { + const queueItem = { directory, base }; + this._queue.push(queueItem, (error) => { + if (error !== null) { + this._handleError(error); + } + }); + } + _worker(item, done) { + this._scandir(item.directory, this._settings.fsScandirSettings, (error, entries) => { + if (error !== null) { + return done(error, undefined); + } + for (const entry of entries) { + this._handleEntry(entry, item.base); + } + done(null, undefined); + }); + } + _handleError(error) { + if (!common.isFatalError(this._settings, error)) { + return; + } + this._isFatalError = true; + this._isDestroyed = true; + this._emitter.emit('error', error); + } + _handleEntry(entry, base) { + if (this._isDestroyed || this._isFatalError) { + return; + } + const fullpath = entry.path; + if (base !== undefined) { + entry.path = common.joinPathSegments(base, entry.name, this._settings.pathSegmentSeparator); + } + if (common.isAppliedFilter(this._settings.entryFilter, entry)) { + this._emitEntry(entry); + } + if (entry.dirent.isDirectory() && common.isAppliedFilter(this._settings.deepFilter, entry)) { + this._pushToQueue(fullpath, entry.path); + } + } + _emitEntry(entry) { + this._emitter.emit('entry', entry); + } +} +exports.default = AsyncReader; - /** - * Dots - */ - if (value === '.') { - if (state.braces > 0 && prev.type === 'dot') { - if (prev.value === '.') prev.output = DOT_LITERAL; - const brace = braces[braces.length - 1]; - prev.type = 'dots'; - prev.output += value; - prev.value += value; - brace.dots = true; - continue; - } +/***/ }), +/* 332 */ +/***/ (function(module, exports, __webpack_require__) { - if ((state.braces + state.parens) === 0 && prev.type !== 'bos' && prev.type !== 'slash') { - push({ type: 'text', value, output: DOT_LITERAL }); - continue; - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const async = __webpack_require__(333); +const sync = __webpack_require__(338); +const settings_1 = __webpack_require__(339); +exports.Settings = settings_1.default; +function scandir(path, optionsOrSettingsOrCallback, callback) { + if (typeof optionsOrSettingsOrCallback === 'function') { + return async.read(path, getSettings(), optionsOrSettingsOrCallback); + } + async.read(path, getSettings(optionsOrSettingsOrCallback), callback); +} +exports.scandir = scandir; +function scandirSync(path, optionsOrSettings) { + const settings = getSettings(optionsOrSettings); + return sync.read(path, settings); +} +exports.scandirSync = scandirSync; +function getSettings(settingsOrOptions = {}) { + if (settingsOrOptions instanceof settings_1.default) { + return settingsOrOptions; + } + return new settings_1.default(settingsOrOptions); +} - push({ type: 'dot', value, output: DOT_LITERAL }); - continue; - } - /** - * Question marks - */ +/***/ }), +/* 333 */ +/***/ (function(module, exports, __webpack_require__) { - if (value === '?') { - const isGroup = prev && prev.value === '('; - if (!isGroup && opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { - extglobOpen('qmark', value); - continue; - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const fsStat = __webpack_require__(324); +const rpl = __webpack_require__(334); +const constants_1 = __webpack_require__(335); +const utils = __webpack_require__(336); +function read(directory, settings, callback) { + if (!settings.stats && constants_1.IS_SUPPORT_READDIR_WITH_FILE_TYPES) { + return readdirWithFileTypes(directory, settings, callback); + } + return readdir(directory, settings, callback); +} +exports.read = read; +function readdirWithFileTypes(directory, settings, callback) { + settings.fs.readdir(directory, { withFileTypes: true }, (readdirError, dirents) => { + if (readdirError !== null) { + return callFailureCallback(callback, readdirError); + } + const entries = dirents.map((dirent) => ({ + dirent, + name: dirent.name, + path: `${directory}${settings.pathSegmentSeparator}${dirent.name}` + })); + if (!settings.followSymbolicLinks) { + return callSuccessCallback(callback, entries); + } + const tasks = entries.map((entry) => makeRplTaskEntry(entry, settings)); + rpl(tasks, (rplError, rplEntries) => { + if (rplError !== null) { + return callFailureCallback(callback, rplError); + } + callSuccessCallback(callback, rplEntries); + }); + }); +} +exports.readdirWithFileTypes = readdirWithFileTypes; +function makeRplTaskEntry(entry, settings) { + return (done) => { + if (!entry.dirent.isSymbolicLink()) { + return done(null, entry); + } + settings.fs.stat(entry.path, (statError, stats) => { + if (statError !== null) { + if (settings.throwErrorOnBrokenSymbolicLink) { + return done(statError); + } + return done(null, entry); + } + entry.dirent = utils.fs.createDirentFromStats(entry.name, stats); + return done(null, entry); + }); + }; +} +function readdir(directory, settings, callback) { + settings.fs.readdir(directory, (readdirError, names) => { + if (readdirError !== null) { + return callFailureCallback(callback, readdirError); + } + const filepaths = names.map((name) => `${directory}${settings.pathSegmentSeparator}${name}`); + const tasks = filepaths.map((filepath) => { + return (done) => fsStat.stat(filepath, settings.fsStatSettings, done); + }); + rpl(tasks, (rplError, results) => { + if (rplError !== null) { + return callFailureCallback(callback, rplError); + } + const entries = []; + names.forEach((name, index) => { + const stats = results[index]; + const entry = { + name, + path: filepaths[index], + dirent: utils.fs.createDirentFromStats(name, stats) + }; + if (settings.stats) { + entry.stats = stats; + } + entries.push(entry); + }); + callSuccessCallback(callback, entries); + }); + }); +} +exports.readdir = readdir; +function callFailureCallback(callback, error) { + callback(error); +} +function callSuccessCallback(callback, result) { + callback(null, result); +} - if (prev && prev.type === 'paren') { - const next = peek(); - let output = value; - if (next === '<' && !utils.supportsLookbehinds()) { - throw new Error('Node.js v10 or higher is required for regex lookbehinds'); - } +/***/ }), +/* 334 */ +/***/ (function(module, exports) { - if ((prev.value === '(' && !/[!=<:]/.test(next)) || (next === '<' && !/<([!=]|\w+>)/.test(remaining()))) { - output = `\\${value}`; - } +module.exports = runParallel - push({ type: 'text', value, output }); - continue; - } +function runParallel (tasks, cb) { + var results, pending, keys + var isSync = true - if (opts.dot !== true && (prev.type === 'slash' || prev.type === 'bos')) { - push({ type: 'qmark', value, output: QMARK_NO_DOT }); - continue; - } + if (Array.isArray(tasks)) { + results = [] + pending = tasks.length + } else { + keys = Object.keys(tasks) + results = {} + pending = keys.length + } - push({ type: 'qmark', value, output: QMARK }); - continue; + function done (err) { + function end () { + if (cb) cb(err, results) + cb = null } + if (isSync) process.nextTick(end) + else end() + } - /** - * Exclamation - */ - - if (value === '!') { - if (opts.noextglob !== true && peek() === '(') { - if (peek(2) !== '?' || !/[!=<:]/.test(peek(3))) { - extglobOpen('negate', value); - continue; - } - } - - if (opts.nonegate !== true && state.index === 0) { - negate(); - continue; - } + function each (i, err, result) { + results[i] = result + if (--pending === 0 || err) { + done(err) } + } - /** - * Plus - */ - - if (value === '+') { - if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { - extglobOpen('plus', value); - continue; - } - - if ((prev && prev.value === '(') || opts.regex === false) { - push({ type: 'plus', value, output: PLUS_LITERAL }); - continue; - } - - if ((prev && (prev.type === 'bracket' || prev.type === 'paren' || prev.type === 'brace')) || state.parens > 0) { - push({ type: 'plus', value }); - continue; - } + if (!pending) { + // empty + done(null) + } else if (keys) { + // object + keys.forEach(function (key) { + tasks[key](function (err, result) { each(key, err, result) }) + }) + } else { + // array + tasks.forEach(function (task, i) { + task(function (err, result) { each(i, err, result) }) + }) + } - push({ type: 'plus', value: PLUS_LITERAL }); - continue; - } + isSync = false +} - /** - * Plain text - */ - if (value === '@') { - if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { - push({ type: 'at', extglob: true, value, output: '' }); - continue; - } +/***/ }), +/* 335 */ +/***/ (function(module, exports, __webpack_require__) { - push({ type: 'text', value }); - continue; - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const NODE_PROCESS_VERSION_PARTS = process.versions.node.split('.'); +const MAJOR_VERSION = parseInt(NODE_PROCESS_VERSION_PARTS[0], 10); +const MINOR_VERSION = parseInt(NODE_PROCESS_VERSION_PARTS[1], 10); +const SUPPORTED_MAJOR_VERSION = 10; +const SUPPORTED_MINOR_VERSION = 10; +const IS_MATCHED_BY_MAJOR = MAJOR_VERSION > SUPPORTED_MAJOR_VERSION; +const IS_MATCHED_BY_MAJOR_AND_MINOR = MAJOR_VERSION === SUPPORTED_MAJOR_VERSION && MINOR_VERSION >= SUPPORTED_MINOR_VERSION; +/** + * IS `true` for Node.js 10.10 and greater. + */ +exports.IS_SUPPORT_READDIR_WITH_FILE_TYPES = IS_MATCHED_BY_MAJOR || IS_MATCHED_BY_MAJOR_AND_MINOR; - /** - * Plain text - */ - if (value !== '*') { - if (value === '$' || value === '^') { - value = `\\${value}`; - } +/***/ }), +/* 336 */ +/***/ (function(module, exports, __webpack_require__) { - const match = REGEX_NON_SPECIAL_CHARS.exec(remaining()); - if (match) { - value += match[0]; - state.index += match[0].length; - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const fs = __webpack_require__(337); +exports.fs = fs; - push({ type: 'text', value }); - continue; - } - /** - * Stars - */ +/***/ }), +/* 337 */ +/***/ (function(module, exports, __webpack_require__) { - if (prev && (prev.type === 'globstar' || prev.star === true)) { - prev.type = 'star'; - prev.star = true; - prev.value += value; - prev.output = star; - state.backtrack = true; - state.globstar = true; - consume(value); - continue; - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +class DirentFromStats { + constructor(name, stats) { + this.name = name; + this.isBlockDevice = stats.isBlockDevice.bind(stats); + this.isCharacterDevice = stats.isCharacterDevice.bind(stats); + this.isDirectory = stats.isDirectory.bind(stats); + this.isFIFO = stats.isFIFO.bind(stats); + this.isFile = stats.isFile.bind(stats); + this.isSocket = stats.isSocket.bind(stats); + this.isSymbolicLink = stats.isSymbolicLink.bind(stats); + } +} +function createDirentFromStats(name, stats) { + return new DirentFromStats(name, stats); +} +exports.createDirentFromStats = createDirentFromStats; - let rest = remaining(); - if (opts.noextglob !== true && /^\([^?]/.test(rest)) { - extglobOpen('star', value); - continue; - } - if (prev.type === 'star') { - if (opts.noglobstar === true) { - consume(value); - continue; - } +/***/ }), +/* 338 */ +/***/ (function(module, exports, __webpack_require__) { - const prior = prev.prev; - const before = prior.prev; - const isStart = prior.type === 'slash' || prior.type === 'bos'; - const afterStar = before && (before.type === 'star' || before.type === 'globstar'); +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const fsStat = __webpack_require__(324); +const constants_1 = __webpack_require__(335); +const utils = __webpack_require__(336); +function read(directory, settings) { + if (!settings.stats && constants_1.IS_SUPPORT_READDIR_WITH_FILE_TYPES) { + return readdirWithFileTypes(directory, settings); + } + return readdir(directory, settings); +} +exports.read = read; +function readdirWithFileTypes(directory, settings) { + const dirents = settings.fs.readdirSync(directory, { withFileTypes: true }); + return dirents.map((dirent) => { + const entry = { + dirent, + name: dirent.name, + path: `${directory}${settings.pathSegmentSeparator}${dirent.name}` + }; + if (entry.dirent.isSymbolicLink() && settings.followSymbolicLinks) { + try { + const stats = settings.fs.statSync(entry.path); + entry.dirent = utils.fs.createDirentFromStats(entry.name, stats); + } + catch (error) { + if (settings.throwErrorOnBrokenSymbolicLink) { + throw error; + } + } + } + return entry; + }); +} +exports.readdirWithFileTypes = readdirWithFileTypes; +function readdir(directory, settings) { + const names = settings.fs.readdirSync(directory); + return names.map((name) => { + const entryPath = `${directory}${settings.pathSegmentSeparator}${name}`; + const stats = fsStat.statSync(entryPath, settings.fsStatSettings); + const entry = { + name, + path: entryPath, + dirent: utils.fs.createDirentFromStats(name, stats) + }; + if (settings.stats) { + entry.stats = stats; + } + return entry; + }); +} +exports.readdir = readdir; - if (opts.bash === true && (!isStart || (rest[0] && rest[0] !== '/'))) { - push({ type: 'star', value, output: '' }); - continue; - } - const isBrace = state.braces > 0 && (prior.type === 'comma' || prior.type === 'brace'); - const isExtglob = extglobs.length && (prior.type === 'pipe' || prior.type === 'paren'); - if (!isStart && prior.type !== 'paren' && !isBrace && !isExtglob) { - push({ type: 'star', value, output: '' }); - continue; - } +/***/ }), +/* 339 */ +/***/ (function(module, exports, __webpack_require__) { - // strip consecutive `/**/` - while (rest.slice(0, 3) === '/**') { - const after = input[state.index + 4]; - if (after && after !== '/') { - break; - } - rest = rest.slice(3); - consume('/**', 3); - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const path = __webpack_require__(4); +const fsStat = __webpack_require__(324); +const fs = __webpack_require__(340); +class Settings { + constructor(_options = {}) { + this._options = _options; + this.followSymbolicLinks = this._getValue(this._options.followSymbolicLinks, false); + this.fs = fs.createFileSystemAdapter(this._options.fs); + this.pathSegmentSeparator = this._getValue(this._options.pathSegmentSeparator, path.sep); + this.stats = this._getValue(this._options.stats, false); + this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, true); + this.fsStatSettings = new fsStat.Settings({ + followSymbolicLink: this.followSymbolicLinks, + fs: this.fs, + throwErrorOnBrokenSymbolicLink: this.throwErrorOnBrokenSymbolicLink + }); + } + _getValue(option, value) { + return option === undefined ? value : option; + } +} +exports.default = Settings; - if (prior.type === 'bos' && eos()) { - prev.type = 'globstar'; - prev.value += value; - prev.output = globstar(opts); - state.output = prev.output; - state.globstar = true; - consume(value); - continue; - } - if (prior.type === 'slash' && prior.prev.type !== 'bos' && !afterStar && eos()) { - state.output = state.output.slice(0, -(prior.output + prev.output).length); - prior.output = `(?:${prior.output}`; +/***/ }), +/* 340 */ +/***/ (function(module, exports, __webpack_require__) { - prev.type = 'globstar'; - prev.output = globstar(opts) + (opts.strictSlashes ? ')' : '|$)'); - prev.value += value; - state.globstar = true; - state.output += prior.output + prev.output; - consume(value); - continue; - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const fs = __webpack_require__(133); +exports.FILE_SYSTEM_ADAPTER = { + lstat: fs.lstat, + stat: fs.stat, + lstatSync: fs.lstatSync, + statSync: fs.statSync, + readdir: fs.readdir, + readdirSync: fs.readdirSync +}; +function createFileSystemAdapter(fsMethods) { + if (fsMethods === undefined) { + return exports.FILE_SYSTEM_ADAPTER; + } + return Object.assign(Object.assign({}, exports.FILE_SYSTEM_ADAPTER), fsMethods); +} +exports.createFileSystemAdapter = createFileSystemAdapter; - if (prior.type === 'slash' && prior.prev.type !== 'bos' && rest[0] === '/') { - const end = rest[1] !== void 0 ? '|$' : ''; - state.output = state.output.slice(0, -(prior.output + prev.output).length); - prior.output = `(?:${prior.output}`; +/***/ }), +/* 341 */ +/***/ (function(module, exports, __webpack_require__) { - prev.type = 'globstar'; - prev.output = `${globstar(opts)}${SLASH_LITERAL}|${SLASH_LITERAL}${end})`; - prev.value += value; +"use strict"; - state.output += prior.output + prev.output; - state.globstar = true; - consume(value + advance()); +var reusify = __webpack_require__(342) - push({ type: 'slash', value: '/', output: '' }); - continue; - } +function fastqueue (context, worker, concurrency) { + if (typeof context === 'function') { + concurrency = worker + worker = context + context = null + } - if (prior.type === 'bos' && rest[0] === '/') { - prev.type = 'globstar'; - prev.value += value; - prev.output = `(?:^|${SLASH_LITERAL}|${globstar(opts)}${SLASH_LITERAL})`; - state.output = prev.output; - state.globstar = true; - consume(value + advance()); - push({ type: 'slash', value: '/', output: '' }); - continue; - } + var cache = reusify(Task) + var queueHead = null + var queueTail = null + var _running = 0 - // remove single star from output - state.output = state.output.slice(0, -prev.output.length); + var self = { + push: push, + drain: noop, + saturated: noop, + pause: pause, + paused: false, + concurrency: concurrency, + running: running, + resume: resume, + idle: idle, + length: length, + unshift: unshift, + empty: noop, + kill: kill, + killAndDrain: killAndDrain + } - // reset previous token to globstar - prev.type = 'globstar'; - prev.output = globstar(opts); - prev.value += value; + return self - // reset output with globstar - state.output += prev.output; - state.globstar = true; - consume(value); - continue; - } + function running () { + return _running + } - const token = { type: 'star', value, output: star }; + function pause () { + self.paused = true + } - if (opts.bash === true) { - token.output = '.*?'; - if (prev.type === 'bos' || prev.type === 'slash') { - token.output = nodot + token.output; - } - push(token); - continue; + function length () { + var current = queueHead + var counter = 0 + + while (current) { + current = current.next + counter++ } - if (prev && (prev.type === 'bracket' || prev.type === 'paren') && opts.regex === true) { - token.output = value; - push(token); - continue; + return counter + } + + function resume () { + if (!self.paused) return + self.paused = false + for (var i = 0; i < self.concurrency; i++) { + _running++ + release() } + } - if (state.index === state.start || prev.type === 'slash' || prev.type === 'dot') { - if (prev.type === 'dot') { - state.output += NO_DOT_SLASH; - prev.output += NO_DOT_SLASH; + function idle () { + return _running === 0 && self.length() === 0 + } - } else if (opts.dot === true) { - state.output += NO_DOTS_SLASH; - prev.output += NO_DOTS_SLASH; + function push (value, done) { + var current = cache.get() + + current.context = context + current.release = release + current.value = value + current.callback = done || noop + if (_running === self.concurrency || self.paused) { + if (queueTail) { + queueTail.next = current + queueTail = current } else { - state.output += nodot; - prev.output += nodot; + queueHead = current + queueTail = current + self.saturated() } + } else { + _running++ + worker.call(context, current.value, current.worked) + } + } - if (peek() !== '*') { - state.output += ONE_CHAR; - prev.output += ONE_CHAR; + function unshift (value, done) { + var current = cache.get() + + current.context = context + current.release = release + current.value = value + current.callback = done || noop + + if (_running === self.concurrency || self.paused) { + if (queueHead) { + current.next = queueHead + queueHead = current + } else { + queueHead = current + queueTail = current + self.saturated() } + } else { + _running++ + worker.call(context, current.value, current.worked) } - - push(token); } - while (state.brackets > 0) { - if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ']')); - state.output = utils.escapeLast(state.output, '['); - decrement('brackets'); + function release (holder) { + if (holder) { + cache.release(holder) + } + var next = queueHead + if (next) { + if (!self.paused) { + if (queueTail === queueHead) { + queueTail = null + } + queueHead = next.next + next.next = null + worker.call(context, next.value, next.worked) + if (queueTail === null) { + self.empty() + } + } else { + _running-- + } + } else if (--_running === 0) { + self.drain() + } } - while (state.parens > 0) { - if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ')')); - state.output = utils.escapeLast(state.output, '('); - decrement('parens'); + function kill () { + queueHead = null + queueTail = null + self.drain = noop } - while (state.braces > 0) { - if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', '}')); - state.output = utils.escapeLast(state.output, '{'); - decrement('braces'); + function killAndDrain () { + queueHead = null + queueTail = null + self.drain() + self.drain = noop } +} - if (opts.strictSlashes !== true && (prev.type === 'star' || prev.type === 'bracket')) { - push({ type: 'maybe_slash', value: '', output: `${SLASH_LITERAL}?` }); - } +function noop () {} - // rebuild the output if we had to backtrack at any point - if (state.backtrack === true) { - state.output = ''; +function Task () { + this.value = null + this.callback = noop + this.next = null + this.release = noop + this.context = null - for (const token of state.tokens) { - state.output += token.output != null ? token.output : token.value; + var self = this - if (token.suffix) { - state.output += token.suffix; - } - } + this.worked = function worked (err, result) { + var callback = self.callback + self.value = null + self.callback = noop + callback.call(self.context, err, result) + self.release(self) } +} - return state; -}; +module.exports = fastqueue -/** - * Fast paths for creating regular expressions for common glob patterns. - * This can significantly speed up processing and has very little downside - * impact when none of the fast paths match. - */ -parse.fastpaths = (input, options) => { - const opts = { ...options }; - const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; - const len = input.length; - if (len > max) { - throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); - } +/***/ }), +/* 342 */ +/***/ (function(module, exports, __webpack_require__) { - input = REPLACEMENTS[input] || input; - const win32 = utils.isWindows(options); +"use strict"; - // create constants based on platform, for windows or posix - const { - DOT_LITERAL, - SLASH_LITERAL, - ONE_CHAR, - DOTS_SLASH, - NO_DOT, - NO_DOTS, - NO_DOTS_SLASH, - STAR, - START_ANCHOR - } = constants.globChars(win32); - const nodot = opts.dot ? NO_DOTS : NO_DOT; - const slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT; - const capture = opts.capture ? '' : '?:'; - const state = { negated: false, prefix: '' }; - let star = opts.bash === true ? '.*?' : STAR; +function reusify (Constructor) { + var head = new Constructor() + var tail = head - if (opts.capture) { - star = `(${star})`; - } + function get () { + var current = head - const globstar = (opts) => { - if (opts.noglobstar === true) return star; - return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; - }; + if (current.next) { + head = current.next + } else { + head = new Constructor() + tail = head + } - const create = str => { - switch (str) { - case '*': - return `${nodot}${ONE_CHAR}${star}`; + current.next = null - case '.*': - return `${DOT_LITERAL}${ONE_CHAR}${star}`; + return current + } - case '*.*': - return `${nodot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; + function release (obj) { + tail.next = obj + tail = obj + } - case '*/*': - return `${nodot}${star}${SLASH_LITERAL}${ONE_CHAR}${slashDot}${star}`; + return { + get: get, + release: release + } +} - case '**': - return nodot + globstar(opts); +module.exports = reusify - case '**/*': - return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${ONE_CHAR}${star}`; - case '**/*.*': - return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; +/***/ }), +/* 343 */ +/***/ (function(module, exports, __webpack_require__) { - case '**/.*': - return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${DOT_LITERAL}${ONE_CHAR}${star}`; +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +function isFatalError(settings, error) { + if (settings.errorFilter === null) { + return true; + } + return !settings.errorFilter(error); +} +exports.isFatalError = isFatalError; +function isAppliedFilter(filter, value) { + return filter === null || filter(value); +} +exports.isAppliedFilter = isAppliedFilter; +function replacePathSegmentSeparator(filepath, separator) { + return filepath.split(/[\\/]/).join(separator); +} +exports.replacePathSegmentSeparator = replacePathSegmentSeparator; +function joinPathSegments(a, b, separator) { + if (a === '') { + return b; + } + return a + separator + b; +} +exports.joinPathSegments = joinPathSegments; - default: { - const match = /^(.*?)\.(\w+)$/.exec(str); - if (!match) return; - const source = create(match[1]); - if (!source) return; +/***/ }), +/* 344 */ +/***/ (function(module, exports, __webpack_require__) { - return source + DOT_LITERAL + match[2]; - } - } - }; +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const common = __webpack_require__(343); +class Reader { + constructor(_root, _settings) { + this._root = _root; + this._settings = _settings; + this._root = common.replacePathSegmentSeparator(_root, _settings.pathSegmentSeparator); + } +} +exports.default = Reader; - const output = utils.removePrefix(input, state); - let source = create(output); - if (source && opts.strictSlashes !== true) { - source += `${SLASH_LITERAL}?`; - } +/***/ }), +/* 345 */ +/***/ (function(module, exports, __webpack_require__) { - return source; -}; +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const stream_1 = __webpack_require__(137); +const async_1 = __webpack_require__(331); +class StreamProvider { + constructor(_root, _settings) { + this._root = _root; + this._settings = _settings; + this._reader = new async_1.default(this._root, this._settings); + this._stream = new stream_1.Readable({ + objectMode: true, + read: () => { }, + destroy: this._reader.destroy.bind(this._reader) + }); + } + read() { + this._reader.onError((error) => { + this._stream.emit('error', error); + }); + this._reader.onEntry((entry) => { + this._stream.push(entry); + }); + this._reader.onEnd(() => { + this._stream.push(null); + }); + this._reader.read(); + return this._stream; + } +} +exports.default = StreamProvider; -module.exports = parse; + +/***/ }), +/* 346 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const sync_1 = __webpack_require__(347); +class SyncProvider { + constructor(_root, _settings) { + this._root = _root; + this._settings = _settings; + this._reader = new sync_1.default(this._root, this._settings); + } + read() { + return this._reader.read(); + } +} +exports.default = SyncProvider; /***/ }), -/* 328 */ +/* 347 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const merge2 = __webpack_require__(299); -function merge(streams) { - const mergedStream = merge2(streams); - streams.forEach((stream) => { - stream.once('error', (error) => mergedStream.emit('error', error)); - }); - mergedStream.once('close', () => propagateCloseEventToSources(streams)); - mergedStream.once('end', () => propagateCloseEventToSources(streams)); - return mergedStream; +const fsScandir = __webpack_require__(332); +const common = __webpack_require__(343); +const reader_1 = __webpack_require__(344); +class SyncReader extends reader_1.default { + constructor() { + super(...arguments); + this._scandir = fsScandir.scandirSync; + this._storage = new Set(); + this._queue = new Set(); + } + read() { + this._pushToQueue(this._root, this._settings.basePath); + this._handleQueue(); + return [...this._storage]; + } + _pushToQueue(directory, base) { + this._queue.add({ directory, base }); + } + _handleQueue() { + for (const item of this._queue.values()) { + this._handleDirectory(item.directory, item.base); + } + } + _handleDirectory(directory, base) { + try { + const entries = this._scandir(directory, this._settings.fsScandirSettings); + for (const entry of entries) { + this._handleEntry(entry, base); + } + } + catch (error) { + this._handleError(error); + } + } + _handleError(error) { + if (!common.isFatalError(this._settings, error)) { + return; + } + throw error; + } + _handleEntry(entry, base) { + const fullpath = entry.path; + if (base !== undefined) { + entry.path = common.joinPathSegments(base, entry.name, this._settings.pathSegmentSeparator); + } + if (common.isAppliedFilter(this._settings.entryFilter, entry)) { + this._pushToStorage(entry); + } + if (entry.dirent.isDirectory() && common.isAppliedFilter(this._settings.deepFilter, entry)) { + this._pushToQueue(fullpath, entry.path); + } + } + _pushToStorage(entry) { + this._storage.add(entry); + } } -exports.merge = merge; -function propagateCloseEventToSources(streams) { - streams.forEach((stream) => stream.emit('close')); +exports.default = SyncReader; + + +/***/ }), +/* 348 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const path = __webpack_require__(4); +const fsScandir = __webpack_require__(332); +class Settings { + constructor(_options = {}) { + this._options = _options; + this.basePath = this._getValue(this._options.basePath, undefined); + this.concurrency = this._getValue(this._options.concurrency, Infinity); + this.deepFilter = this._getValue(this._options.deepFilter, null); + this.entryFilter = this._getValue(this._options.entryFilter, null); + this.errorFilter = this._getValue(this._options.errorFilter, null); + this.pathSegmentSeparator = this._getValue(this._options.pathSegmentSeparator, path.sep); + this.fsScandirSettings = new fsScandir.Settings({ + followSymbolicLinks: this._options.followSymbolicLinks, + fs: this._options.fs, + pathSegmentSeparator: this._options.pathSegmentSeparator, + stats: this._options.stats, + throwErrorOnBrokenSymbolicLink: this._options.throwErrorOnBrokenSymbolicLink + }); + } + _getValue(option, value) { + return option === undefined ? value : option; + } } +exports.default = Settings; /***/ }), -/* 329 */ +/* 349 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -function isString(input) { - return typeof input === 'string'; -} -exports.isString = isString; -function isEmpty(input) { - return input === ''; +const path = __webpack_require__(4); +const fsStat = __webpack_require__(324); +const utils = __webpack_require__(294); +class Reader { + constructor(_settings) { + this._settings = _settings; + this._fsStatSettings = new fsStat.Settings({ + followSymbolicLink: this._settings.followSymbolicLinks, + fs: this._settings.fs, + throwErrorOnBrokenSymbolicLink: this._settings.followSymbolicLinks + }); + } + _getFullEntryPath(filepath) { + return path.resolve(this._settings.cwd, filepath); + } + _makeEntry(stats, pattern) { + const entry = { + name: pattern, + path: pattern, + dirent: utils.fs.createDirentFromStats(pattern, stats) + }; + if (this._settings.stats) { + entry.stats = stats; + } + return entry; + } + _isFatalError(error) { + return !utils.errno.isEnoentCodeError(error) && !this._settings.suppressErrors; + } } -exports.isEmpty = isEmpty; +exports.default = Reader; /***/ }), -/* 330 */ +/* 350 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const stream_1 = __webpack_require__(331); -const provider_1 = __webpack_require__(358); -class ProviderAsync extends provider_1.default { - constructor() { - super(...arguments); - this._reader = new stream_1.default(this._settings); +const path = __webpack_require__(4); +const deep_1 = __webpack_require__(351); +const entry_1 = __webpack_require__(354); +const error_1 = __webpack_require__(355); +const entry_2 = __webpack_require__(356); +class Provider { + constructor(_settings) { + this._settings = _settings; + this.errorFilter = new error_1.default(this._settings); + this.entryFilter = new entry_1.default(this._settings, this._getMicromatchOptions()); + this.deepFilter = new deep_1.default(this._settings, this._getMicromatchOptions()); + this.entryTransformer = new entry_2.default(this._settings); } - read(task) { - const root = this._getRootDirectory(task); - const options = this._getReaderOptions(task); - const entries = []; - return new Promise((resolve, reject) => { - const stream = this.api(root, task, options); - stream.once('error', reject); - stream.on('data', (entry) => entries.push(options.transform(entry))); - stream.once('end', () => resolve(entries)); - }); + _getRootDirectory(task) { + return path.resolve(this._settings.cwd, task.base); } - api(root, task, options) { - if (task.dynamic) { - return this._reader.dynamic(root, options); - } - return this._reader.static(task.patterns, options); + _getReaderOptions(task) { + const basePath = task.base === '.' ? '' : task.base; + return { + basePath, + pathSegmentSeparator: '/', + concurrency: this._settings.concurrency, + deepFilter: this.deepFilter.getFilter(basePath, task.positive, task.negative), + entryFilter: this.entryFilter.getFilter(task.positive, task.negative), + errorFilter: this.errorFilter.getFilter(), + followSymbolicLinks: this._settings.followSymbolicLinks, + fs: this._settings.fs, + stats: this._settings.stats, + throwErrorOnBrokenSymbolicLink: this._settings.throwErrorOnBrokenSymbolicLink, + transform: this.entryTransformer.getTransformer() + }; + } + _getMicromatchOptions() { + return { + dot: this._settings.dot, + matchBase: this._settings.baseNameMatch, + nobrace: !this._settings.braceExpansion, + nocase: !this._settings.caseSensitiveMatch, + noext: !this._settings.extglob, + noglobstar: !this._settings.globstar, + posix: true, + strictSlashes: false + }; } } -exports.default = ProviderAsync; +exports.default = Provider; /***/ }), -/* 331 */ +/* 351 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const stream_1 = __webpack_require__(137); -const fsStat = __webpack_require__(332); -const fsWalk = __webpack_require__(337); -const reader_1 = __webpack_require__(357); -class ReaderStream extends reader_1.default { - constructor() { - super(...arguments); - this._walkStream = fsWalk.walkStream; - this._stat = fsStat.stat; +const utils = __webpack_require__(294); +const partial_1 = __webpack_require__(352); +class DeepFilter { + constructor(_settings, _micromatchOptions) { + this._settings = _settings; + this._micromatchOptions = _micromatchOptions; } - dynamic(root, options) { - return this._walkStream(root, options); + getFilter(basePath, positive, negative) { + const matcher = this._getMatcher(positive); + const negativeRe = this._getNegativePatternsRe(negative); + return (entry) => this._filter(basePath, entry, matcher, negativeRe); } - static(patterns, options) { - const filepaths = patterns.map(this._getFullEntryPath, this); - const stream = new stream_1.PassThrough({ objectMode: true }); - stream._write = (index, _enc, done) => { - return this._getEntry(filepaths[index], patterns[index], options) - .then((entry) => { - if (entry !== null && options.entryFilter(entry)) { - stream.push(entry); - } - if (index === filepaths.length - 1) { - stream.end(); - } - done(); - }) - .catch(done); - }; - for (let i = 0; i < filepaths.length; i++) { - stream.write(i); + _getMatcher(patterns) { + return new partial_1.default(patterns, this._settings, this._micromatchOptions); + } + _getNegativePatternsRe(patterns) { + const affectDepthOfReadingPatterns = patterns.filter(utils.pattern.isAffectDepthOfReadingPattern); + return utils.pattern.convertPatternsToRe(affectDepthOfReadingPatterns, this._micromatchOptions); + } + _filter(basePath, entry, matcher, negativeRe) { + const depth = this._getEntryLevel(basePath, entry.path); + if (this._isSkippedByDeep(depth)) { + return false; } - return stream; + if (this._isSkippedSymbolicLink(entry)) { + return false; + } + const filepath = utils.path.removeLeadingDotSegment(entry.path); + if (this._isSkippedByPositivePatterns(filepath, matcher)) { + return false; + } + return this._isSkippedByNegativePatterns(filepath, negativeRe); } - _getEntry(filepath, pattern, options) { - return this._getStat(filepath) - .then((stats) => this._makeEntry(stats, pattern)) - .catch((error) => { - if (options.errorFilter(error)) { - return null; - } - throw error; - }); + _isSkippedByDeep(entryDepth) { + return entryDepth >= this._settings.deep; } - _getStat(filepath) { - return new Promise((resolve, reject) => { - this._stat(filepath, this._fsStatSettings, (error, stats) => { - return error === null ? resolve(stats) : reject(error); - }); - }); + _isSkippedSymbolicLink(entry) { + return !this._settings.followSymbolicLinks && entry.dirent.isSymbolicLink(); + } + _getEntryLevel(basePath, entryPath) { + const basePathDepth = basePath.split('/').length; + const entryPathDepth = entryPath.split('/').length; + return entryPathDepth - (basePath === '' ? 0 : basePathDepth); + } + _isSkippedByPositivePatterns(entryPath, matcher) { + return !this._settings.baseNameMatch && !matcher.match(entryPath); + } + _isSkippedByNegativePatterns(entryPath, negativeRe) { + return !utils.pattern.matchAny(entryPath, negativeRe); } } -exports.default = ReaderStream; +exports.default = DeepFilter; /***/ }), -/* 332 */ +/* 352 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const async = __webpack_require__(333); -const sync = __webpack_require__(334); -const settings_1 = __webpack_require__(335); -exports.Settings = settings_1.default; -function stat(path, optionsOrSettingsOrCallback, callback) { - if (typeof optionsOrSettingsOrCallback === 'function') { - return async.read(path, getSettings(), optionsOrSettingsOrCallback); - } - async.read(path, getSettings(optionsOrSettingsOrCallback), callback); -} -exports.stat = stat; -function statSync(path, optionsOrSettings) { - const settings = getSettings(optionsOrSettings); - return sync.read(path, settings); -} -exports.statSync = statSync; -function getSettings(settingsOrOptions = {}) { - if (settingsOrOptions instanceof settings_1.default) { - return settingsOrOptions; +const matcher_1 = __webpack_require__(353); +class PartialMatcher extends matcher_1.default { + match(filepath) { + const parts = filepath.split('/'); + const levels = parts.length; + const patterns = this._storage.filter((info) => !info.complete || info.segments.length > levels); + for (const pattern of patterns) { + const section = pattern.sections[0]; + /** + * In this case, the pattern has a globstar and we must read all directories unconditionally, + * but only if the level has reached the end of the first group. + * + * fixtures/{a,b}/** + * ^ true/false ^ always true + */ + if (!pattern.complete && levels > section.length) { + return true; + } + const match = parts.every((part, index) => { + const segment = pattern.segments[index]; + if (segment.dynamic && segment.patternRe.test(part)) { + return true; + } + if (!segment.dynamic && segment.pattern === part) { + return true; + } + return false; + }); + if (match) { + return true; + } + } + return false; } - return new settings_1.default(settingsOrOptions); } +exports.default = PartialMatcher; /***/ }), -/* 333 */ +/* 353 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -function read(path, settings, callback) { - settings.fs.lstat(path, (lstatError, lstat) => { - if (lstatError !== null) { - return callFailureCallback(callback, lstatError); - } - if (!lstat.isSymbolicLink() || !settings.followSymbolicLink) { - return callSuccessCallback(callback, lstat); +const utils = __webpack_require__(294); +class Matcher { + constructor(_patterns, _settings, _micromatchOptions) { + this._patterns = _patterns; + this._settings = _settings; + this._micromatchOptions = _micromatchOptions; + this._storage = []; + this._fillStorage(); + } + _fillStorage() { + /** + * The original pattern may include `{,*,**,a/*}`, which will lead to problems with matching (unresolved level). + * So, before expand patterns with brace expansion into separated patterns. + */ + const patterns = utils.pattern.expandPatternsWithBraceExpansion(this._patterns); + for (const pattern of patterns) { + const segments = this._getPatternSegments(pattern); + const sections = this._splitSegmentsIntoSections(segments); + this._storage.push({ + complete: sections.length <= 1, + pattern, + segments, + sections + }); } - settings.fs.stat(path, (statError, stat) => { - if (statError !== null) { - if (settings.throwErrorOnBrokenSymbolicLink) { - return callFailureCallback(callback, statError); - } - return callSuccessCallback(callback, lstat); - } - if (settings.markSymbolicLink) { - stat.isSymbolicLink = () => true; + } + _getPatternSegments(pattern) { + const parts = utils.pattern.getPatternParts(pattern, this._micromatchOptions); + return parts.map((part) => { + const dynamic = utils.pattern.isDynamicPattern(part, this._settings); + if (!dynamic) { + return { + dynamic: false, + pattern: part + }; } - callSuccessCallback(callback, stat); + return { + dynamic: true, + pattern: part, + patternRe: utils.pattern.makeRe(part, this._micromatchOptions) + }; }); - }); -} -exports.read = read; -function callFailureCallback(callback, error) { - callback(error); -} -function callSuccessCallback(callback, result) { - callback(null, result); + } + _splitSegmentsIntoSections(segments) { + return utils.array.splitWhen(segments, (segment) => segment.dynamic && utils.pattern.hasGlobStar(segment.pattern)); + } } +exports.default = Matcher; /***/ }), -/* 334 */ +/* 354 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -function read(path, settings) { - const lstat = settings.fs.lstatSync(path); - if (!lstat.isSymbolicLink() || !settings.followSymbolicLink) { - return lstat; +const utils = __webpack_require__(294); +class EntryFilter { + constructor(_settings, _micromatchOptions) { + this._settings = _settings; + this._micromatchOptions = _micromatchOptions; + this.index = new Map(); } - try { - const stat = settings.fs.statSync(path); - if (settings.markSymbolicLink) { - stat.isSymbolicLink = () => true; + getFilter(positive, negative) { + const positiveRe = utils.pattern.convertPatternsToRe(positive, this._micromatchOptions); + const negativeRe = utils.pattern.convertPatternsToRe(negative, this._micromatchOptions); + return (entry) => this._filter(entry, positiveRe, negativeRe); + } + _filter(entry, positiveRe, negativeRe) { + if (this._settings.unique) { + if (this._isDuplicateEntry(entry)) { + return false; + } + this._createIndexRecord(entry); } - return stat; + if (this._onlyFileFilter(entry) || this._onlyDirectoryFilter(entry)) { + return false; + } + if (this._isSkippedByAbsoluteNegativePatterns(entry, negativeRe)) { + return false; + } + const filepath = this._settings.baseNameMatch ? entry.name : entry.path; + return this._isMatchToPatterns(filepath, positiveRe) && !this._isMatchToPatterns(entry.path, negativeRe); } - catch (error) { - if (!settings.throwErrorOnBrokenSymbolicLink) { - return lstat; + _isDuplicateEntry(entry) { + return this.index.has(entry.path); + } + _createIndexRecord(entry) { + this.index.set(entry.path, undefined); + } + _onlyFileFilter(entry) { + return this._settings.onlyFiles && !entry.dirent.isFile(); + } + _onlyDirectoryFilter(entry) { + return this._settings.onlyDirectories && !entry.dirent.isDirectory(); + } + _isSkippedByAbsoluteNegativePatterns(entry, negativeRe) { + if (!this._settings.absolute) { + return false; } - throw error; + const fullpath = utils.path.makeAbsolute(this._settings.cwd, entry.path); + return this._isMatchToPatterns(fullpath, negativeRe); + } + _isMatchToPatterns(entryPath, patternsRe) { + const filepath = utils.path.removeLeadingDotSegment(entryPath); + return utils.pattern.matchAny(filepath, patternsRe); } } -exports.read = read; +exports.default = EntryFilter; /***/ }), -/* 335 */ +/* 355 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const fs = __webpack_require__(336); -class Settings { - constructor(_options = {}) { - this._options = _options; - this.followSymbolicLink = this._getValue(this._options.followSymbolicLink, true); - this.fs = fs.createFileSystemAdapter(this._options.fs); - this.markSymbolicLink = this._getValue(this._options.markSymbolicLink, false); - this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, true); +const utils = __webpack_require__(294); +class ErrorFilter { + constructor(_settings) { + this._settings = _settings; } - _getValue(option, value) { - return option === undefined ? value : option; + getFilter() { + return (error) => this._isNonFatalError(error); } -} -exports.default = Settings; - - -/***/ }), -/* 336 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const fs = __webpack_require__(133); -exports.FILE_SYSTEM_ADAPTER = { - lstat: fs.lstat, - stat: fs.stat, - lstatSync: fs.lstatSync, - statSync: fs.statSync -}; -function createFileSystemAdapter(fsMethods) { - if (fsMethods === undefined) { - return exports.FILE_SYSTEM_ADAPTER; + _isNonFatalError(error) { + return utils.errno.isEnoentCodeError(error) || this._settings.suppressErrors; } - return Object.assign(Object.assign({}, exports.FILE_SYSTEM_ADAPTER), fsMethods); } -exports.createFileSystemAdapter = createFileSystemAdapter; +exports.default = ErrorFilter; /***/ }), -/* 337 */ +/* 356 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const async_1 = __webpack_require__(338); -const stream_1 = __webpack_require__(353); -const sync_1 = __webpack_require__(354); -const settings_1 = __webpack_require__(356); -exports.Settings = settings_1.default; -function walk(directory, optionsOrSettingsOrCallback, callback) { - if (typeof optionsOrSettingsOrCallback === 'function') { - return new async_1.default(directory, getSettings()).read(optionsOrSettingsOrCallback); +const utils = __webpack_require__(294); +class EntryTransformer { + constructor(_settings) { + this._settings = _settings; } - new async_1.default(directory, getSettings(optionsOrSettingsOrCallback)).read(callback); -} -exports.walk = walk; -function walkSync(directory, optionsOrSettings) { - const settings = getSettings(optionsOrSettings); - const provider = new sync_1.default(directory, settings); - return provider.read(); -} -exports.walkSync = walkSync; -function walkStream(directory, optionsOrSettings) { - const settings = getSettings(optionsOrSettings); - const provider = new stream_1.default(directory, settings); - return provider.read(); -} -exports.walkStream = walkStream; -function getSettings(settingsOrOptions = {}) { - if (settingsOrOptions instanceof settings_1.default) { - return settingsOrOptions; + getTransformer() { + return (entry) => this._transform(entry); + } + _transform(entry) { + let filepath = entry.path; + if (this._settings.absolute) { + filepath = utils.path.makeAbsolute(this._settings.cwd, filepath); + filepath = utils.path.unixify(filepath); + } + if (this._settings.markDirectories && entry.dirent.isDirectory()) { + filepath += '/'; + } + if (!this._settings.objectMode) { + return filepath; + } + return Object.assign(Object.assign({}, entry), { path: filepath }); } - return new settings_1.default(settingsOrOptions); } +exports.default = EntryTransformer; /***/ }), -/* 338 */ +/* 357 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const async_1 = __webpack_require__(339); -class AsyncProvider { - constructor(_root, _settings) { - this._root = _root; - this._settings = _settings; - this._reader = new async_1.default(this._root, this._settings); - this._storage = new Set(); +const stream_1 = __webpack_require__(137); +const stream_2 = __webpack_require__(323); +const provider_1 = __webpack_require__(350); +class ProviderStream extends provider_1.default { + constructor() { + super(...arguments); + this._reader = new stream_2.default(this._settings); } - read(callback) { - this._reader.onError((error) => { - callFailureCallback(callback, error); - }); - this._reader.onEntry((entry) => { - this._storage.add(entry); - }); - this._reader.onEnd(() => { - callSuccessCallback(callback, [...this._storage]); - }); - this._reader.read(); + read(task) { + const root = this._getRootDirectory(task); + const options = this._getReaderOptions(task); + const source = this.api(root, task, options); + const destination = new stream_1.Readable({ objectMode: true, read: () => { } }); + source + .once('error', (error) => destination.emit('error', error)) + .on('data', (entry) => destination.emit('data', options.transform(entry))) + .once('end', () => destination.emit('end')); + destination + .once('close', () => source.destroy()); + return destination; + } + api(root, task, options) { + if (task.dynamic) { + return this._reader.dynamic(root, options); + } + return this._reader.static(task.patterns, options); } } -exports.default = AsyncProvider; -function callFailureCallback(callback, error) { - callback(error); -} -function callSuccessCallback(callback, entries) { - callback(null, entries); -} +exports.default = ProviderStream; /***/ }), -/* 339 */ +/* 358 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const events_1 = __webpack_require__(155); -const fsScandir = __webpack_require__(340); -const fastq = __webpack_require__(349); -const common = __webpack_require__(351); -const reader_1 = __webpack_require__(352); -class AsyncReader extends reader_1.default { - constructor(_root, _settings) { - super(_root, _settings); - this._settings = _settings; - this._scandir = fsScandir.scandir; - this._emitter = new events_1.EventEmitter(); - this._queue = fastq(this._worker.bind(this), this._settings.concurrency); - this._isFatalError = false; - this._isDestroyed = false; - this._queue.drain = () => { - if (!this._isFatalError) { - this._emitter.emit('end'); - } - }; +const sync_1 = __webpack_require__(359); +const provider_1 = __webpack_require__(350); +class ProviderSync extends provider_1.default { + constructor() { + super(...arguments); + this._reader = new sync_1.default(this._settings); } - read() { - this._isFatalError = false; - this._isDestroyed = false; - setImmediate(() => { - this._pushToQueue(this._root, this._settings.basePath); - }); - return this._emitter; + read(task) { + const root = this._getRootDirectory(task); + const options = this._getReaderOptions(task); + const entries = this.api(root, task, options); + return entries.map(options.transform); } - destroy() { - if (this._isDestroyed) { - throw new Error('The reader is already destroyed'); + api(root, task, options) { + if (task.dynamic) { + return this._reader.dynamic(root, options); } - this._isDestroyed = true; - this._queue.killAndDrain(); - } - onEntry(callback) { - this._emitter.on('entry', callback); - } - onError(callback) { - this._emitter.once('error', callback); + return this._reader.static(task.patterns, options); } - onEnd(callback) { - this._emitter.once('end', callback); +} +exports.default = ProviderSync; + + +/***/ }), +/* 359 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const fsStat = __webpack_require__(324); +const fsWalk = __webpack_require__(329); +const reader_1 = __webpack_require__(349); +class ReaderSync extends reader_1.default { + constructor() { + super(...arguments); + this._walkSync = fsWalk.walkSync; + this._statSync = fsStat.statSync; } - _pushToQueue(directory, base) { - const queueItem = { directory, base }; - this._queue.push(queueItem, (error) => { - if (error !== null) { - this._handleError(error); - } - }); + dynamic(root, options) { + return this._walkSync(root, options); } - _worker(item, done) { - this._scandir(item.directory, this._settings.fsScandirSettings, (error, entries) => { - if (error !== null) { - return done(error, undefined); - } - for (const entry of entries) { - this._handleEntry(entry, item.base); + static(patterns, options) { + const entries = []; + for (const pattern of patterns) { + const filepath = this._getFullEntryPath(pattern); + const entry = this._getEntry(filepath, pattern, options); + if (entry === null || !options.entryFilter(entry)) { + continue; } - done(null, undefined); - }); - } - _handleError(error) { - if (!common.isFatalError(this._settings, error)) { - return; + entries.push(entry); } - this._isFatalError = true; - this._isDestroyed = true; - this._emitter.emit('error', error); + return entries; } - _handleEntry(entry, base) { - if (this._isDestroyed || this._isFatalError) { - return; - } - const fullpath = entry.path; - if (base !== undefined) { - entry.path = common.joinPathSegments(base, entry.name, this._settings.pathSegmentSeparator); - } - if (common.isAppliedFilter(this._settings.entryFilter, entry)) { - this._emitEntry(entry); + _getEntry(filepath, pattern, options) { + try { + const stats = this._getStat(filepath); + return this._makeEntry(stats, pattern); } - if (entry.dirent.isDirectory() && common.isAppliedFilter(this._settings.deepFilter, entry)) { - this._pushToQueue(fullpath, entry.path); + catch (error) { + if (options.errorFilter(error)) { + return null; + } + throw error; } } - _emitEntry(entry) { - this._emitter.emit('entry', entry); + _getStat(filepath) { + return this._statSync(filepath, this._fsStatSettings); } } -exports.default = AsyncReader; +exports.default = ReaderSync; /***/ }), -/* 340 */ +/* 360 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const async = __webpack_require__(341); -const sync = __webpack_require__(346); -const settings_1 = __webpack_require__(347); -exports.Settings = settings_1.default; -function scandir(path, optionsOrSettingsOrCallback, callback) { - if (typeof optionsOrSettingsOrCallback === 'function') { - return async.read(path, getSettings(), optionsOrSettingsOrCallback); +const fs = __webpack_require__(133); +const os = __webpack_require__(120); +const CPU_COUNT = os.cpus().length; +exports.DEFAULT_FILE_SYSTEM_ADAPTER = { + lstat: fs.lstat, + lstatSync: fs.lstatSync, + stat: fs.stat, + statSync: fs.statSync, + readdir: fs.readdir, + readdirSync: fs.readdirSync +}; +class Settings { + constructor(_options = {}) { + this._options = _options; + this.absolute = this._getValue(this._options.absolute, false); + this.baseNameMatch = this._getValue(this._options.baseNameMatch, false); + this.braceExpansion = this._getValue(this._options.braceExpansion, true); + this.caseSensitiveMatch = this._getValue(this._options.caseSensitiveMatch, true); + this.concurrency = this._getValue(this._options.concurrency, CPU_COUNT); + this.cwd = this._getValue(this._options.cwd, process.cwd()); + this.deep = this._getValue(this._options.deep, Infinity); + this.dot = this._getValue(this._options.dot, false); + this.extglob = this._getValue(this._options.extglob, true); + this.followSymbolicLinks = this._getValue(this._options.followSymbolicLinks, true); + this.fs = this._getFileSystemMethods(this._options.fs); + this.globstar = this._getValue(this._options.globstar, true); + this.ignore = this._getValue(this._options.ignore, []); + this.markDirectories = this._getValue(this._options.markDirectories, false); + this.objectMode = this._getValue(this._options.objectMode, false); + this.onlyDirectories = this._getValue(this._options.onlyDirectories, false); + this.onlyFiles = this._getValue(this._options.onlyFiles, true); + this.stats = this._getValue(this._options.stats, false); + this.suppressErrors = this._getValue(this._options.suppressErrors, false); + this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, false); + this.unique = this._getValue(this._options.unique, true); + if (this.onlyDirectories) { + this.onlyFiles = false; + } + if (this.stats) { + this.objectMode = true; + } } - async.read(path, getSettings(optionsOrSettingsOrCallback), callback); -} -exports.scandir = scandir; -function scandirSync(path, optionsOrSettings) { - const settings = getSettings(optionsOrSettings); - return sync.read(path, settings); -} -exports.scandirSync = scandirSync; -function getSettings(settingsOrOptions = {}) { - if (settingsOrOptions instanceof settings_1.default) { - return settingsOrOptions; + _getValue(option, value) { + return option === undefined ? value : option; + } + _getFileSystemMethods(methods = {}) { + return Object.assign(Object.assign({}, exports.DEFAULT_FILE_SYSTEM_ADAPTER), methods); } - return new settings_1.default(settingsOrOptions); } +exports.default = Settings; /***/ }), -/* 341 */ +/* 361 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const fsStat = __webpack_require__(332); -const rpl = __webpack_require__(342); -const constants_1 = __webpack_require__(343); -const utils = __webpack_require__(344); -function read(directory, settings, callback) { - if (!settings.stats && constants_1.IS_SUPPORT_READDIR_WITH_FILE_TYPES) { - return readdirWithFileTypes(directory, settings, callback); - } - return readdir(directory, settings, callback); -} -exports.read = read; -function readdirWithFileTypes(directory, settings, callback) { - settings.fs.readdir(directory, { withFileTypes: true }, (readdirError, dirents) => { - if (readdirError !== null) { - return callFailureCallback(callback, readdirError); - } - const entries = dirents.map((dirent) => ({ - dirent, - name: dirent.name, - path: `${directory}${settings.pathSegmentSeparator}${dirent.name}` - })); - if (!settings.followSymbolicLinks) { - return callSuccessCallback(callback, entries); - } - const tasks = entries.map((entry) => makeRplTaskEntry(entry, settings)); - rpl(tasks, (rplError, rplEntries) => { - if (rplError !== null) { - return callFailureCallback(callback, rplError); - } - callSuccessCallback(callback, rplEntries); - }); - }); -} -exports.readdirWithFileTypes = readdirWithFileTypes; -function makeRplTaskEntry(entry, settings) { - return (done) => { - if (!entry.dirent.isSymbolicLink()) { - return done(null, entry); - } - settings.fs.stat(entry.path, (statError, stats) => { - if (statError !== null) { - if (settings.throwErrorOnBrokenSymbolicLink) { - return done(statError); - } - return done(null, entry); - } - entry.dirent = utils.fs.createDirentFromStats(entry.name, stats); - return done(null, entry); - }); - }; -} -function readdir(directory, settings, callback) { - settings.fs.readdir(directory, (readdirError, names) => { - if (readdirError !== null) { - return callFailureCallback(callback, readdirError); - } - const filepaths = names.map((name) => `${directory}${settings.pathSegmentSeparator}${name}`); - const tasks = filepaths.map((filepath) => { - return (done) => fsStat.stat(filepath, settings.fsStatSettings, done); - }); - rpl(tasks, (rplError, results) => { - if (rplError !== null) { - return callFailureCallback(callback, rplError); - } - const entries = []; - names.forEach((name, index) => { - const stats = results[index]; - const entry = { - name, - path: filepaths[index], - dirent: utils.fs.createDirentFromStats(name, stats) - }; - if (settings.stats) { - entry.stats = stats; - } - entries.push(entry); - }); - callSuccessCallback(callback, entries); - }); - }); -} -exports.readdir = readdir; -function callFailureCallback(callback, error) { - callback(error); -} -function callSuccessCallback(callback, result) { - callback(null, result); -} + +const path = __webpack_require__(4); +const pathType = __webpack_require__(362); + +const getExtensions = extensions => extensions.length > 1 ? `{${extensions.join(',')}}` : extensions[0]; + +const getPath = (filepath, cwd) => { + const pth = filepath[0] === '!' ? filepath.slice(1) : filepath; + return path.isAbsolute(pth) ? pth : path.join(cwd, pth); +}; + +const addExtensions = (file, extensions) => { + if (path.extname(file)) { + return `**/${file}`; + } + + return `**/${file}.${getExtensions(extensions)}`; +}; + +const getGlob = (directory, options) => { + if (options.files && !Array.isArray(options.files)) { + throw new TypeError(`Expected \`files\` to be of type \`Array\` but received type \`${typeof options.files}\``); + } + + if (options.extensions && !Array.isArray(options.extensions)) { + throw new TypeError(`Expected \`extensions\` to be of type \`Array\` but received type \`${typeof options.extensions}\``); + } + + if (options.files && options.extensions) { + return options.files.map(x => path.posix.join(directory, addExtensions(x, options.extensions))); + } + + if (options.files) { + return options.files.map(x => path.posix.join(directory, `**/${x}`)); + } + + if (options.extensions) { + return [path.posix.join(directory, `**/*.${getExtensions(options.extensions)}`)]; + } + + return [path.posix.join(directory, '**')]; +}; + +module.exports = async (input, options) => { + options = { + cwd: process.cwd(), + ...options + }; + + if (typeof options.cwd !== 'string') { + throw new TypeError(`Expected \`cwd\` to be of type \`string\` but received type \`${typeof options.cwd}\``); + } + + const globs = await Promise.all([].concat(input).map(async x => { + const isDirectory = await pathType.isDirectory(getPath(x, options.cwd)); + return isDirectory ? getGlob(x, options) : x; + })); + + return [].concat.apply([], globs); // eslint-disable-line prefer-spread +}; + +module.exports.sync = (input, options) => { + options = { + cwd: process.cwd(), + ...options + }; + + if (typeof options.cwd !== 'string') { + throw new TypeError(`Expected \`cwd\` to be of type \`string\` but received type \`${typeof options.cwd}\``); + } + + const globs = [].concat(input).map(x => pathType.isDirectorySync(getPath(x, options.cwd)) ? getGlob(x, options) : x); + + return [].concat.apply([], globs); // eslint-disable-line prefer-spread +}; + + +/***/ }), +/* 362 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +const {promisify} = __webpack_require__(111); +const fs = __webpack_require__(133); + +async function isType(fsStatType, statsMethodName, filePath) { + if (typeof filePath !== 'string') { + throw new TypeError(`Expected a string, got ${typeof filePath}`); + } + + try { + const stats = await promisify(fs[fsStatType])(filePath); + return stats[statsMethodName](); + } catch (error) { + if (error.code === 'ENOENT') { + return false; + } + + throw error; + } +} + +function isTypeSync(fsStatType, statsMethodName, filePath) { + if (typeof filePath !== 'string') { + throw new TypeError(`Expected a string, got ${typeof filePath}`); + } + + try { + return fs[fsStatType](filePath)[statsMethodName](); + } catch (error) { + if (error.code === 'ENOENT') { + return false; + } + + throw error; + } +} + +exports.isFile = isType.bind(null, 'stat', 'isFile'); +exports.isDirectory = isType.bind(null, 'stat', 'isDirectory'); +exports.isSymlink = isType.bind(null, 'lstat', 'isSymbolicLink'); +exports.isFileSync = isTypeSync.bind(null, 'statSync', 'isFile'); +exports.isDirectorySync = isTypeSync.bind(null, 'statSync', 'isDirectory'); +exports.isSymlinkSync = isTypeSync.bind(null, 'lstatSync', 'isSymbolicLink'); + + +/***/ }), +/* 363 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +const {promisify} = __webpack_require__(111); +const fs = __webpack_require__(133); +const path = __webpack_require__(4); +const fastGlob = __webpack_require__(292); +const gitIgnore = __webpack_require__(364); +const slash = __webpack_require__(365); + +const DEFAULT_IGNORE = [ + '**/node_modules/**', + '**/flow-typed/**', + '**/coverage/**', + '**/.git' +]; + +const readFileP = promisify(fs.readFile); + +const mapGitIgnorePatternTo = base => ignore => { + if (ignore.startsWith('!')) { + return '!' + path.posix.join(base, ignore.slice(1)); + } + + return path.posix.join(base, ignore); +}; + +const parseGitIgnore = (content, options) => { + const base = slash(path.relative(options.cwd, path.dirname(options.fileName))); + + return content + .split(/\r?\n/) + .filter(Boolean) + .filter(line => !line.startsWith('#')) + .map(mapGitIgnorePatternTo(base)); +}; + +const reduceIgnore = files => { + return files.reduce((ignores, file) => { + ignores.add(parseGitIgnore(file.content, { + cwd: file.cwd, + fileName: file.filePath + })); + return ignores; + }, gitIgnore()); +}; + +const ensureAbsolutePathForCwd = (cwd, p) => { + if (path.isAbsolute(p)) { + if (p.startsWith(cwd)) { + return p; + } + + throw new Error(`Path ${p} is not in cwd ${cwd}`); + } + + return path.join(cwd, p); +}; + +const getIsIgnoredPredecate = (ignores, cwd) => { + return p => ignores.ignores(slash(path.relative(cwd, ensureAbsolutePathForCwd(cwd, p)))); +}; + +const getFile = async (file, cwd) => { + const filePath = path.join(cwd, file); + const content = await readFileP(filePath, 'utf8'); + + return { + cwd, + filePath, + content + }; +}; + +const getFileSync = (file, cwd) => { + const filePath = path.join(cwd, file); + const content = fs.readFileSync(filePath, 'utf8'); + + return { + cwd, + filePath, + content + }; +}; + +const normalizeOptions = ({ + ignore = [], + cwd = slash(process.cwd()) +} = {}) => { + return {ignore, cwd}; +}; + +module.exports = async options => { + options = normalizeOptions(options); + + const paths = await fastGlob('**/.gitignore', { + ignore: DEFAULT_IGNORE.concat(options.ignore), + cwd: options.cwd + }); + + const files = await Promise.all(paths.map(file => getFile(file, options.cwd))); + const ignores = reduceIgnore(files); + + return getIsIgnoredPredecate(ignores, options.cwd); +}; + +module.exports.sync = options => { + options = normalizeOptions(options); + + const paths = fastGlob.sync('**/.gitignore', { + ignore: DEFAULT_IGNORE.concat(options.ignore), + cwd: options.cwd + }); + + const files = paths.map(file => getFileSync(file, options.cwd)); + const ignores = reduceIgnore(files); + + return getIsIgnoredPredecate(ignores, options.cwd); +}; /***/ }), -/* 342 */ +/* 364 */ /***/ (function(module, exports) { -module.exports = runParallel +// A simple implementation of make-array +function makeArray (subject) { + return Array.isArray(subject) + ? subject + : [subject] +} -function runParallel (tasks, cb) { - var results, pending, keys - var isSync = true +const EMPTY = '' +const SPACE = ' ' +const ESCAPE = '\\' +const REGEX_TEST_BLANK_LINE = /^\s+$/ +const REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION = /^\\!/ +const REGEX_REPLACE_LEADING_EXCAPED_HASH = /^\\#/ +const REGEX_SPLITALL_CRLF = /\r?\n/g +// /foo, +// ./foo, +// ../foo, +// . +// .. +const REGEX_TEST_INVALID_PATH = /^\.*\/|^\.+$/ - if (Array.isArray(tasks)) { - results = [] - pending = tasks.length - } else { - keys = Object.keys(tasks) - results = {} - pending = keys.length - } +const SLASH = '/' +const KEY_IGNORE = typeof Symbol !== 'undefined' + ? Symbol.for('node-ignore') + /* istanbul ignore next */ + : 'node-ignore' - function done (err) { - function end () { - if (cb) cb(err, results) - cb = null - } - if (isSync) process.nextTick(end) - else end() - } +const define = (object, key, value) => + Object.defineProperty(object, key, {value}) - function each (i, err, result) { - results[i] = result - if (--pending === 0 || err) { - done(err) - } - } +const REGEX_REGEXP_RANGE = /([0-z])-([0-z])/g - if (!pending) { - // empty - done(null) - } else if (keys) { - // object - keys.forEach(function (key) { - tasks[key](function (err, result) { each(key, err, result) }) - }) - } else { - // array - tasks.forEach(function (task, i) { - task(function (err, result) { each(i, err, result) }) - }) - } +// Sanitize the range of a regular expression +// The cases are complicated, see test cases for details +const sanitizeRange = range => range.replace( + REGEX_REGEXP_RANGE, + (match, from, to) => from.charCodeAt(0) <= to.charCodeAt(0) + ? match + // Invalid range (out of order) which is ok for gitignore rules but + // fatal for JavaScript regular expression, so eliminate it. + : EMPTY +) - isSync = false +// See fixtures #59 +const cleanRangeBackSlash = slashes => { + const {length} = slashes + return slashes.slice(0, length - length % 2) } +// > If the pattern ends with a slash, +// > it is removed for the purpose of the following description, +// > but it would only find a match with a directory. +// > In other words, foo/ will match a directory foo and paths underneath it, +// > but will not match a regular file or a symbolic link foo +// > (this is consistent with the way how pathspec works in general in Git). +// '`foo/`' will not match regular file '`foo`' or symbolic link '`foo`' +// -> ignore-rules will not deal with it, because it costs extra `fs.stat` call +// you could use option `mark: true` with `glob` -/***/ }), -/* 343 */ -/***/ (function(module, exports, __webpack_require__) { +// '`foo/`' should not continue with the '`..`' +const REPLACERS = [ -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const NODE_PROCESS_VERSION_PARTS = process.versions.node.split('.'); -const MAJOR_VERSION = parseInt(NODE_PROCESS_VERSION_PARTS[0], 10); -const MINOR_VERSION = parseInt(NODE_PROCESS_VERSION_PARTS[1], 10); -const SUPPORTED_MAJOR_VERSION = 10; -const SUPPORTED_MINOR_VERSION = 10; -const IS_MATCHED_BY_MAJOR = MAJOR_VERSION > SUPPORTED_MAJOR_VERSION; -const IS_MATCHED_BY_MAJOR_AND_MINOR = MAJOR_VERSION === SUPPORTED_MAJOR_VERSION && MINOR_VERSION >= SUPPORTED_MINOR_VERSION; -/** - * IS `true` for Node.js 10.10 and greater. - */ -exports.IS_SUPPORT_READDIR_WITH_FILE_TYPES = IS_MATCHED_BY_MAJOR || IS_MATCHED_BY_MAJOR_AND_MINOR; + // > Trailing spaces are ignored unless they are quoted with backslash ("\") + [ + // (a\ ) -> (a ) + // (a ) -> (a) + // (a \ ) -> (a ) + /\\?\s+$/, + match => match.indexOf('\\') === 0 + ? SPACE + : EMPTY + ], + // replace (\ ) with ' ' + [ + /\\\s/g, + () => SPACE + ], -/***/ }), -/* 344 */ -/***/ (function(module, exports, __webpack_require__) { + // Escape metacharacters + // which is written down by users but means special for regular expressions. -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const fs = __webpack_require__(345); -exports.fs = fs; + // > There are 12 characters with special meanings: + // > - the backslash \, + // > - the caret ^, + // > - the dollar sign $, + // > - the period or dot ., + // > - the vertical bar or pipe symbol |, + // > - the question mark ?, + // > - the asterisk or star *, + // > - the plus sign +, + // > - the opening parenthesis (, + // > - the closing parenthesis ), + // > - and the opening square bracket [, + // > - the opening curly brace {, + // > These special characters are often called "metacharacters". + [ + /[\\$.|*+(){^]/g, + match => `\\${match}` + ], + [ + // > a question mark (?) matches a single character + /(?!\\)\?/g, + () => '[^/]' + ], -/***/ }), -/* 345 */ -/***/ (function(module, exports, __webpack_require__) { + // leading slash + [ -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -class DirentFromStats { - constructor(name, stats) { - this.name = name; - this.isBlockDevice = stats.isBlockDevice.bind(stats); - this.isCharacterDevice = stats.isCharacterDevice.bind(stats); - this.isDirectory = stats.isDirectory.bind(stats); - this.isFIFO = stats.isFIFO.bind(stats); - this.isFile = stats.isFile.bind(stats); - this.isSocket = stats.isSocket.bind(stats); - this.isSymbolicLink = stats.isSymbolicLink.bind(stats); - } -} -function createDirentFromStats(name, stats) { - return new DirentFromStats(name, stats); -} -exports.createDirentFromStats = createDirentFromStats; + // > A leading slash matches the beginning of the pathname. + // > For example, "/*.c" matches "cat-file.c" but not "mozilla-sha1/sha1.c". + // A leading slash matches the beginning of the pathname + /^\//, + () => '^' + ], + // replace special metacharacter slash after the leading slash + [ + /\//g, + () => '\\/' + ], -/***/ }), -/* 346 */ -/***/ (function(module, exports, __webpack_require__) { + [ + // > A leading "**" followed by a slash means match in all directories. + // > For example, "**/foo" matches file or directory "foo" anywhere, + // > the same as pattern "foo". + // > "**/foo/bar" matches file or directory "bar" anywhere that is directly + // > under directory "foo". + // Notice that the '*'s have been replaced as '\\*' + /^\^*\\\*\\\*\\\//, -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const fsStat = __webpack_require__(332); -const constants_1 = __webpack_require__(343); -const utils = __webpack_require__(344); -function read(directory, settings) { - if (!settings.stats && constants_1.IS_SUPPORT_READDIR_WITH_FILE_TYPES) { - return readdirWithFileTypes(directory, settings); - } - return readdir(directory, settings); -} -exports.read = read; -function readdirWithFileTypes(directory, settings) { - const dirents = settings.fs.readdirSync(directory, { withFileTypes: true }); - return dirents.map((dirent) => { - const entry = { - dirent, - name: dirent.name, - path: `${directory}${settings.pathSegmentSeparator}${dirent.name}` - }; - if (entry.dirent.isSymbolicLink() && settings.followSymbolicLinks) { - try { - const stats = settings.fs.statSync(entry.path); - entry.dirent = utils.fs.createDirentFromStats(entry.name, stats); - } - catch (error) { - if (settings.throwErrorOnBrokenSymbolicLink) { - throw error; - } - } - } - return entry; - }); -} -exports.readdirWithFileTypes = readdirWithFileTypes; -function readdir(directory, settings) { - const names = settings.fs.readdirSync(directory); - return names.map((name) => { - const entryPath = `${directory}${settings.pathSegmentSeparator}${name}`; - const stats = fsStat.statSync(entryPath, settings.fsStatSettings); - const entry = { - name, - path: entryPath, - dirent: utils.fs.createDirentFromStats(name, stats) - }; - if (settings.stats) { - entry.stats = stats; - } - return entry; - }); -} -exports.readdir = readdir; + // '**/foo' <-> 'foo' + () => '^(?:.*\\/)?' + ], + // starting + [ + // there will be no leading '/' + // (which has been replaced by section "leading slash") + // If starts with '**', adding a '^' to the regular expression also works + /^(?=[^^])/, + function startingReplacer () { + // If has a slash `/` at the beginning or middle + return !/\/(?!$)/.test(this) + // > Prior to 2.22.1 + // > If the pattern does not contain a slash /, + // > Git treats it as a shell glob pattern + // Actually, if there is only a trailing slash, + // git also treats it as a shell glob pattern -/***/ }), -/* 347 */ -/***/ (function(module, exports, __webpack_require__) { + // After 2.22.1 (compatible but clearer) + // > If there is a separator at the beginning or middle (or both) + // > of the pattern, then the pattern is relative to the directory + // > level of the particular .gitignore file itself. + // > Otherwise the pattern may also match at any level below + // > the .gitignore level. + ? '(?:^|\\/)' -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const path = __webpack_require__(4); -const fsStat = __webpack_require__(332); -const fs = __webpack_require__(348); -class Settings { - constructor(_options = {}) { - this._options = _options; - this.followSymbolicLinks = this._getValue(this._options.followSymbolicLinks, false); - this.fs = fs.createFileSystemAdapter(this._options.fs); - this.pathSegmentSeparator = this._getValue(this._options.pathSegmentSeparator, path.sep); - this.stats = this._getValue(this._options.stats, false); - this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, true); - this.fsStatSettings = new fsStat.Settings({ - followSymbolicLink: this.followSymbolicLinks, - fs: this.fs, - throwErrorOnBrokenSymbolicLink: this.throwErrorOnBrokenSymbolicLink - }); - } - _getValue(option, value) { - return option === undefined ? value : option; - } -} -exports.default = Settings; + // > Otherwise, Git treats the pattern as a shell glob suitable for + // > consumption by fnmatch(3) + : '^' + } + ], + // two globstars + [ + // Use lookahead assertions so that we could match more than one `'/**'` + /\\\/\\\*\\\*(?=\\\/|$)/g, -/***/ }), -/* 348 */ -/***/ (function(module, exports, __webpack_require__) { + // Zero, one or several directories + // should not use '*', or it will be replaced by the next replacer -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const fs = __webpack_require__(133); -exports.FILE_SYSTEM_ADAPTER = { - lstat: fs.lstat, - stat: fs.stat, - lstatSync: fs.lstatSync, - statSync: fs.statSync, - readdir: fs.readdir, - readdirSync: fs.readdirSync -}; -function createFileSystemAdapter(fsMethods) { - if (fsMethods === undefined) { - return exports.FILE_SYSTEM_ADAPTER; - } - return Object.assign(Object.assign({}, exports.FILE_SYSTEM_ADAPTER), fsMethods); -} -exports.createFileSystemAdapter = createFileSystemAdapter; + // Check if it is not the last `'/**'` + (_, index, str) => index + 6 < str.length + // case: /**/ + // > A slash followed by two consecutive asterisks then a slash matches + // > zero or more directories. + // > For example, "a/**/b" matches "a/b", "a/x/b", "a/x/y/b" and so on. + // '/**/' + ? '(?:\\/[^\\/]+)*' -/***/ }), -/* 349 */ -/***/ (function(module, exports, __webpack_require__) { + // case: /** + // > A trailing `"/**"` matches everything inside. -"use strict"; + // #21: everything inside but it should not include the current folder + : '\\/.+' + ], + // intermediate wildcards + [ + // Never replace escaped '*' + // ignore rule '\*' will match the path '*' -var reusify = __webpack_require__(350) + // 'abc.*/' -> go + // 'abc.*' -> skip this rule + /(^|[^\\]+)\\\*(?=.+)/g, -function fastqueue (context, worker, concurrency) { - if (typeof context === 'function') { - concurrency = worker - worker = context - context = null - } + // '*.js' matches '.js' + // '*.js' doesn't match 'abc' + (_, p1) => `${p1}[^\\/]*` + ], - var cache = reusify(Task) - var queueHead = null - var queueTail = null - var _running = 0 + [ + // unescape, revert step 3 except for back slash + // For example, if a user escape a '\\*', + // after step 3, the result will be '\\\\\\*' + /\\\\\\(?=[$.|*+(){^])/g, + () => ESCAPE + ], - var self = { - push: push, - drain: noop, - saturated: noop, - pause: pause, - paused: false, - concurrency: concurrency, - running: running, - resume: resume, - idle: idle, - length: length, - unshift: unshift, - empty: noop, - kill: kill, - killAndDrain: killAndDrain + [ + // '\\\\' -> '\\' + /\\\\/g, + () => ESCAPE + ], + + [ + // > The range notation, e.g. [a-zA-Z], + // > can be used to match one of the characters in a range. + + // `\` is escaped by step 3 + /(\\)?\[([^\]/]*?)(\\*)($|\])/g, + (match, leadEscape, range, endEscape, close) => leadEscape === ESCAPE + // '\\[bar]' -> '\\\\[bar\\]' + ? `\\[${range}${cleanRangeBackSlash(endEscape)}${close}` + : close === ']' + ? endEscape.length % 2 === 0 + // A normal case, and it is a range notation + // '[bar]' + // '[bar\\\\]' + ? `[${sanitizeRange(range)}${endEscape}]` + // Invalid range notaton + // '[bar\\]' -> '[bar\\\\]' + : '[]' + : '[]' + ], + + // ending + [ + // 'js' will not match 'js.' + // 'ab' will not match 'abc' + /(?:[^*])$/, + + // WTF! + // https://git-scm.com/docs/gitignore + // changes in [2.22.1](https://git-scm.com/docs/gitignore/2.22.1) + // which re-fixes #24, #38 + + // > If there is a separator at the end of the pattern then the pattern + // > will only match directories, otherwise the pattern can match both + // > files and directories. + + // 'js*' will not match 'a.js' + // 'js/' will not match 'a.js' + // 'js' will match 'a.js' and 'a.js/' + match => /\/$/.test(match) + // foo/ will not match 'foo' + ? `${match}$` + // foo matches 'foo' and 'foo/' + : `${match}(?=$|\\/$)` + ], + + // trailing wildcard + [ + /(\^|\\\/)?\\\*$/, + (_, p1) => { + const prefix = p1 + // '\^': + // '/*' does not match EMPTY + // '/*' does not match everything + + // '\\\/': + // 'abc/*' does not match 'abc/' + ? `${p1}[^/]+` + + // 'a*' matches 'a' + // 'a*' matches 'aa' + : '[^/]*' + + return `${prefix}(?=$|\\/$)` + } + ], +] + +// A simple cache, because an ignore rule only has only one certain meaning +const regexCache = Object.create(null) + +// @param {pattern} +const makeRegex = (pattern, negative, ignorecase) => { + const r = regexCache[pattern] + if (r) { + return r } - return self + // const replacers = negative + // ? NEGATIVE_REPLACERS + // : POSITIVE_REPLACERS + + const source = REPLACERS.reduce( + (prev, current) => prev.replace(current[0], current[1].bind(pattern)), + pattern + ) + + return regexCache[pattern] = ignorecase + ? new RegExp(source, 'i') + : new RegExp(source) +} - function running () { - return _running - } +const isString = subject => typeof subject === 'string' - function pause () { - self.paused = true - } +// > A blank line matches no files, so it can serve as a separator for readability. +const checkPattern = pattern => pattern + && isString(pattern) + && !REGEX_TEST_BLANK_LINE.test(pattern) - function length () { - var current = queueHead - var counter = 0 + // > A line starting with # serves as a comment. + && pattern.indexOf('#') !== 0 - while (current) { - current = current.next - counter++ - } +const splitPattern = pattern => pattern.split(REGEX_SPLITALL_CRLF) - return counter +class IgnoreRule { + constructor ( + origin, + pattern, + negative, + regex + ) { + this.origin = origin + this.pattern = pattern + this.negative = negative + this.regex = regex } +} - function resume () { - if (!self.paused) return - self.paused = false - for (var i = 0; i < self.concurrency; i++) { - _running++ - release() - } - } +const createRule = (pattern, ignorecase) => { + const origin = pattern + let negative = false - function idle () { - return _running === 0 && self.length() === 0 + // > An optional prefix "!" which negates the pattern; + if (pattern.indexOf('!') === 0) { + negative = true + pattern = pattern.substr(1) } - function push (value, done) { - var current = cache.get() - - current.context = context - current.release = release - current.value = value - current.callback = done || noop + pattern = pattern + // > Put a backslash ("\") in front of the first "!" for patterns that + // > begin with a literal "!", for example, `"\!important!.txt"`. + .replace(REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION, '!') + // > Put a backslash ("\") in front of the first hash for patterns that + // > begin with a hash. + .replace(REGEX_REPLACE_LEADING_EXCAPED_HASH, '#') - if (_running === self.concurrency || self.paused) { - if (queueTail) { - queueTail.next = current - queueTail = current - } else { - queueHead = current - queueTail = current - self.saturated() - } - } else { - _running++ - worker.call(context, current.value, current.worked) - } - } + const regex = makeRegex(pattern, negative, ignorecase) - function unshift (value, done) { - var current = cache.get() + return new IgnoreRule( + origin, + pattern, + negative, + regex + ) +} - current.context = context - current.release = release - current.value = value - current.callback = done || noop +const throwError = (message, Ctor) => { + throw new Ctor(message) +} - if (_running === self.concurrency || self.paused) { - if (queueHead) { - current.next = queueHead - queueHead = current - } else { - queueHead = current - queueTail = current - self.saturated() - } - } else { - _running++ - worker.call(context, current.value, current.worked) - } +const checkPath = (path, originalPath, doThrow) => { + if (!isString(path)) { + return doThrow( + `path must be a string, but got \`${originalPath}\``, + TypeError + ) } - function release (holder) { - if (holder) { - cache.release(holder) - } - var next = queueHead - if (next) { - if (!self.paused) { - if (queueTail === queueHead) { - queueTail = null - } - queueHead = next.next - next.next = null - worker.call(context, next.value, next.worked) - if (queueTail === null) { - self.empty() - } - } else { - _running-- - } - } else if (--_running === 0) { - self.drain() - } + // We don't know if we should ignore EMPTY, so throw + if (!path) { + return doThrow(`path must not be empty`, TypeError) } - function kill () { - queueHead = null - queueTail = null - self.drain = noop + // Check if it is a relative path + if (checkPath.isNotRelative(path)) { + const r = '`path.relative()`d' + return doThrow( + `path should be a ${r} string, but got "${originalPath}"`, + RangeError + ) } - function killAndDrain () { - queueHead = null - queueTail = null - self.drain() - self.drain = noop - } + return true } -function noop () {} - -function Task () { - this.value = null - this.callback = noop - this.next = null - this.release = noop - this.context = null +const isNotRelative = path => REGEX_TEST_INVALID_PATH.test(path) - var self = this +checkPath.isNotRelative = isNotRelative +checkPath.convert = p => p - this.worked = function worked (err, result) { - var callback = self.callback - self.value = null - self.callback = noop - callback.call(self.context, err, result) - self.release(self) +class Ignore { + constructor ({ + ignorecase = true + } = {}) { + this._rules = [] + this._ignorecase = ignorecase + define(this, KEY_IGNORE, true) + this._initCache() } -} - -module.exports = fastqueue + _initCache () { + this._ignoreCache = Object.create(null) + this._testCache = Object.create(null) + } -/***/ }), -/* 350 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; + _addPattern (pattern) { + // #32 + if (pattern && pattern[KEY_IGNORE]) { + this._rules = this._rules.concat(pattern._rules) + this._added = true + return + } + if (checkPattern(pattern)) { + const rule = createRule(pattern, this._ignorecase) + this._added = true + this._rules.push(rule) + } + } -function reusify (Constructor) { - var head = new Constructor() - var tail = head + // @param {Array | string | Ignore} pattern + add (pattern) { + this._added = false - function get () { - var current = head + makeArray( + isString(pattern) + ? splitPattern(pattern) + : pattern + ).forEach(this._addPattern, this) - if (current.next) { - head = current.next - } else { - head = new Constructor() - tail = head + // Some rules have just added to the ignore, + // making the behavior changed. + if (this._added) { + this._initCache() } - current.next = null - - return current + return this } - function release (obj) { - tail.next = obj - tail = obj + // legacy + addPattern (pattern) { + return this.add(pattern) } - return { - get: get, - release: release - } -} + // | ignored : unignored + // negative | 0:0 | 0:1 | 1:0 | 1:1 + // -------- | ------- | ------- | ------- | -------- + // 0 | TEST | TEST | SKIP | X + // 1 | TESTIF | SKIP | TEST | X -module.exports = reusify + // - SKIP: always skip + // - TEST: always test + // - TESTIF: only test if checkUnignored + // - X: that never happen + // @param {boolean} whether should check if the path is unignored, + // setting `checkUnignored` to `false` could reduce additional + // path matching. -/***/ }), -/* 351 */ -/***/ (function(module, exports, __webpack_require__) { + // @returns {TestResult} true if a file is ignored + _testOne (path, checkUnignored) { + let ignored = false + let unignored = false -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -function isFatalError(settings, error) { - if (settings.errorFilter === null) { - return true; - } - return !settings.errorFilter(error); -} -exports.isFatalError = isFatalError; -function isAppliedFilter(filter, value) { - return filter === null || filter(value); -} -exports.isAppliedFilter = isAppliedFilter; -function replacePathSegmentSeparator(filepath, separator) { - return filepath.split(/[\\/]/).join(separator); -} -exports.replacePathSegmentSeparator = replacePathSegmentSeparator; -function joinPathSegments(a, b, separator) { - if (a === '') { - return b; - } - return a + separator + b; -} -exports.joinPathSegments = joinPathSegments; + this._rules.forEach(rule => { + const {negative} = rule + if ( + unignored === negative && ignored !== unignored + || negative && !ignored && !unignored && !checkUnignored + ) { + return + } + const matched = rule.regex.test(path) -/***/ }), -/* 352 */ -/***/ (function(module, exports, __webpack_require__) { + if (matched) { + ignored = !negative + unignored = negative + } + }) -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const common = __webpack_require__(351); -class Reader { - constructor(_root, _settings) { - this._root = _root; - this._settings = _settings; - this._root = common.replacePathSegmentSeparator(_root, _settings.pathSegmentSeparator); - } -} -exports.default = Reader; + return { + ignored, + unignored + } + } + // @returns {TestResult} + _test (originalPath, cache, checkUnignored, slices) { + const path = originalPath + // Supports nullable path + && checkPath.convert(originalPath) -/***/ }), -/* 353 */ -/***/ (function(module, exports, __webpack_require__) { + checkPath(path, originalPath, throwError) -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const stream_1 = __webpack_require__(137); -const async_1 = __webpack_require__(339); -class StreamProvider { - constructor(_root, _settings) { - this._root = _root; - this._settings = _settings; - this._reader = new async_1.default(this._root, this._settings); - this._stream = new stream_1.Readable({ - objectMode: true, - read: () => { }, - destroy: this._reader.destroy.bind(this._reader) - }); - } - read() { - this._reader.onError((error) => { - this._stream.emit('error', error); - }); - this._reader.onEntry((entry) => { - this._stream.push(entry); - }); - this._reader.onEnd(() => { - this._stream.push(null); - }); - this._reader.read(); - return this._stream; - } -} -exports.default = StreamProvider; + return this._t(path, cache, checkUnignored, slices) + } + _t (path, cache, checkUnignored, slices) { + if (path in cache) { + return cache[path] + } -/***/ }), -/* 354 */ -/***/ (function(module, exports, __webpack_require__) { + if (!slices) { + // path/to/a.js + // ['path', 'to', 'a.js'] + slices = path.split(SLASH) + } -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const sync_1 = __webpack_require__(355); -class SyncProvider { - constructor(_root, _settings) { - this._root = _root; - this._settings = _settings; - this._reader = new sync_1.default(this._root, this._settings); - } - read() { - return this._reader.read(); - } -} -exports.default = SyncProvider; + slices.pop() + // If the path has no parent directory, just test it + if (!slices.length) { + return cache[path] = this._testOne(path, checkUnignored) + } -/***/ }), -/* 355 */ -/***/ (function(module, exports, __webpack_require__) { + const parent = this._t( + slices.join(SLASH) + SLASH, + cache, + checkUnignored, + slices + ) -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const fsScandir = __webpack_require__(340); -const common = __webpack_require__(351); -const reader_1 = __webpack_require__(352); -class SyncReader extends reader_1.default { - constructor() { - super(...arguments); - this._scandir = fsScandir.scandirSync; - this._storage = new Set(); - this._queue = new Set(); - } - read() { - this._pushToQueue(this._root, this._settings.basePath); - this._handleQueue(); - return [...this._storage]; - } - _pushToQueue(directory, base) { - this._queue.add({ directory, base }); - } - _handleQueue() { - for (const item of this._queue.values()) { - this._handleDirectory(item.directory, item.base); - } - } - _handleDirectory(directory, base) { - try { - const entries = this._scandir(directory, this._settings.fsScandirSettings); - for (const entry of entries) { - this._handleEntry(entry, base); - } - } - catch (error) { - this._handleError(error); - } - } - _handleError(error) { - if (!common.isFatalError(this._settings, error)) { - return; - } - throw error; - } - _handleEntry(entry, base) { - const fullpath = entry.path; - if (base !== undefined) { - entry.path = common.joinPathSegments(base, entry.name, this._settings.pathSegmentSeparator); - } - if (common.isAppliedFilter(this._settings.entryFilter, entry)) { - this._pushToStorage(entry); - } - if (entry.dirent.isDirectory() && common.isAppliedFilter(this._settings.deepFilter, entry)) { - this._pushToQueue(fullpath, entry.path); - } - } - _pushToStorage(entry) { - this._storage.add(entry); - } -} -exports.default = SyncReader; + // If the path contains a parent directory, check the parent first + return cache[path] = parent.ignored + // > It is not possible to re-include a file if a parent directory of + // > that file is excluded. + ? parent + : this._testOne(path, checkUnignored) + } + ignores (path) { + return this._test(path, this._ignoreCache, false).ignored + } -/***/ }), -/* 356 */ -/***/ (function(module, exports, __webpack_require__) { + createFilter () { + return path => !this.ignores(path) + } -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const path = __webpack_require__(4); -const fsScandir = __webpack_require__(340); -class Settings { - constructor(_options = {}) { - this._options = _options; - this.basePath = this._getValue(this._options.basePath, undefined); - this.concurrency = this._getValue(this._options.concurrency, Infinity); - this.deepFilter = this._getValue(this._options.deepFilter, null); - this.entryFilter = this._getValue(this._options.entryFilter, null); - this.errorFilter = this._getValue(this._options.errorFilter, null); - this.pathSegmentSeparator = this._getValue(this._options.pathSegmentSeparator, path.sep); - this.fsScandirSettings = new fsScandir.Settings({ - followSymbolicLinks: this._options.followSymbolicLinks, - fs: this._options.fs, - pathSegmentSeparator: this._options.pathSegmentSeparator, - stats: this._options.stats, - throwErrorOnBrokenSymbolicLink: this._options.throwErrorOnBrokenSymbolicLink - }); - } - _getValue(option, value) { - return option === undefined ? value : option; - } -} -exports.default = Settings; + filter (paths) { + return makeArray(paths).filter(this.createFilter()) + } + + // @returns {TestResult} + test (path) { + return this._test(path, this._testCache, true) + } +} +const factory = options => new Ignore(options) -/***/ }), -/* 357 */ -/***/ (function(module, exports, __webpack_require__) { +const returnFalse = () => false -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const path = __webpack_require__(4); -const fsStat = __webpack_require__(332); -const utils = __webpack_require__(302); -class Reader { - constructor(_settings) { - this._settings = _settings; - this._fsStatSettings = new fsStat.Settings({ - followSymbolicLink: this._settings.followSymbolicLinks, - fs: this._settings.fs, - throwErrorOnBrokenSymbolicLink: this._settings.followSymbolicLinks - }); - } - _getFullEntryPath(filepath) { - return path.resolve(this._settings.cwd, filepath); - } - _makeEntry(stats, pattern) { - const entry = { - name: pattern, - path: pattern, - dirent: utils.fs.createDirentFromStats(pattern, stats) - }; - if (this._settings.stats) { - entry.stats = stats; - } - return entry; - } - _isFatalError(error) { - return !utils.errno.isEnoentCodeError(error) && !this._settings.suppressErrors; - } -} -exports.default = Reader; +const isPathValid = path => + checkPath(path && checkPath.convert(path), path, returnFalse) +factory.isPathValid = isPathValid -/***/ }), -/* 358 */ -/***/ (function(module, exports, __webpack_require__) { +// Fixes typescript +factory.default = factory -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const path = __webpack_require__(4); -const deep_1 = __webpack_require__(359); -const entry_1 = __webpack_require__(362); -const error_1 = __webpack_require__(363); -const entry_2 = __webpack_require__(364); -class Provider { - constructor(_settings) { - this._settings = _settings; - this.errorFilter = new error_1.default(this._settings); - this.entryFilter = new entry_1.default(this._settings, this._getMicromatchOptions()); - this.deepFilter = new deep_1.default(this._settings, this._getMicromatchOptions()); - this.entryTransformer = new entry_2.default(this._settings); - } - _getRootDirectory(task) { - return path.resolve(this._settings.cwd, task.base); - } - _getReaderOptions(task) { - const basePath = task.base === '.' ? '' : task.base; - return { - basePath, - pathSegmentSeparator: '/', - concurrency: this._settings.concurrency, - deepFilter: this.deepFilter.getFilter(basePath, task.positive, task.negative), - entryFilter: this.entryFilter.getFilter(task.positive, task.negative), - errorFilter: this.errorFilter.getFilter(), - followSymbolicLinks: this._settings.followSymbolicLinks, - fs: this._settings.fs, - stats: this._settings.stats, - throwErrorOnBrokenSymbolicLink: this._settings.throwErrorOnBrokenSymbolicLink, - transform: this.entryTransformer.getTransformer() - }; - } - _getMicromatchOptions() { - return { - dot: this._settings.dot, - matchBase: this._settings.baseNameMatch, - nobrace: !this._settings.braceExpansion, - nocase: !this._settings.caseSensitiveMatch, - noext: !this._settings.extglob, - noglobstar: !this._settings.globstar, - posix: true, - strictSlashes: false - }; - } -} -exports.default = Provider; +module.exports = factory +// Windows +// -------------------------------------------------------------- +/* istanbul ignore if */ +if ( + // Detect `process` so that it can run in browsers. + typeof process !== 'undefined' + && ( + process.env && process.env.IGNORE_TEST_WIN32 + || process.platform === 'win32' + ) +) { + /* eslint no-control-regex: "off" */ + const makePosix = str => /^\\\\\?\\/.test(str) + || /["<>|\u0000-\u001F]+/u.test(str) + ? str + : str.replace(/\\/g, '/') -/***/ }), -/* 359 */ -/***/ (function(module, exports, __webpack_require__) { + checkPath.convert = makePosix -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const utils = __webpack_require__(302); -const partial_1 = __webpack_require__(360); -class DeepFilter { - constructor(_settings, _micromatchOptions) { - this._settings = _settings; - this._micromatchOptions = _micromatchOptions; - } - getFilter(basePath, positive, negative) { - const matcher = this._getMatcher(positive); - const negativeRe = this._getNegativePatternsRe(negative); - return (entry) => this._filter(basePath, entry, matcher, negativeRe); - } - _getMatcher(patterns) { - return new partial_1.default(patterns, this._settings, this._micromatchOptions); - } - _getNegativePatternsRe(patterns) { - const affectDepthOfReadingPatterns = patterns.filter(utils.pattern.isAffectDepthOfReadingPattern); - return utils.pattern.convertPatternsToRe(affectDepthOfReadingPatterns, this._micromatchOptions); - } - _filter(basePath, entry, matcher, negativeRe) { - const depth = this._getEntryLevel(basePath, entry.path); - if (this._isSkippedByDeep(depth)) { - return false; - } - if (this._isSkippedSymbolicLink(entry)) { - return false; - } - const filepath = utils.path.removeLeadingDotSegment(entry.path); - if (this._isSkippedByPositivePatterns(filepath, matcher)) { - return false; - } - return this._isSkippedByNegativePatterns(filepath, negativeRe); - } - _isSkippedByDeep(entryDepth) { - return entryDepth >= this._settings.deep; - } - _isSkippedSymbolicLink(entry) { - return !this._settings.followSymbolicLinks && entry.dirent.isSymbolicLink(); - } - _getEntryLevel(basePath, entryPath) { - const basePathDepth = basePath.split('/').length; - const entryPathDepth = entryPath.split('/').length; - return entryPathDepth - (basePath === '' ? 0 : basePathDepth); - } - _isSkippedByPositivePatterns(entryPath, matcher) { - return !this._settings.baseNameMatch && !matcher.match(entryPath); - } - _isSkippedByNegativePatterns(entryPath, negativeRe) { - return !utils.pattern.matchAny(entryPath, negativeRe); - } -} -exports.default = DeepFilter; + // 'C:\\foo' <- 'C:\\foo' has been converted to 'C:/' + // 'd:\\foo' + const REGIX_IS_WINDOWS_PATH_ABSOLUTE = /^[a-z]:\//i + checkPath.isNotRelative = path => + REGIX_IS_WINDOWS_PATH_ABSOLUTE.test(path) + || isNotRelative(path) +} /***/ }), -/* 360 */ +/* 365 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const matcher_1 = __webpack_require__(361); -class PartialMatcher extends matcher_1.default { - match(filepath) { - const parts = filepath.split('/'); - const levels = parts.length; - const patterns = this._storage.filter((info) => !info.complete || info.segments.length > levels); - for (const pattern of patterns) { - const section = pattern.sections[0]; - /** - * In this case, the pattern has a globstar and we must read all directories unconditionally, - * but only if the level has reached the end of the first group. - * - * fixtures/{a,b}/** - * ^ true/false ^ always true - */ - if (!pattern.complete && levels > section.length) { - return true; - } - const match = parts.every((part, index) => { - const segment = pattern.segments[index]; - if (segment.dynamic && segment.patternRe.test(part)) { - return true; - } - if (!segment.dynamic && segment.pattern === part) { - return true; - } - return false; - }); - if (match) { - return true; - } - } - return false; - } -} -exports.default = PartialMatcher; +module.exports = path => { + const isExtendedLengthPath = /^\\\\\?\\/.test(path); + const hasNonAscii = /[^\u0000-\u0080]+/.test(path); // eslint-disable-line no-control-regex -/***/ }), -/* 361 */ -/***/ (function(module, exports, __webpack_require__) { + if (isExtendedLengthPath || hasNonAscii) { + return path; + } -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const utils = __webpack_require__(302); -class Matcher { - constructor(_patterns, _settings, _micromatchOptions) { - this._patterns = _patterns; - this._settings = _settings; - this._micromatchOptions = _micromatchOptions; - this._storage = []; - this._fillStorage(); - } - _fillStorage() { - /** - * The original pattern may include `{,*,**,a/*}`, which will lead to problems with matching (unresolved level). - * So, before expand patterns with brace expansion into separated patterns. - */ - const patterns = utils.pattern.expandPatternsWithBraceExpansion(this._patterns); - for (const pattern of patterns) { - const segments = this._getPatternSegments(pattern); - const sections = this._splitSegmentsIntoSections(segments); - this._storage.push({ - complete: sections.length <= 1, - pattern, - segments, - sections - }); - } - } - _getPatternSegments(pattern) { - const parts = utils.pattern.getPatternParts(pattern, this._micromatchOptions); - return parts.map((part) => { - const dynamic = utils.pattern.isDynamicPattern(part, this._settings); - if (!dynamic) { - return { - dynamic: false, - pattern: part - }; - } - return { - dynamic: true, - pattern: part, - patternRe: utils.pattern.makeRe(part, this._micromatchOptions) - }; - }); - } - _splitSegmentsIntoSections(segments) { - return utils.array.splitWhen(segments, (segment) => segment.dynamic && utils.pattern.hasGlobStar(segment.pattern)); - } -} -exports.default = Matcher; + return path.replace(/\\/g, '/'); +}; /***/ }), -/* 362 */ +/* 366 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const utils = __webpack_require__(302); -class EntryFilter { - constructor(_settings, _micromatchOptions) { - this._settings = _settings; - this._micromatchOptions = _micromatchOptions; - this.index = new Map(); - } - getFilter(positive, negative) { - const positiveRe = utils.pattern.convertPatternsToRe(positive, this._micromatchOptions); - const negativeRe = utils.pattern.convertPatternsToRe(negative, this._micromatchOptions); - return (entry) => this._filter(entry, positiveRe, negativeRe); - } - _filter(entry, positiveRe, negativeRe) { - if (this._settings.unique) { - if (this._isDuplicateEntry(entry)) { - return false; - } - this._createIndexRecord(entry); - } - if (this._onlyFileFilter(entry) || this._onlyDirectoryFilter(entry)) { - return false; - } - if (this._isSkippedByAbsoluteNegativePatterns(entry, negativeRe)) { - return false; - } - const filepath = this._settings.baseNameMatch ? entry.name : entry.path; - return this._isMatchToPatterns(filepath, positiveRe) && !this._isMatchToPatterns(entry.path, negativeRe); - } - _isDuplicateEntry(entry) { - return this.index.has(entry.path); - } - _createIndexRecord(entry) { - this.index.set(entry.path, undefined); - } - _onlyFileFilter(entry) { - return this._settings.onlyFiles && !entry.dirent.isFile(); - } - _onlyDirectoryFilter(entry) { - return this._settings.onlyDirectories && !entry.dirent.isDirectory(); - } - _isSkippedByAbsoluteNegativePatterns(entry, negativeRe) { - if (!this._settings.absolute) { - return false; - } - const fullpath = utils.path.makeAbsolute(this._settings.cwd, entry.path); - return this._isMatchToPatterns(fullpath, negativeRe); - } - _isMatchToPatterns(entryPath, patternsRe) { - const filepath = utils.path.removeLeadingDotSegment(entryPath); - return utils.pattern.matchAny(filepath, patternsRe); - } -} -exports.default = EntryFilter; +const {Transform} = __webpack_require__(137); -/***/ }), -/* 363 */ -/***/ (function(module, exports, __webpack_require__) { +class ObjectTransform extends Transform { + constructor() { + super({ + objectMode: true + }); + } +} -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const utils = __webpack_require__(302); -class ErrorFilter { - constructor(_settings) { - this._settings = _settings; - } - getFilter() { - return (error) => this._isNonFatalError(error); - } - _isNonFatalError(error) { - return utils.errno.isEnoentCodeError(error) || this._settings.suppressErrors; - } -} -exports.default = ErrorFilter; +class FilterStream extends ObjectTransform { + constructor(filter) { + super(); + this._filter = filter; + } + _transform(data, encoding, callback) { + if (this._filter(data)) { + this.push(data); + } -/***/ }), -/* 364 */ -/***/ (function(module, exports, __webpack_require__) { + callback(); + } +} -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const utils = __webpack_require__(302); -class EntryTransformer { - constructor(_settings) { - this._settings = _settings; - } - getTransformer() { - return (entry) => this._transform(entry); - } - _transform(entry) { - let filepath = entry.path; - if (this._settings.absolute) { - filepath = utils.path.makeAbsolute(this._settings.cwd, filepath); - filepath = utils.path.unixify(filepath); - } - if (this._settings.markDirectories && entry.dirent.isDirectory()) { - filepath += '/'; - } - if (!this._settings.objectMode) { - return filepath; - } - return Object.assign(Object.assign({}, entry), { path: filepath }); - } -} -exports.default = EntryTransformer; +class UniqueStream extends ObjectTransform { + constructor() { + super(); + this._pushed = new Set(); + } + _transform(data, encoding, callback) { + if (!this._pushed.has(data)) { + this.push(data); + this._pushed.add(data); + } -/***/ }), -/* 365 */ -/***/ (function(module, exports, __webpack_require__) { + callback(); + } +} -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const stream_1 = __webpack_require__(137); -const stream_2 = __webpack_require__(331); -const provider_1 = __webpack_require__(358); -class ProviderStream extends provider_1.default { - constructor() { - super(...arguments); - this._reader = new stream_2.default(this._settings); - } - read(task) { - const root = this._getRootDirectory(task); - const options = this._getReaderOptions(task); - const source = this.api(root, task, options); - const destination = new stream_1.Readable({ objectMode: true, read: () => { } }); - source - .once('error', (error) => destination.emit('error', error)) - .on('data', (entry) => destination.emit('data', options.transform(entry))) - .once('end', () => destination.emit('end')); - destination - .once('close', () => source.destroy()); - return destination; - } - api(root, task, options) { - if (task.dynamic) { - return this._reader.dynamic(root, options); - } - return this._reader.static(task.patterns, options); - } -} -exports.default = ProviderStream; +module.exports = { + FilterStream, + UniqueStream +}; /***/ }), -/* 366 */ +/* 367 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const sync_1 = __webpack_require__(367); -const provider_1 = __webpack_require__(358); -class ProviderSync extends provider_1.default { - constructor() { - super(...arguments); - this._reader = new sync_1.default(this._settings); - } - read(task) { - const root = this._getRootDirectory(task); - const options = this._getReaderOptions(task); - const entries = this.api(root, task, options); - return entries.map(options.transform); - } - api(root, task, options) { - if (task.dynamic) { - return this._reader.dynamic(root, options); - } - return this._reader.static(task.patterns, options); - } -} -exports.default = ProviderSync; +/*! + * is-glob + * + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. + */ + +var isExtglob = __webpack_require__(302); +var chars = { '{': '}', '(': ')', '[': ']'}; +var strictRegex = /\\(.)|(^!|\*|[\].+)]\?|\[[^\\\]]+\]|\{[^\\}]+\}|\(\?[:!=][^\\)]+\)|\([^|]+\|[^\\)]+\))/; +var relaxedRegex = /\\(.)|(^!|[*?{}()[\]]|\(\?)/; + +module.exports = function isGlob(str, options) { + if (typeof str !== 'string' || str === '') { + return false; + } + + if (isExtglob(str)) { + return true; + } + + var regex = strictRegex; + var match; + + // optionally relax regex + if (options && options.strict === false) { + regex = relaxedRegex; + } + + while ((match = regex.exec(str))) { + if (match[2]) return true; + var idx = match.index + match[0].length; + + // if an open bracket/brace/paren is escaped, + // set the index to the next closing character + var open = match[1]; + var close = open ? chars[open] : null; + if (open && close) { + var n = str.indexOf(close, idx); + if (n !== -1) { + idx = n + 1; + } + } + + str = str.slice(idx); + } + return false; +}; /***/ }), -/* 367 */ +/* 368 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const fsStat = __webpack_require__(332); -const fsWalk = __webpack_require__(337); -const reader_1 = __webpack_require__(357); -class ReaderSync extends reader_1.default { - constructor() { - super(...arguments); - this._walkSync = fsWalk.walkSync; - this._statSync = fsStat.statSync; - } - dynamic(root, options) { - return this._walkSync(root, options); - } - static(patterns, options) { - const entries = []; - for (const pattern of patterns) { - const filepath = this._getFullEntryPath(pattern); - const entry = this._getEntry(filepath, pattern, options); - if (entry === null || !options.entryFilter(entry)) { - continue; - } - entries.push(entry); - } - return entries; - } - _getEntry(filepath, pattern, options) { - try { - const stats = this._getStat(filepath); - return this._makeEntry(stats, pattern); - } - catch (error) { - if (options.errorFilter(error)) { - return null; - } - throw error; - } - } - _getStat(filepath) { - return this._statSync(filepath, this._fsStatSettings); - } -} -exports.default = ReaderSync; +const path = __webpack_require__(4); -/***/ }), -/* 368 */ -/***/ (function(module, exports, __webpack_require__) { +module.exports = path_ => { + let cwd = process.cwd(); -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const fs = __webpack_require__(133); -const os = __webpack_require__(120); -const CPU_COUNT = os.cpus().length; -exports.DEFAULT_FILE_SYSTEM_ADAPTER = { - lstat: fs.lstat, - lstatSync: fs.lstatSync, - stat: fs.stat, - statSync: fs.statSync, - readdir: fs.readdir, - readdirSync: fs.readdirSync -}; -class Settings { - constructor(_options = {}) { - this._options = _options; - this.absolute = this._getValue(this._options.absolute, false); - this.baseNameMatch = this._getValue(this._options.baseNameMatch, false); - this.braceExpansion = this._getValue(this._options.braceExpansion, true); - this.caseSensitiveMatch = this._getValue(this._options.caseSensitiveMatch, true); - this.concurrency = this._getValue(this._options.concurrency, CPU_COUNT); - this.cwd = this._getValue(this._options.cwd, process.cwd()); - this.deep = this._getValue(this._options.deep, Infinity); - this.dot = this._getValue(this._options.dot, false); - this.extglob = this._getValue(this._options.extglob, true); - this.followSymbolicLinks = this._getValue(this._options.followSymbolicLinks, true); - this.fs = this._getFileSystemMethods(this._options.fs); - this.globstar = this._getValue(this._options.globstar, true); - this.ignore = this._getValue(this._options.ignore, []); - this.markDirectories = this._getValue(this._options.markDirectories, false); - this.objectMode = this._getValue(this._options.objectMode, false); - this.onlyDirectories = this._getValue(this._options.onlyDirectories, false); - this.onlyFiles = this._getValue(this._options.onlyFiles, true); - this.stats = this._getValue(this._options.stats, false); - this.suppressErrors = this._getValue(this._options.suppressErrors, false); - this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, false); - this.unique = this._getValue(this._options.unique, true); - if (this.onlyDirectories) { - this.onlyFiles = false; - } - if (this.stats) { - this.objectMode = true; - } - } - _getValue(option, value) { - return option === undefined ? value : option; - } - _getFileSystemMethods(methods = {}) { - return Object.assign(Object.assign({}, exports.DEFAULT_FILE_SYSTEM_ADAPTER), methods); - } -} -exports.default = Settings; + path_ = path.resolve(path_); + + if (process.platform === 'win32') { + cwd = cwd.toLowerCase(); + path_ = path_.toLowerCase(); + } + + return path_ === cwd; +}; /***/ }), @@ -48016,129 +47504,391 @@ exports.default = Settings; "use strict"; const path = __webpack_require__(4); -const pathType = __webpack_require__(370); -const getExtensions = extensions => extensions.length > 1 ? `{${extensions.join(',')}}` : extensions[0]; +module.exports = (childPath, parentPath) => { + childPath = path.resolve(childPath); + parentPath = path.resolve(parentPath); -const getPath = (filepath, cwd) => { - const pth = filepath[0] === '!' ? filepath.slice(1) : filepath; - return path.isAbsolute(pth) ? pth : path.join(cwd, pth); -}; + if (process.platform === 'win32') { + childPath = childPath.toLowerCase(); + parentPath = parentPath.toLowerCase(); + } -const addExtensions = (file, extensions) => { - if (path.extname(file)) { - return `**/${file}`; + if (childPath === parentPath) { + return false; } - return `**/${file}.${getExtensions(extensions)}`; + childPath += path.sep; + parentPath += path.sep; + + return childPath.startsWith(parentPath); }; -const getGlob = (directory, options) => { - if (options.files && !Array.isArray(options.files)) { - throw new TypeError(`Expected \`files\` to be of type \`Array\` but received type \`${typeof options.files}\``); - } - if (options.extensions && !Array.isArray(options.extensions)) { - throw new TypeError(`Expected \`extensions\` to be of type \`Array\` but received type \`${typeof options.extensions}\``); - } +/***/ }), +/* 370 */ +/***/ (function(module, exports, __webpack_require__) { - if (options.files && options.extensions) { - return options.files.map(x => path.posix.join(directory, addExtensions(x, options.extensions))); - } +const assert = __webpack_require__(139) +const path = __webpack_require__(4) +const fs = __webpack_require__(133) +let glob = undefined +try { + glob = __webpack_require__(146) +} catch (_err) { + // treat glob as optional. +} - if (options.files) { - return options.files.map(x => path.posix.join(directory, `**/${x}`)); - } +const defaultGlobOpts = { + nosort: true, + silent: true +} - if (options.extensions) { - return [path.posix.join(directory, `**/*.${getExtensions(options.extensions)}`)]; - } +// for EMFILE handling +let timeout = 0 - return [path.posix.join(directory, '**')]; -}; +const isWindows = (process.platform === "win32") -module.exports = async (input, options) => { - options = { - cwd: process.cwd(), - ...options - }; +const defaults = options => { + const methods = [ + 'unlink', + 'chmod', + 'stat', + 'lstat', + 'rmdir', + 'readdir' + ] + methods.forEach(m => { + options[m] = options[m] || fs[m] + m = m + 'Sync' + options[m] = options[m] || fs[m] + }) - if (typeof options.cwd !== 'string') { - throw new TypeError(`Expected \`cwd\` to be of type \`string\` but received type \`${typeof options.cwd}\``); - } + options.maxBusyTries = options.maxBusyTries || 3 + options.emfileWait = options.emfileWait || 1000 + if (options.glob === false) { + options.disableGlob = true + } + if (options.disableGlob !== true && glob === undefined) { + throw Error('glob dependency not found, set `options.disableGlob = true` if intentional') + } + options.disableGlob = options.disableGlob || false + options.glob = options.glob || defaultGlobOpts +} - const globs = await Promise.all([].concat(input).map(async x => { - const isDirectory = await pathType.isDirectory(getPath(x, options.cwd)); - return isDirectory ? getGlob(x, options) : x; - })); +const rimraf = (p, options, cb) => { + if (typeof options === 'function') { + cb = options + options = {} + } - return [].concat.apply([], globs); // eslint-disable-line prefer-spread -}; + assert(p, 'rimraf: missing path') + assert.equal(typeof p, 'string', 'rimraf: path should be a string') + assert.equal(typeof cb, 'function', 'rimraf: callback function required') + assert(options, 'rimraf: invalid options argument provided') + assert.equal(typeof options, 'object', 'rimraf: options should be object') -module.exports.sync = (input, options) => { - options = { - cwd: process.cwd(), - ...options - }; + defaults(options) - if (typeof options.cwd !== 'string') { - throw new TypeError(`Expected \`cwd\` to be of type \`string\` but received type \`${typeof options.cwd}\``); - } + let busyTries = 0 + let errState = null + let n = 0 - const globs = [].concat(input).map(x => pathType.isDirectorySync(getPath(x, options.cwd)) ? getGlob(x, options) : x); + const next = (er) => { + errState = errState || er + if (--n === 0) + cb(errState) + } - return [].concat.apply([], globs); // eslint-disable-line prefer-spread -}; + const afterGlob = (er, results) => { + if (er) + return cb(er) + n = results.length + if (n === 0) + return cb() -/***/ }), -/* 370 */ -/***/ (function(module, exports, __webpack_require__) { + results.forEach(p => { + const CB = (er) => { + if (er) { + if ((er.code === "EBUSY" || er.code === "ENOTEMPTY" || er.code === "EPERM") && + busyTries < options.maxBusyTries) { + busyTries ++ + // try again, with the same exact callback as this one. + return setTimeout(() => rimraf_(p, options, CB), busyTries * 100) + } -"use strict"; + // this one won't happen if graceful-fs is used. + if (er.code === "EMFILE" && timeout < options.emfileWait) { + return setTimeout(() => rimraf_(p, options, CB), timeout ++) + } -const {promisify} = __webpack_require__(111); -const fs = __webpack_require__(133); + // already gone + if (er.code === "ENOENT") er = null + } -async function isType(fsStatType, statsMethodName, filePath) { - if (typeof filePath !== 'string') { - throw new TypeError(`Expected a string, got ${typeof filePath}`); - } + timeout = 0 + next(er) + } + rimraf_(p, options, CB) + }) + } - try { - const stats = await promisify(fs[fsStatType])(filePath); - return stats[statsMethodName](); - } catch (error) { - if (error.code === 'ENOENT') { - return false; - } + if (options.disableGlob || !glob.hasMagic(p)) + return afterGlob(null, [p]) - throw error; - } + options.lstat(p, (er, stat) => { + if (!er) + return afterGlob(null, [p]) + + glob(p, options.glob, afterGlob) + }) + +} + +// Two possible strategies. +// 1. Assume it's a file. unlink it, then do the dir stuff on EPERM or EISDIR +// 2. Assume it's a directory. readdir, then do the file stuff on ENOTDIR +// +// Both result in an extra syscall when you guess wrong. However, there +// are likely far more normal files in the world than directories. This +// is based on the assumption that a the average number of files per +// directory is >= 1. +// +// If anyone ever complains about this, then I guess the strategy could +// be made configurable somehow. But until then, YAGNI. +const rimraf_ = (p, options, cb) => { + assert(p) + assert(options) + assert(typeof cb === 'function') + + // sunos lets the root user unlink directories, which is... weird. + // so we have to lstat here and make sure it's not a dir. + options.lstat(p, (er, st) => { + if (er && er.code === "ENOENT") + return cb(null) + + // Windows can EPERM on stat. Life is suffering. + if (er && er.code === "EPERM" && isWindows) + fixWinEPERM(p, options, er, cb) + + if (st && st.isDirectory()) + return rmdir(p, options, er, cb) + + options.unlink(p, er => { + if (er) { + if (er.code === "ENOENT") + return cb(null) + if (er.code === "EPERM") + return (isWindows) + ? fixWinEPERM(p, options, er, cb) + : rmdir(p, options, er, cb) + if (er.code === "EISDIR") + return rmdir(p, options, er, cb) + } + return cb(er) + }) + }) +} + +const fixWinEPERM = (p, options, er, cb) => { + assert(p) + assert(options) + assert(typeof cb === 'function') + + options.chmod(p, 0o666, er2 => { + if (er2) + cb(er2.code === "ENOENT" ? null : er) + else + options.stat(p, (er3, stats) => { + if (er3) + cb(er3.code === "ENOENT" ? null : er) + else if (stats.isDirectory()) + rmdir(p, options, er, cb) + else + options.unlink(p, cb) + }) + }) +} + +const fixWinEPERMSync = (p, options, er) => { + assert(p) + assert(options) + + try { + options.chmodSync(p, 0o666) + } catch (er2) { + if (er2.code === "ENOENT") + return + else + throw er + } + + let stats + try { + stats = options.statSync(p) + } catch (er3) { + if (er3.code === "ENOENT") + return + else + throw er + } + + if (stats.isDirectory()) + rmdirSync(p, options, er) + else + options.unlinkSync(p) +} + +const rmdir = (p, options, originalEr, cb) => { + assert(p) + assert(options) + assert(typeof cb === 'function') + + // try to rmdir first, and only readdir on ENOTEMPTY or EEXIST (SunOS) + // if we guessed wrong, and it's not a directory, then + // raise the original error. + options.rmdir(p, er => { + if (er && (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM")) + rmkids(p, options, cb) + else if (er && er.code === "ENOTDIR") + cb(originalEr) + else + cb(er) + }) +} + +const rmkids = (p, options, cb) => { + assert(p) + assert(options) + assert(typeof cb === 'function') + + options.readdir(p, (er, files) => { + if (er) + return cb(er) + let n = files.length + if (n === 0) + return options.rmdir(p, cb) + let errState + files.forEach(f => { + rimraf(path.join(p, f), options, er => { + if (errState) + return + if (er) + return cb(errState = er) + if (--n === 0) + options.rmdir(p, cb) + }) + }) + }) +} + +// this looks simpler, and is strictly *faster*, but will +// tie up the JavaScript thread and fail on excessively +// deep directory trees. +const rimrafSync = (p, options) => { + options = options || {} + defaults(options) + + assert(p, 'rimraf: missing path') + assert.equal(typeof p, 'string', 'rimraf: path should be a string') + assert(options, 'rimraf: missing options') + assert.equal(typeof options, 'object', 'rimraf: options should be object') + + let results + + if (options.disableGlob || !glob.hasMagic(p)) { + results = [p] + } else { + try { + options.lstatSync(p) + results = [p] + } catch (er) { + results = glob.sync(p, options.glob) + } + } + + if (!results.length) + return + + for (let i = 0; i < results.length; i++) { + const p = results[i] + + let st + try { + st = options.lstatSync(p) + } catch (er) { + if (er.code === "ENOENT") + return + + // Windows can EPERM on stat. Life is suffering. + if (er.code === "EPERM" && isWindows) + fixWinEPERMSync(p, options, er) + } + + try { + // sunos lets the root user unlink directories, which is... weird. + if (st && st.isDirectory()) + rmdirSync(p, options, null) + else + options.unlinkSync(p) + } catch (er) { + if (er.code === "ENOENT") + return + if (er.code === "EPERM") + return isWindows ? fixWinEPERMSync(p, options, er) : rmdirSync(p, options, er) + if (er.code !== "EISDIR") + throw er + + rmdirSync(p, options, er) + } + } +} + +const rmdirSync = (p, options, originalEr) => { + assert(p) + assert(options) + + try { + options.rmdirSync(p) + } catch (er) { + if (er.code === "ENOENT") + return + if (er.code === "ENOTDIR") + throw originalEr + if (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM") + rmkidsSync(p, options) + } } -function isTypeSync(fsStatType, statsMethodName, filePath) { - if (typeof filePath !== 'string') { - throw new TypeError(`Expected a string, got ${typeof filePath}`); - } - - try { - return fs[fsStatType](filePath)[statsMethodName](); - } catch (error) { - if (error.code === 'ENOENT') { - return false; - } +const rmkidsSync = (p, options) => { + assert(p) + assert(options) + options.readdirSync(p).forEach(f => rimrafSync(path.join(p, f), options)) - throw error; - } + // We only end up here once we got ENOTEMPTY at least once, and + // at this point, we are guaranteed to have removed all the kids. + // So, we know that it won't be ENOENT or ENOTDIR or anything else. + // try really hard to delete stuff on windows, because it has a + // PROFOUNDLY annoying habit of not closing handles promptly when + // files are deleted, resulting in spurious ENOTEMPTY errors. + const retries = isWindows ? 100 : 1 + let i = 0 + do { + let threw = true + try { + const ret = options.rmdirSync(p, options) + threw = false + return ret + } finally { + if (++i < retries && threw) + continue + } + } while (true) } -exports.isFile = isType.bind(null, 'stat', 'isFile'); -exports.isDirectory = isType.bind(null, 'stat', 'isDirectory'); -exports.isSymlink = isType.bind(null, 'lstat', 'isSymbolicLink'); -exports.isFileSync = isTypeSync.bind(null, 'statSync', 'isFile'); -exports.isDirectorySync = isTypeSync.bind(null, 'statSync', 'isDirectory'); -exports.isSymlinkSync = isTypeSync.bind(null, 'lstatSync', 'isSymbolicLink'); +module.exports = rimraf +rimraf.sync = rimrafSync /***/ }), @@ -48147,2064 +47897,2169 @@ exports.isSymlinkSync = isTypeSync.bind(null, 'lstatSync', 'isSymbolicLink'); "use strict"; -const {promisify} = __webpack_require__(111); -const fs = __webpack_require__(133); -const path = __webpack_require__(4); -const fastGlob = __webpack_require__(300); -const gitIgnore = __webpack_require__(372); -const slash = __webpack_require__(373); - -const DEFAULT_IGNORE = [ - '**/node_modules/**', - '**/flow-typed/**', - '**/coverage/**', - '**/.git' -]; +const AggregateError = __webpack_require__(372); -const readFileP = promisify(fs.readFile); +module.exports = async ( + iterable, + mapper, + { + concurrency = Infinity, + stopOnError = true + } = {} +) => { + return new Promise((resolve, reject) => { + if (typeof mapper !== 'function') { + throw new TypeError('Mapper function is required'); + } -const mapGitIgnorePatternTo = base => ignore => { - if (ignore.startsWith('!')) { - return '!' + path.posix.join(base, ignore.slice(1)); - } + if (!(typeof concurrency === 'number' && concurrency >= 1)) { + throw new TypeError(`Expected \`concurrency\` to be a number from 1 and up, got \`${concurrency}\` (${typeof concurrency})`); + } - return path.posix.join(base, ignore); -}; + const ret = []; + const errors = []; + const iterator = iterable[Symbol.iterator](); + let isRejected = false; + let isIterableDone = false; + let resolvingCount = 0; + let currentIndex = 0; -const parseGitIgnore = (content, options) => { - const base = slash(path.relative(options.cwd, path.dirname(options.fileName))); + const next = () => { + if (isRejected) { + return; + } - return content - .split(/\r?\n/) - .filter(Boolean) - .filter(line => !line.startsWith('#')) - .map(mapGitIgnorePatternTo(base)); -}; + const nextItem = iterator.next(); + const i = currentIndex; + currentIndex++; -const reduceIgnore = files => { - return files.reduce((ignores, file) => { - ignores.add(parseGitIgnore(file.content, { - cwd: file.cwd, - fileName: file.filePath - })); - return ignores; - }, gitIgnore()); -}; + if (nextItem.done) { + isIterableDone = true; -const ensureAbsolutePathForCwd = (cwd, p) => { - if (path.isAbsolute(p)) { - if (p.startsWith(cwd)) { - return p; - } + if (resolvingCount === 0) { + if (!stopOnError && errors.length !== 0) { + reject(new AggregateError(errors)); + } else { + resolve(ret); + } + } - throw new Error(`Path ${p} is not in cwd ${cwd}`); - } + return; + } - return path.join(cwd, p); -}; + resolvingCount++; -const getIsIgnoredPredecate = (ignores, cwd) => { - return p => ignores.ignores(slash(path.relative(cwd, ensureAbsolutePathForCwd(cwd, p)))); -}; + (async () => { + try { + const element = await nextItem.value; + ret[i] = await mapper(element, i); + resolvingCount--; + next(); + } catch (error) { + if (stopOnError) { + isRejected = true; + reject(error); + } else { + errors.push(error); + resolvingCount--; + next(); + } + } + })(); + }; -const getFile = async (file, cwd) => { - const filePath = path.join(cwd, file); - const content = await readFileP(filePath, 'utf8'); + for (let i = 0; i < concurrency; i++) { + next(); - return { - cwd, - filePath, - content - }; + if (isIterableDone) { + break; + } + } + }); }; -const getFileSync = (file, cwd) => { - const filePath = path.join(cwd, file); - const content = fs.readFileSync(filePath, 'utf8'); - - return { - cwd, - filePath, - content - }; -}; -const normalizeOptions = ({ - ignore = [], - cwd = slash(process.cwd()) -} = {}) => { - return {ignore, cwd}; -}; +/***/ }), +/* 372 */ +/***/ (function(module, exports, __webpack_require__) { -module.exports = async options => { - options = normalizeOptions(options); +"use strict"; - const paths = await fastGlob('**/.gitignore', { - ignore: DEFAULT_IGNORE.concat(options.ignore), - cwd: options.cwd - }); +const indentString = __webpack_require__(373); +const cleanStack = __webpack_require__(374); - const files = await Promise.all(paths.map(file => getFile(file, options.cwd))); - const ignores = reduceIgnore(files); +const cleanInternalStack = stack => stack.replace(/\s+at .*aggregate-error\/index.js:\d+:\d+\)?/g, ''); - return getIsIgnoredPredecate(ignores, options.cwd); -}; +class AggregateError extends Error { + constructor(errors) { + if (!Array.isArray(errors)) { + throw new TypeError(`Expected input to be an Array, got ${typeof errors}`); + } -module.exports.sync = options => { - options = normalizeOptions(options); + errors = [...errors].map(error => { + if (error instanceof Error) { + return error; + } - const paths = fastGlob.sync('**/.gitignore', { - ignore: DEFAULT_IGNORE.concat(options.ignore), - cwd: options.cwd - }); + if (error !== null && typeof error === 'object') { + // Handle plain error objects with message property and/or possibly other metadata + return Object.assign(new Error(error.message), error); + } - const files = paths.map(file => getFileSync(file, options.cwd)); - const ignores = reduceIgnore(files); + return new Error(error); + }); - return getIsIgnoredPredecate(ignores, options.cwd); -}; + let message = errors + .map(error => { + // The `stack` property is not standardized, so we can't assume it exists + return typeof error.stack === 'string' ? cleanInternalStack(cleanStack(error.stack)) : String(error); + }) + .join('\n'); + message = '\n' + indentString(message, 4); + super(message); + this.name = 'AggregateError'; -/***/ }), -/* 372 */ -/***/ (function(module, exports) { + Object.defineProperty(this, '_errors', {value: errors}); + } -// A simple implementation of make-array -function makeArray (subject) { - return Array.isArray(subject) - ? subject - : [subject] + * [Symbol.iterator]() { + for (const error of this._errors) { + yield error; + } + } } -const EMPTY = '' -const SPACE = ' ' -const ESCAPE = '\\' -const REGEX_TEST_BLANK_LINE = /^\s+$/ -const REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION = /^\\!/ -const REGEX_REPLACE_LEADING_EXCAPED_HASH = /^\\#/ -const REGEX_SPLITALL_CRLF = /\r?\n/g -// /foo, -// ./foo, -// ../foo, -// . -// .. -const REGEX_TEST_INVALID_PATH = /^\.*\/|^\.+$/ - -const SLASH = '/' -const KEY_IGNORE = typeof Symbol !== 'undefined' - ? Symbol.for('node-ignore') - /* istanbul ignore next */ - : 'node-ignore' - -const define = (object, key, value) => - Object.defineProperty(object, key, {value}) - -const REGEX_REGEXP_RANGE = /([0-z])-([0-z])/g +module.exports = AggregateError; -// Sanitize the range of a regular expression -// The cases are complicated, see test cases for details -const sanitizeRange = range => range.replace( - REGEX_REGEXP_RANGE, - (match, from, to) => from.charCodeAt(0) <= to.charCodeAt(0) - ? match - // Invalid range (out of order) which is ok for gitignore rules but - // fatal for JavaScript regular expression, so eliminate it. - : EMPTY -) -// See fixtures #59 -const cleanRangeBackSlash = slashes => { - const {length} = slashes - return slashes.slice(0, length - length % 2) -} +/***/ }), +/* 373 */ +/***/ (function(module, exports, __webpack_require__) { -// > If the pattern ends with a slash, -// > it is removed for the purpose of the following description, -// > but it would only find a match with a directory. -// > In other words, foo/ will match a directory foo and paths underneath it, -// > but will not match a regular file or a symbolic link foo -// > (this is consistent with the way how pathspec works in general in Git). -// '`foo/`' will not match regular file '`foo`' or symbolic link '`foo`' -// -> ignore-rules will not deal with it, because it costs extra `fs.stat` call -// you could use option `mark: true` with `glob` +"use strict"; -// '`foo/`' should not continue with the '`..`' -const REPLACERS = [ - // > Trailing spaces are ignored unless they are quoted with backslash ("\") - [ - // (a\ ) -> (a ) - // (a ) -> (a) - // (a \ ) -> (a ) - /\\?\s+$/, - match => match.indexOf('\\') === 0 - ? SPACE - : EMPTY - ], +module.exports = (string, count = 1, options) => { + options = { + indent: ' ', + includeEmptyLines: false, + ...options + }; - // replace (\ ) with ' ' - [ - /\\\s/g, - () => SPACE - ], + if (typeof string !== 'string') { + throw new TypeError( + `Expected \`input\` to be a \`string\`, got \`${typeof string}\`` + ); + } - // Escape metacharacters - // which is written down by users but means special for regular expressions. + if (typeof count !== 'number') { + throw new TypeError( + `Expected \`count\` to be a \`number\`, got \`${typeof count}\`` + ); + } - // > There are 12 characters with special meanings: - // > - the backslash \, - // > - the caret ^, - // > - the dollar sign $, - // > - the period or dot ., - // > - the vertical bar or pipe symbol |, - // > - the question mark ?, - // > - the asterisk or star *, - // > - the plus sign +, - // > - the opening parenthesis (, - // > - the closing parenthesis ), - // > - and the opening square bracket [, - // > - the opening curly brace {, - // > These special characters are often called "metacharacters". - [ - /[\\$.|*+(){^]/g, - match => `\\${match}` - ], + if (typeof options.indent !== 'string') { + throw new TypeError( + `Expected \`options.indent\` to be a \`string\`, got \`${typeof options.indent}\`` + ); + } - [ - // > a question mark (?) matches a single character - /(?!\\)\?/g, - () => '[^/]' - ], + if (count === 0) { + return string; + } - // leading slash - [ + const regex = options.includeEmptyLines ? /^/gm : /^(?!\s*$)/gm; - // > A leading slash matches the beginning of the pathname. - // > For example, "/*.c" matches "cat-file.c" but not "mozilla-sha1/sha1.c". - // A leading slash matches the beginning of the pathname - /^\//, - () => '^' - ], + return string.replace(regex, options.indent.repeat(count)); +}; - // replace special metacharacter slash after the leading slash - [ - /\//g, - () => '\\/' - ], - [ - // > A leading "**" followed by a slash means match in all directories. - // > For example, "**/foo" matches file or directory "foo" anywhere, - // > the same as pattern "foo". - // > "**/foo/bar" matches file or directory "bar" anywhere that is directly - // > under directory "foo". - // Notice that the '*'s have been replaced as '\\*' - /^\^*\\\*\\\*\\\//, +/***/ }), +/* 374 */ +/***/ (function(module, exports, __webpack_require__) { - // '**/foo' <-> 'foo' - () => '^(?:.*\\/)?' - ], +"use strict"; - // starting - [ - // there will be no leading '/' - // (which has been replaced by section "leading slash") - // If starts with '**', adding a '^' to the regular expression also works - /^(?=[^^])/, - function startingReplacer () { - // If has a slash `/` at the beginning or middle - return !/\/(?!$)/.test(this) - // > Prior to 2.22.1 - // > If the pattern does not contain a slash /, - // > Git treats it as a shell glob pattern - // Actually, if there is only a trailing slash, - // git also treats it as a shell glob pattern +const os = __webpack_require__(120); - // After 2.22.1 (compatible but clearer) - // > If there is a separator at the beginning or middle (or both) - // > of the pattern, then the pattern is relative to the directory - // > level of the particular .gitignore file itself. - // > Otherwise the pattern may also match at any level below - // > the .gitignore level. - ? '(?:^|\\/)' +const extractPathRegex = /\s+at.*(?:\(|\s)(.*)\)?/; +const pathRegex = /^(?:(?:(?:node|(?:internal\/[\w/]*|.*node_modules\/(?:babel-polyfill|pirates)\/.*)?\w+)\.js:\d+:\d+)|native)/; +const homeDir = typeof os.homedir === 'undefined' ? '' : os.homedir(); - // > Otherwise, Git treats the pattern as a shell glob suitable for - // > consumption by fnmatch(3) - : '^' - } - ], +module.exports = (stack, options) => { + options = Object.assign({pretty: false}, options); - // two globstars - [ - // Use lookahead assertions so that we could match more than one `'/**'` - /\\\/\\\*\\\*(?=\\\/|$)/g, + return stack.replace(/\\/g, '/') + .split('\n') + .filter(line => { + const pathMatches = line.match(extractPathRegex); + if (pathMatches === null || !pathMatches[1]) { + return true; + } - // Zero, one or several directories - // should not use '*', or it will be replaced by the next replacer + const match = pathMatches[1]; - // Check if it is not the last `'/**'` - (_, index, str) => index + 6 < str.length + // Electron + if ( + match.includes('.app/Contents/Resources/electron.asar') || + match.includes('.app/Contents/Resources/default_app.asar') + ) { + return false; + } - // case: /**/ - // > A slash followed by two consecutive asterisks then a slash matches - // > zero or more directories. - // > For example, "a/**/b" matches "a/b", "a/x/b", "a/x/y/b" and so on. - // '/**/' - ? '(?:\\/[^\\/]+)*' + return !pathRegex.test(match); + }) + .filter(line => line.trim() !== '') + .map(line => { + if (options.pretty) { + return line.replace(extractPathRegex, (m, p1) => m.replace(p1, p1.replace(homeDir, '~'))); + } - // case: /** - // > A trailing `"/**"` matches everything inside. + return line; + }) + .join('\n'); +}; - // #21: everything inside but it should not include the current folder - : '\\/.+' - ], - // intermediate wildcards - [ - // Never replace escaped '*' - // ignore rule '\*' will match the path '*' +/***/ }), +/* 375 */ +/***/ (function(module, exports, __webpack_require__) { - // 'abc.*/' -> go - // 'abc.*' -> skip this rule - /(^|[^\\]+)\\\*(?=.+)/g, +"use strict"; - // '*.js' matches '.js' - // '*.js' doesn't match 'abc' - (_, p1) => `${p1}[^\\/]*` - ], +const chalk = __webpack_require__(376); +const cliCursor = __webpack_require__(385); +const cliSpinners = __webpack_require__(389); +const logSymbols = __webpack_require__(391); - [ - // unescape, revert step 3 except for back slash - // For example, if a user escape a '\\*', - // after step 3, the result will be '\\\\\\*' - /\\\\\\(?=[$.|*+(){^])/g, - () => ESCAPE - ], +class Ora { + constructor(options) { + if (typeof options === 'string') { + options = { + text: options + }; + } - [ - // '\\\\' -> '\\' - /\\\\/g, - () => ESCAPE - ], + this.options = Object.assign({ + text: '', + color: 'cyan', + stream: process.stderr + }, options); - [ - // > The range notation, e.g. [a-zA-Z], - // > can be used to match one of the characters in a range. + const sp = this.options.spinner; + this.spinner = typeof sp === 'object' ? sp : (process.platform === 'win32' ? cliSpinners.line : (cliSpinners[sp] || cliSpinners.dots)); // eslint-disable-line no-nested-ternary - // `\` is escaped by step 3 - /(\\)?\[([^\]/]*?)(\\*)($|\])/g, - (match, leadEscape, range, endEscape, close) => leadEscape === ESCAPE - // '\\[bar]' -> '\\\\[bar\\]' - ? `\\[${range}${cleanRangeBackSlash(endEscape)}${close}` - : close === ']' - ? endEscape.length % 2 === 0 - // A normal case, and it is a range notation - // '[bar]' - // '[bar\\\\]' - ? `[${sanitizeRange(range)}${endEscape}]` - // Invalid range notaton - // '[bar\\]' -> '[bar\\\\]' - : '[]' - : '[]' - ], + if (this.spinner.frames === undefined) { + throw new Error('Spinner must define `frames`'); + } - // ending - [ - // 'js' will not match 'js.' - // 'ab' will not match 'abc' - /(?:[^*])$/, + this.text = this.options.text; + this.color = this.options.color; + this.interval = this.options.interval || this.spinner.interval || 100; + this.stream = this.options.stream; + this.id = null; + this.frameIndex = 0; + this.enabled = typeof this.options.enabled === 'boolean' ? this.options.enabled : ((this.stream && this.stream.isTTY) && !process.env.CI); + } + frame() { + const frames = this.spinner.frames; + let frame = frames[this.frameIndex]; - // WTF! - // https://git-scm.com/docs/gitignore - // changes in [2.22.1](https://git-scm.com/docs/gitignore/2.22.1) - // which re-fixes #24, #38 + if (this.color) { + frame = chalk[this.color](frame); + } - // > If there is a separator at the end of the pattern then the pattern - // > will only match directories, otherwise the pattern can match both - // > files and directories. + this.frameIndex = ++this.frameIndex % frames.length; - // 'js*' will not match 'a.js' - // 'js/' will not match 'a.js' - // 'js' will match 'a.js' and 'a.js/' - match => /\/$/.test(match) - // foo/ will not match 'foo' - ? `${match}$` - // foo matches 'foo' and 'foo/' - : `${match}(?=$|\\/$)` - ], + return frame + ' ' + this.text; + } + clear() { + if (!this.enabled) { + return this; + } - // trailing wildcard - [ - /(\^|\\\/)?\\\*$/, - (_, p1) => { - const prefix = p1 - // '\^': - // '/*' does not match EMPTY - // '/*' does not match everything + this.stream.clearLine(); + this.stream.cursorTo(0); - // '\\\/': - // 'abc/*' does not match 'abc/' - ? `${p1}[^/]+` + return this; + } + render() { + this.clear(); + this.stream.write(this.frame()); - // 'a*' matches 'a' - // 'a*' matches 'aa' - : '[^/]*' + return this; + } + start(text) { + if (text) { + this.text = text; + } - return `${prefix}(?=$|\\/$)` - } - ], -] + if (!this.enabled || this.id) { + return this; + } -// A simple cache, because an ignore rule only has only one certain meaning -const regexCache = Object.create(null) + cliCursor.hide(this.stream); + this.render(); + this.id = setInterval(this.render.bind(this), this.interval); -// @param {pattern} -const makeRegex = (pattern, negative, ignorecase) => { - const r = regexCache[pattern] - if (r) { - return r - } + return this; + } + stop() { + if (!this.enabled) { + return this; + } - // const replacers = negative - // ? NEGATIVE_REPLACERS - // : POSITIVE_REPLACERS + clearInterval(this.id); + this.id = null; + this.frameIndex = 0; + this.clear(); + cliCursor.show(this.stream); - const source = REPLACERS.reduce( - (prev, current) => prev.replace(current[0], current[1].bind(pattern)), - pattern - ) + return this; + } + succeed(text) { + return this.stopAndPersist({symbol: logSymbols.success, text}); + } + fail(text) { + return this.stopAndPersist({symbol: logSymbols.error, text}); + } + warn(text) { + return this.stopAndPersist({symbol: logSymbols.warning, text}); + } + info(text) { + return this.stopAndPersist({symbol: logSymbols.info, text}); + } + stopAndPersist(options) { + if (!this.enabled) { + return this; + } - return regexCache[pattern] = ignorecase - ? new RegExp(source, 'i') - : new RegExp(source) -} + // Legacy argument + // TODO: Deprecate sometime in the future + if (typeof options === 'string') { + options = { + symbol: options + }; + } -const isString = subject => typeof subject === 'string' + options = options || {}; -// > A blank line matches no files, so it can serve as a separator for readability. -const checkPattern = pattern => pattern - && isString(pattern) - && !REGEX_TEST_BLANK_LINE.test(pattern) + this.stop(); + this.stream.write(`${options.symbol || ' '} ${options.text || this.text}\n`); - // > A line starting with # serves as a comment. - && pattern.indexOf('#') !== 0 + return this; + } +} -const splitPattern = pattern => pattern.split(REGEX_SPLITALL_CRLF) +module.exports = function (opts) { + return new Ora(opts); +}; -class IgnoreRule { - constructor ( - origin, - pattern, - negative, - regex - ) { - this.origin = origin - this.pattern = pattern - this.negative = negative - this.regex = regex - } -} +module.exports.promise = (action, options) => { + if (typeof action.then !== 'function') { + throw new TypeError('Parameter `action` must be a Promise'); + } -const createRule = (pattern, ignorecase) => { - const origin = pattern - let negative = false + const spinner = new Ora(options); + spinner.start(); - // > An optional prefix "!" which negates the pattern; - if (pattern.indexOf('!') === 0) { - negative = true - pattern = pattern.substr(1) - } + action.then( + () => { + spinner.succeed(); + }, + () => { + spinner.fail(); + } + ); - pattern = pattern - // > Put a backslash ("\") in front of the first "!" for patterns that - // > begin with a literal "!", for example, `"\!important!.txt"`. - .replace(REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION, '!') - // > Put a backslash ("\") in front of the first hash for patterns that - // > begin with a hash. - .replace(REGEX_REPLACE_LEADING_EXCAPED_HASH, '#') + return spinner; +}; - const regex = makeRegex(pattern, negative, ignorecase) - return new IgnoreRule( - origin, - pattern, - negative, - regex - ) -} +/***/ }), +/* 376 */ +/***/ (function(module, exports, __webpack_require__) { -const throwError = (message, Ctor) => { - throw new Ctor(message) -} +"use strict"; -const checkPath = (path, originalPath, doThrow) => { - if (!isString(path)) { - return doThrow( - `path must be a string, but got \`${originalPath}\``, - TypeError - ) - } +const escapeStringRegexp = __webpack_require__(178); +const ansiStyles = __webpack_require__(377); +const stdoutColor = __webpack_require__(382).stdout; - // We don't know if we should ignore EMPTY, so throw - if (!path) { - return doThrow(`path must not be empty`, TypeError) - } +const template = __webpack_require__(384); - // Check if it is a relative path - if (checkPath.isNotRelative(path)) { - const r = '`path.relative()`d' - return doThrow( - `path should be a ${r} string, but got "${originalPath}"`, - RangeError - ) - } +const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm'); - return true -} +// `supportsColor.level` → `ansiStyles.color[name]` mapping +const levelMapping = ['ansi', 'ansi', 'ansi256', 'ansi16m']; -const isNotRelative = path => REGEX_TEST_INVALID_PATH.test(path) +// `color-convert` models to exclude from the Chalk API due to conflicts and such +const skipModels = new Set(['gray']); -checkPath.isNotRelative = isNotRelative -checkPath.convert = p => p +const styles = Object.create(null); -class Ignore { - constructor ({ - ignorecase = true - } = {}) { - this._rules = [] - this._ignorecase = ignorecase - define(this, KEY_IGNORE, true) - this._initCache() - } +function applyOptions(obj, options) { + options = options || {}; - _initCache () { - this._ignoreCache = Object.create(null) - this._testCache = Object.create(null) - } + // Detect level if not set manually + const scLevel = stdoutColor ? stdoutColor.level : 0; + obj.level = options.level === undefined ? scLevel : options.level; + obj.enabled = 'enabled' in options ? options.enabled : obj.level > 0; +} - _addPattern (pattern) { - // #32 - if (pattern && pattern[KEY_IGNORE]) { - this._rules = this._rules.concat(pattern._rules) - this._added = true - return - } +function Chalk(options) { + // We check for this.template here since calling `chalk.constructor()` + // by itself will have a `this` of a previously constructed chalk object + if (!this || !(this instanceof Chalk) || this.template) { + const chalk = {}; + applyOptions(chalk, options); - if (checkPattern(pattern)) { - const rule = createRule(pattern, this._ignorecase) - this._added = true - this._rules.push(rule) - } - } + chalk.template = function () { + const args = [].slice.call(arguments); + return chalkTag.apply(null, [chalk.template].concat(args)); + }; - // @param {Array | string | Ignore} pattern - add (pattern) { - this._added = false + Object.setPrototypeOf(chalk, Chalk.prototype); + Object.setPrototypeOf(chalk.template, chalk); - makeArray( - isString(pattern) - ? splitPattern(pattern) - : pattern - ).forEach(this._addPattern, this) + chalk.template.constructor = Chalk; - // Some rules have just added to the ignore, - // making the behavior changed. - if (this._added) { - this._initCache() - } + return chalk.template; + } - return this - } + applyOptions(this, options); +} - // legacy - addPattern (pattern) { - return this.add(pattern) - } +// Use bright blue on Windows as the normal blue color is illegible +if (isSimpleWindowsTerm) { + ansiStyles.blue.open = '\u001B[94m'; +} - // | ignored : unignored - // negative | 0:0 | 0:1 | 1:0 | 1:1 - // -------- | ------- | ------- | ------- | -------- - // 0 | TEST | TEST | SKIP | X - // 1 | TESTIF | SKIP | TEST | X +for (const key of Object.keys(ansiStyles)) { + ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g'); - // - SKIP: always skip - // - TEST: always test - // - TESTIF: only test if checkUnignored - // - X: that never happen + styles[key] = { + get() { + const codes = ansiStyles[key]; + return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, key); + } + }; +} - // @param {boolean} whether should check if the path is unignored, - // setting `checkUnignored` to `false` could reduce additional - // path matching. +styles.visible = { + get() { + return build.call(this, this._styles || [], true, 'visible'); + } +}; - // @returns {TestResult} true if a file is ignored - _testOne (path, checkUnignored) { - let ignored = false - let unignored = false +ansiStyles.color.closeRe = new RegExp(escapeStringRegexp(ansiStyles.color.close), 'g'); +for (const model of Object.keys(ansiStyles.color.ansi)) { + if (skipModels.has(model)) { + continue; + } - this._rules.forEach(rule => { - const {negative} = rule - if ( - unignored === negative && ignored !== unignored - || negative && !ignored && !unignored && !checkUnignored - ) { - return - } + styles[model] = { + get() { + const level = this.level; + return function () { + const open = ansiStyles.color[levelMapping[level]][model].apply(null, arguments); + const codes = { + open, + close: ansiStyles.color.close, + closeRe: ansiStyles.color.closeRe + }; + return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model); + }; + } + }; +} - const matched = rule.regex.test(path) +ansiStyles.bgColor.closeRe = new RegExp(escapeStringRegexp(ansiStyles.bgColor.close), 'g'); +for (const model of Object.keys(ansiStyles.bgColor.ansi)) { + if (skipModels.has(model)) { + continue; + } - if (matched) { - ignored = !negative - unignored = negative - } - }) + const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1); + styles[bgModel] = { + get() { + const level = this.level; + return function () { + const open = ansiStyles.bgColor[levelMapping[level]][model].apply(null, arguments); + const codes = { + open, + close: ansiStyles.bgColor.close, + closeRe: ansiStyles.bgColor.closeRe + }; + return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model); + }; + } + }; +} - return { - ignored, - unignored - } - } +const proto = Object.defineProperties(() => {}, styles); - // @returns {TestResult} - _test (originalPath, cache, checkUnignored, slices) { - const path = originalPath - // Supports nullable path - && checkPath.convert(originalPath) +function build(_styles, _empty, key) { + const builder = function () { + return applyStyle.apply(builder, arguments); + }; - checkPath(path, originalPath, throwError) + builder._styles = _styles; + builder._empty = _empty; - return this._t(path, cache, checkUnignored, slices) - } + const self = this; - _t (path, cache, checkUnignored, slices) { - if (path in cache) { - return cache[path] - } + Object.defineProperty(builder, 'level', { + enumerable: true, + get() { + return self.level; + }, + set(level) { + self.level = level; + } + }); - if (!slices) { - // path/to/a.js - // ['path', 'to', 'a.js'] - slices = path.split(SLASH) - } + Object.defineProperty(builder, 'enabled', { + enumerable: true, + get() { + return self.enabled; + }, + set(enabled) { + self.enabled = enabled; + } + }); - slices.pop() + // See below for fix regarding invisible grey/dim combination on Windows + builder.hasGrey = this.hasGrey || key === 'gray' || key === 'grey'; - // If the path has no parent directory, just test it - if (!slices.length) { - return cache[path] = this._testOne(path, checkUnignored) - } + // `__proto__` is used because we must return a function, but there is + // no way to create a function with a different prototype + builder.__proto__ = proto; // eslint-disable-line no-proto - const parent = this._t( - slices.join(SLASH) + SLASH, - cache, - checkUnignored, - slices - ) + return builder; +} - // If the path contains a parent directory, check the parent first - return cache[path] = parent.ignored - // > It is not possible to re-include a file if a parent directory of - // > that file is excluded. - ? parent - : this._testOne(path, checkUnignored) - } +function applyStyle() { + // Support varags, but simply cast to string in case there's only one arg + const args = arguments; + const argsLen = args.length; + let str = String(arguments[0]); - ignores (path) { - return this._test(path, this._ignoreCache, false).ignored - } + if (argsLen === 0) { + return ''; + } + + if (argsLen > 1) { + // Don't slice `arguments`, it prevents V8 optimizations + for (let a = 1; a < argsLen; a++) { + str += ' ' + args[a]; + } + } - createFilter () { - return path => !this.ignores(path) - } + if (!this.enabled || this.level <= 0 || !str) { + return this._empty ? '' : str; + } - filter (paths) { - return makeArray(paths).filter(this.createFilter()) - } + // Turns out that on Windows dimmed gray text becomes invisible in cmd.exe, + // see https://github.com/chalk/chalk/issues/58 + // If we're on Windows and we're dealing with a gray color, temporarily make 'dim' a noop. + const originalDim = ansiStyles.dim.open; + if (isSimpleWindowsTerm && this.hasGrey) { + ansiStyles.dim.open = ''; + } - // @returns {TestResult} - test (path) { - return this._test(path, this._testCache, true) - } -} + for (const code of this._styles.slice().reverse()) { + // Replace any instances already present with a re-opening code + // otherwise only the part of the string until said closing code + // will be colored, and the rest will simply be 'plain'. + str = code.open + str.replace(code.closeRe, code.open) + code.close; -const factory = options => new Ignore(options) + // Close the styling before a linebreak and reopen + // after next line to fix a bleed issue on macOS + // https://github.com/chalk/chalk/pull/92 + str = str.replace(/\r?\n/g, `${code.close}$&${code.open}`); + } -const returnFalse = () => false + // Reset the original `dim` if we changed it to work around the Windows dimmed gray issue + ansiStyles.dim.open = originalDim; -const isPathValid = path => - checkPath(path && checkPath.convert(path), path, returnFalse) + return str; +} -factory.isPathValid = isPathValid +function chalkTag(chalk, strings) { + if (!Array.isArray(strings)) { + // If chalk() was called by itself or with a string, + // return the string itself as a string. + return [].slice.call(arguments, 1).join(' '); + } -// Fixes typescript -factory.default = factory + const args = [].slice.call(arguments, 2); + const parts = [strings.raw[0]]; -module.exports = factory + for (let i = 1; i < strings.length; i++) { + parts.push(String(args[i - 1]).replace(/[{}\\]/g, '\\$&')); + parts.push(String(strings.raw[i])); + } -// Windows -// -------------------------------------------------------------- -/* istanbul ignore if */ -if ( - // Detect `process` so that it can run in browsers. - typeof process !== 'undefined' - && ( - process.env && process.env.IGNORE_TEST_WIN32 - || process.platform === 'win32' - ) -) { - /* eslint no-control-regex: "off" */ - const makePosix = str => /^\\\\\?\\/.test(str) - || /["<>|\u0000-\u001F]+/u.test(str) - ? str - : str.replace(/\\/g, '/') + return template(chalk, parts.join('')); +} - checkPath.convert = makePosix +Object.defineProperties(Chalk.prototype, styles); - // 'C:\\foo' <- 'C:\\foo' has been converted to 'C:/' - // 'd:\\foo' - const REGIX_IS_WINDOWS_PATH_ABSOLUTE = /^[a-z]:\//i - checkPath.isNotRelative = path => - REGIX_IS_WINDOWS_PATH_ABSOLUTE.test(path) - || isNotRelative(path) -} +module.exports = Chalk(); // eslint-disable-line new-cap +module.exports.supportsColor = stdoutColor; +module.exports.default = module.exports; // For TypeScript /***/ }), -/* 373 */ +/* 377 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +/* WEBPACK VAR INJECTION */(function(module) { +const colorConvert = __webpack_require__(378); -module.exports = path => { - const isExtendedLengthPath = /^\\\\\?\\/.test(path); - const hasNonAscii = /[^\u0000-\u0080]+/.test(path); // eslint-disable-line no-control-regex - - if (isExtendedLengthPath || hasNonAscii) { - return path; - } +const wrapAnsi16 = (fn, offset) => function () { + const code = fn.apply(colorConvert, arguments); + return `\u001B[${code + offset}m`; +}; - return path.replace(/\\/g, '/'); +const wrapAnsi256 = (fn, offset) => function () { + const code = fn.apply(colorConvert, arguments); + return `\u001B[${38 + offset};5;${code}m`; }; +const wrapAnsi16m = (fn, offset) => function () { + const rgb = fn.apply(colorConvert, arguments); + return `\u001B[${38 + offset};2;${rgb[0]};${rgb[1]};${rgb[2]}m`; +}; -/***/ }), -/* 374 */ -/***/ (function(module, exports, __webpack_require__) { +function assembleStyles() { + const codes = new Map(); + const styles = { + modifier: { + reset: [0, 0], + // 21 isn't widely supported and 22 does the same thing + bold: [1, 22], + dim: [2, 22], + italic: [3, 23], + underline: [4, 24], + inverse: [7, 27], + hidden: [8, 28], + strikethrough: [9, 29] + }, + color: { + black: [30, 39], + red: [31, 39], + green: [32, 39], + yellow: [33, 39], + blue: [34, 39], + magenta: [35, 39], + cyan: [36, 39], + white: [37, 39], + gray: [90, 39], -"use strict"; + // Bright color + redBright: [91, 39], + greenBright: [92, 39], + yellowBright: [93, 39], + blueBright: [94, 39], + magentaBright: [95, 39], + cyanBright: [96, 39], + whiteBright: [97, 39] + }, + bgColor: { + bgBlack: [40, 49], + bgRed: [41, 49], + bgGreen: [42, 49], + bgYellow: [43, 49], + bgBlue: [44, 49], + bgMagenta: [45, 49], + bgCyan: [46, 49], + bgWhite: [47, 49], -const {Transform} = __webpack_require__(137); + // Bright color + bgBlackBright: [100, 49], + bgRedBright: [101, 49], + bgGreenBright: [102, 49], + bgYellowBright: [103, 49], + bgBlueBright: [104, 49], + bgMagentaBright: [105, 49], + bgCyanBright: [106, 49], + bgWhiteBright: [107, 49] + } + }; -class ObjectTransform extends Transform { - constructor() { - super({ - objectMode: true - }); - } -} + // Fix humans + styles.color.grey = styles.color.gray; -class FilterStream extends ObjectTransform { - constructor(filter) { - super(); - this._filter = filter; - } + for (const groupName of Object.keys(styles)) { + const group = styles[groupName]; - _transform(data, encoding, callback) { - if (this._filter(data)) { - this.push(data); - } + for (const styleName of Object.keys(group)) { + const style = group[styleName]; - callback(); - } -} + styles[styleName] = { + open: `\u001B[${style[0]}m`, + close: `\u001B[${style[1]}m` + }; -class UniqueStream extends ObjectTransform { - constructor() { - super(); - this._pushed = new Set(); - } + group[styleName] = styles[styleName]; - _transform(data, encoding, callback) { - if (!this._pushed.has(data)) { - this.push(data); - this._pushed.add(data); + codes.set(style[0], style[1]); } - callback(); + Object.defineProperty(styles, groupName, { + value: group, + enumerable: false + }); + + Object.defineProperty(styles, 'codes', { + value: codes, + enumerable: false + }); } -} -module.exports = { - FilterStream, - UniqueStream -}; + const ansi2ansi = n => n; + const rgb2rgb = (r, g, b) => [r, g, b]; + styles.color.close = '\u001B[39m'; + styles.bgColor.close = '\u001B[49m'; -/***/ }), -/* 375 */ -/***/ (function(module, exports, __webpack_require__) { + styles.color.ansi = { + ansi: wrapAnsi16(ansi2ansi, 0) + }; + styles.color.ansi256 = { + ansi256: wrapAnsi256(ansi2ansi, 0) + }; + styles.color.ansi16m = { + rgb: wrapAnsi16m(rgb2rgb, 0) + }; -/*! - * is-glob - * - * Copyright (c) 2014-2017, Jon Schlinkert. - * Released under the MIT License. - */ + styles.bgColor.ansi = { + ansi: wrapAnsi16(ansi2ansi, 10) + }; + styles.bgColor.ansi256 = { + ansi256: wrapAnsi256(ansi2ansi, 10) + }; + styles.bgColor.ansi16m = { + rgb: wrapAnsi16m(rgb2rgb, 10) + }; -var isExtglob = __webpack_require__(310); -var chars = { '{': '}', '(': ')', '[': ']'}; -var strictRegex = /\\(.)|(^!|\*|[\].+)]\?|\[[^\\\]]+\]|\{[^\\}]+\}|\(\?[:!=][^\\)]+\)|\([^|]+\|[^\\)]+\))/; -var relaxedRegex = /\\(.)|(^!|[*?{}()[\]]|\(\?)/; + for (let key of Object.keys(colorConvert)) { + if (typeof colorConvert[key] !== 'object') { + continue; + } -module.exports = function isGlob(str, options) { - if (typeof str !== 'string' || str === '') { - return false; - } + const suite = colorConvert[key]; - if (isExtglob(str)) { - return true; - } + if (key === 'ansi16') { + key = 'ansi'; + } - var regex = strictRegex; - var match; + if ('ansi16' in suite) { + styles.color.ansi[key] = wrapAnsi16(suite.ansi16, 0); + styles.bgColor.ansi[key] = wrapAnsi16(suite.ansi16, 10); + } - // optionally relax regex - if (options && options.strict === false) { - regex = relaxedRegex; - } + if ('ansi256' in suite) { + styles.color.ansi256[key] = wrapAnsi256(suite.ansi256, 0); + styles.bgColor.ansi256[key] = wrapAnsi256(suite.ansi256, 10); + } - while ((match = regex.exec(str))) { - if (match[2]) return true; - var idx = match.index + match[0].length; + if ('rgb' in suite) { + styles.color.ansi16m[key] = wrapAnsi16m(suite.rgb, 0); + styles.bgColor.ansi16m[key] = wrapAnsi16m(suite.rgb, 10); + } + } - // if an open bracket/brace/paren is escaped, - // set the index to the next closing character - var open = match[1]; - var close = open ? chars[open] : null; - if (open && close) { - var n = str.indexOf(close, idx); - if (n !== -1) { - idx = n + 1; - } - } + return styles; +} - str = str.slice(idx); - } - return false; -}; +// Make the export immutable +Object.defineProperty(module, 'exports', { + enumerable: true, + get: assembleStyles +}); +/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(114)(module))) /***/ }), -/* 376 */ +/* 378 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; +var conversions = __webpack_require__(379); +var route = __webpack_require__(381); -const path = __webpack_require__(4); +var convert = {}; -module.exports = path_ => { - let cwd = process.cwd(); +var models = Object.keys(conversions); - path_ = path.resolve(path_); +function wrapRaw(fn) { + var wrappedFn = function (args) { + if (args === undefined || args === null) { + return args; + } - if (process.platform === 'win32') { - cwd = cwd.toLowerCase(); - path_ = path_.toLowerCase(); + if (arguments.length > 1) { + args = Array.prototype.slice.call(arguments); + } + + return fn(args); + }; + + // preserve .conversion property if there is one + if ('conversion' in fn) { + wrappedFn.conversion = fn.conversion; } - return path_ === cwd; -}; + return wrappedFn; +} +function wrapRounded(fn) { + var wrappedFn = function (args) { + if (args === undefined || args === null) { + return args; + } -/***/ }), -/* 377 */ -/***/ (function(module, exports, __webpack_require__) { + if (arguments.length > 1) { + args = Array.prototype.slice.call(arguments); + } -"use strict"; + var result = fn(args); -const path = __webpack_require__(4); + // we're assuming the result is an array here. + // see notice in conversions.js; don't use box types + // in conversion functions. + if (typeof result === 'object') { + for (var len = result.length, i = 0; i < len; i++) { + result[i] = Math.round(result[i]); + } + } -module.exports = (childPath, parentPath) => { - childPath = path.resolve(childPath); - parentPath = path.resolve(parentPath); + return result; + }; - if (process.platform === 'win32') { - childPath = childPath.toLowerCase(); - parentPath = parentPath.toLowerCase(); + // preserve .conversion property if there is one + if ('conversion' in fn) { + wrappedFn.conversion = fn.conversion; } - if (childPath === parentPath) { - return false; - } + return wrappedFn; +} - childPath += path.sep; - parentPath += path.sep; +models.forEach(function (fromModel) { + convert[fromModel] = {}; - return childPath.startsWith(parentPath); -}; + Object.defineProperty(convert[fromModel], 'channels', {value: conversions[fromModel].channels}); + Object.defineProperty(convert[fromModel], 'labels', {value: conversions[fromModel].labels}); + + var routes = route(fromModel); + var routeModels = Object.keys(routes); + + routeModels.forEach(function (toModel) { + var fn = routes[toModel]; + + convert[fromModel][toModel] = wrapRounded(fn); + convert[fromModel][toModel].raw = wrapRaw(fn); + }); +}); + +module.exports = convert; /***/ }), -/* 378 */ +/* 379 */ /***/ (function(module, exports, __webpack_require__) { -const assert = __webpack_require__(139) -const path = __webpack_require__(4) -const fs = __webpack_require__(133) -let glob = undefined -try { - glob = __webpack_require__(146) -} catch (_err) { - // treat glob as optional. -} +/* MIT license */ +var cssKeywords = __webpack_require__(380); -const defaultGlobOpts = { - nosort: true, - silent: true +// NOTE: conversions should only return primitive values (i.e. arrays, or +// values that give correct `typeof` results). +// do not use box values types (i.e. Number(), String(), etc.) + +var reverseKeywords = {}; +for (var key in cssKeywords) { + if (cssKeywords.hasOwnProperty(key)) { + reverseKeywords[cssKeywords[key]] = key; + } } -// for EMFILE handling -let timeout = 0 +var convert = module.exports = { + rgb: {channels: 3, labels: 'rgb'}, + hsl: {channels: 3, labels: 'hsl'}, + hsv: {channels: 3, labels: 'hsv'}, + hwb: {channels: 3, labels: 'hwb'}, + cmyk: {channels: 4, labels: 'cmyk'}, + xyz: {channels: 3, labels: 'xyz'}, + lab: {channels: 3, labels: 'lab'}, + lch: {channels: 3, labels: 'lch'}, + hex: {channels: 1, labels: ['hex']}, + keyword: {channels: 1, labels: ['keyword']}, + ansi16: {channels: 1, labels: ['ansi16']}, + ansi256: {channels: 1, labels: ['ansi256']}, + hcg: {channels: 3, labels: ['h', 'c', 'g']}, + apple: {channels: 3, labels: ['r16', 'g16', 'b16']}, + gray: {channels: 1, labels: ['gray']} +}; -const isWindows = (process.platform === "win32") +// hide .channels and .labels properties +for (var model in convert) { + if (convert.hasOwnProperty(model)) { + if (!('channels' in convert[model])) { + throw new Error('missing channels property: ' + model); + } -const defaults = options => { - const methods = [ - 'unlink', - 'chmod', - 'stat', - 'lstat', - 'rmdir', - 'readdir' - ] - methods.forEach(m => { - options[m] = options[m] || fs[m] - m = m + 'Sync' - options[m] = options[m] || fs[m] - }) + if (!('labels' in convert[model])) { + throw new Error('missing channel labels property: ' + model); + } - options.maxBusyTries = options.maxBusyTries || 3 - options.emfileWait = options.emfileWait || 1000 - if (options.glob === false) { - options.disableGlob = true - } - if (options.disableGlob !== true && glob === undefined) { - throw Error('glob dependency not found, set `options.disableGlob = true` if intentional') - } - options.disableGlob = options.disableGlob || false - options.glob = options.glob || defaultGlobOpts -} + if (convert[model].labels.length !== convert[model].channels) { + throw new Error('channel and label counts mismatch: ' + model); + } -const rimraf = (p, options, cb) => { - if (typeof options === 'function') { - cb = options - options = {} - } + var channels = convert[model].channels; + var labels = convert[model].labels; + delete convert[model].channels; + delete convert[model].labels; + Object.defineProperty(convert[model], 'channels', {value: channels}); + Object.defineProperty(convert[model], 'labels', {value: labels}); + } +} - assert(p, 'rimraf: missing path') - assert.equal(typeof p, 'string', 'rimraf: path should be a string') - assert.equal(typeof cb, 'function', 'rimraf: callback function required') - assert(options, 'rimraf: invalid options argument provided') - assert.equal(typeof options, 'object', 'rimraf: options should be object') +convert.rgb.hsl = function (rgb) { + var r = rgb[0] / 255; + var g = rgb[1] / 255; + var b = rgb[2] / 255; + var min = Math.min(r, g, b); + var max = Math.max(r, g, b); + var delta = max - min; + var h; + var s; + var l; - defaults(options) + if (max === min) { + h = 0; + } else if (r === max) { + h = (g - b) / delta; + } else if (g === max) { + h = 2 + (b - r) / delta; + } else if (b === max) { + h = 4 + (r - g) / delta; + } - let busyTries = 0 - let errState = null - let n = 0 + h = Math.min(h * 60, 360); - const next = (er) => { - errState = errState || er - if (--n === 0) - cb(errState) - } + if (h < 0) { + h += 360; + } - const afterGlob = (er, results) => { - if (er) - return cb(er) + l = (min + max) / 2; - n = results.length - if (n === 0) - return cb() + if (max === min) { + s = 0; + } else if (l <= 0.5) { + s = delta / (max + min); + } else { + s = delta / (2 - max - min); + } - results.forEach(p => { - const CB = (er) => { - if (er) { - if ((er.code === "EBUSY" || er.code === "ENOTEMPTY" || er.code === "EPERM") && - busyTries < options.maxBusyTries) { - busyTries ++ - // try again, with the same exact callback as this one. - return setTimeout(() => rimraf_(p, options, CB), busyTries * 100) - } + return [h, s * 100, l * 100]; +}; - // this one won't happen if graceful-fs is used. - if (er.code === "EMFILE" && timeout < options.emfileWait) { - return setTimeout(() => rimraf_(p, options, CB), timeout ++) - } +convert.rgb.hsv = function (rgb) { + var rdif; + var gdif; + var bdif; + var h; + var s; - // already gone - if (er.code === "ENOENT") er = null - } + var r = rgb[0] / 255; + var g = rgb[1] / 255; + var b = rgb[2] / 255; + var v = Math.max(r, g, b); + var diff = v - Math.min(r, g, b); + var diffc = function (c) { + return (v - c) / 6 / diff + 1 / 2; + }; - timeout = 0 - next(er) - } - rimraf_(p, options, CB) - }) - } + if (diff === 0) { + h = s = 0; + } else { + s = diff / v; + rdif = diffc(r); + gdif = diffc(g); + bdif = diffc(b); - if (options.disableGlob || !glob.hasMagic(p)) - return afterGlob(null, [p]) + if (r === v) { + h = bdif - gdif; + } else if (g === v) { + h = (1 / 3) + rdif - bdif; + } else if (b === v) { + h = (2 / 3) + gdif - rdif; + } + if (h < 0) { + h += 1; + } else if (h > 1) { + h -= 1; + } + } - options.lstat(p, (er, stat) => { - if (!er) - return afterGlob(null, [p]) + return [ + h * 360, + s * 100, + v * 100 + ]; +}; - glob(p, options.glob, afterGlob) - }) +convert.rgb.hwb = function (rgb) { + var r = rgb[0]; + var g = rgb[1]; + var b = rgb[2]; + var h = convert.rgb.hsl(rgb)[0]; + var w = 1 / 255 * Math.min(r, Math.min(g, b)); -} + b = 1 - 1 / 255 * Math.max(r, Math.max(g, b)); -// Two possible strategies. -// 1. Assume it's a file. unlink it, then do the dir stuff on EPERM or EISDIR -// 2. Assume it's a directory. readdir, then do the file stuff on ENOTDIR -// -// Both result in an extra syscall when you guess wrong. However, there -// are likely far more normal files in the world than directories. This -// is based on the assumption that a the average number of files per -// directory is >= 1. -// -// If anyone ever complains about this, then I guess the strategy could -// be made configurable somehow. But until then, YAGNI. -const rimraf_ = (p, options, cb) => { - assert(p) - assert(options) - assert(typeof cb === 'function') + return [h, w * 100, b * 100]; +}; - // sunos lets the root user unlink directories, which is... weird. - // so we have to lstat here and make sure it's not a dir. - options.lstat(p, (er, st) => { - if (er && er.code === "ENOENT") - return cb(null) +convert.rgb.cmyk = function (rgb) { + var r = rgb[0] / 255; + var g = rgb[1] / 255; + var b = rgb[2] / 255; + var c; + var m; + var y; + var k; - // Windows can EPERM on stat. Life is suffering. - if (er && er.code === "EPERM" && isWindows) - fixWinEPERM(p, options, er, cb) + k = Math.min(1 - r, 1 - g, 1 - b); + c = (1 - r - k) / (1 - k) || 0; + m = (1 - g - k) / (1 - k) || 0; + y = (1 - b - k) / (1 - k) || 0; - if (st && st.isDirectory()) - return rmdir(p, options, er, cb) + return [c * 100, m * 100, y * 100, k * 100]; +}; - options.unlink(p, er => { - if (er) { - if (er.code === "ENOENT") - return cb(null) - if (er.code === "EPERM") - return (isWindows) - ? fixWinEPERM(p, options, er, cb) - : rmdir(p, options, er, cb) - if (er.code === "EISDIR") - return rmdir(p, options, er, cb) - } - return cb(er) - }) - }) +/** + * See https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance + * */ +function comparativeDistance(x, y) { + return ( + Math.pow(x[0] - y[0], 2) + + Math.pow(x[1] - y[1], 2) + + Math.pow(x[2] - y[2], 2) + ); } -const fixWinEPERM = (p, options, er, cb) => { - assert(p) - assert(options) - assert(typeof cb === 'function') - - options.chmod(p, 0o666, er2 => { - if (er2) - cb(er2.code === "ENOENT" ? null : er) - else - options.stat(p, (er3, stats) => { - if (er3) - cb(er3.code === "ENOENT" ? null : er) - else if (stats.isDirectory()) - rmdir(p, options, er, cb) - else - options.unlink(p, cb) - }) - }) -} +convert.rgb.keyword = function (rgb) { + var reversed = reverseKeywords[rgb]; + if (reversed) { + return reversed; + } -const fixWinEPERMSync = (p, options, er) => { - assert(p) - assert(options) + var currentClosestDistance = Infinity; + var currentClosestKeyword; - try { - options.chmodSync(p, 0o666) - } catch (er2) { - if (er2.code === "ENOENT") - return - else - throw er - } + for (var keyword in cssKeywords) { + if (cssKeywords.hasOwnProperty(keyword)) { + var value = cssKeywords[keyword]; - let stats - try { - stats = options.statSync(p) - } catch (er3) { - if (er3.code === "ENOENT") - return - else - throw er - } + // Compute comparative distance + var distance = comparativeDistance(rgb, value); - if (stats.isDirectory()) - rmdirSync(p, options, er) - else - options.unlinkSync(p) -} + // Check if its less, if so set as closest + if (distance < currentClosestDistance) { + currentClosestDistance = distance; + currentClosestKeyword = keyword; + } + } + } -const rmdir = (p, options, originalEr, cb) => { - assert(p) - assert(options) - assert(typeof cb === 'function') + return currentClosestKeyword; +}; - // try to rmdir first, and only readdir on ENOTEMPTY or EEXIST (SunOS) - // if we guessed wrong, and it's not a directory, then - // raise the original error. - options.rmdir(p, er => { - if (er && (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM")) - rmkids(p, options, cb) - else if (er && er.code === "ENOTDIR") - cb(originalEr) - else - cb(er) - }) -} +convert.keyword.rgb = function (keyword) { + return cssKeywords[keyword]; +}; -const rmkids = (p, options, cb) => { - assert(p) - assert(options) - assert(typeof cb === 'function') +convert.rgb.xyz = function (rgb) { + var r = rgb[0] / 255; + var g = rgb[1] / 255; + var b = rgb[2] / 255; - options.readdir(p, (er, files) => { - if (er) - return cb(er) - let n = files.length - if (n === 0) - return options.rmdir(p, cb) - let errState - files.forEach(f => { - rimraf(path.join(p, f), options, er => { - if (errState) - return - if (er) - return cb(errState = er) - if (--n === 0) - options.rmdir(p, cb) - }) - }) - }) -} + // assume sRGB + r = r > 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92); + g = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92); + b = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92); -// this looks simpler, and is strictly *faster*, but will -// tie up the JavaScript thread and fail on excessively -// deep directory trees. -const rimrafSync = (p, options) => { - options = options || {} - defaults(options) + var x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805); + var y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722); + var z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505); - assert(p, 'rimraf: missing path') - assert.equal(typeof p, 'string', 'rimraf: path should be a string') - assert(options, 'rimraf: missing options') - assert.equal(typeof options, 'object', 'rimraf: options should be object') + return [x * 100, y * 100, z * 100]; +}; - let results +convert.rgb.lab = function (rgb) { + var xyz = convert.rgb.xyz(rgb); + var x = xyz[0]; + var y = xyz[1]; + var z = xyz[2]; + var l; + var a; + var b; - if (options.disableGlob || !glob.hasMagic(p)) { - results = [p] - } else { - try { - options.lstatSync(p) - results = [p] - } catch (er) { - results = glob.sync(p, options.glob) - } - } + x /= 95.047; + y /= 100; + z /= 108.883; - if (!results.length) - return + x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116); + y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116); + z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116); - for (let i = 0; i < results.length; i++) { - const p = results[i] + l = (116 * y) - 16; + a = 500 * (x - y); + b = 200 * (y - z); - let st - try { - st = options.lstatSync(p) - } catch (er) { - if (er.code === "ENOENT") - return + return [l, a, b]; +}; - // Windows can EPERM on stat. Life is suffering. - if (er.code === "EPERM" && isWindows) - fixWinEPERMSync(p, options, er) - } +convert.hsl.rgb = function (hsl) { + var h = hsl[0] / 360; + var s = hsl[1] / 100; + var l = hsl[2] / 100; + var t1; + var t2; + var t3; + var rgb; + var val; - try { - // sunos lets the root user unlink directories, which is... weird. - if (st && st.isDirectory()) - rmdirSync(p, options, null) - else - options.unlinkSync(p) - } catch (er) { - if (er.code === "ENOENT") - return - if (er.code === "EPERM") - return isWindows ? fixWinEPERMSync(p, options, er) : rmdirSync(p, options, er) - if (er.code !== "EISDIR") - throw er + if (s === 0) { + val = l * 255; + return [val, val, val]; + } - rmdirSync(p, options, er) - } - } -} + if (l < 0.5) { + t2 = l * (1 + s); + } else { + t2 = l + s - l * s; + } -const rmdirSync = (p, options, originalEr) => { - assert(p) - assert(options) + t1 = 2 * l - t2; - try { - options.rmdirSync(p) - } catch (er) { - if (er.code === "ENOENT") - return - if (er.code === "ENOTDIR") - throw originalEr - if (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM") - rmkidsSync(p, options) - } -} + rgb = [0, 0, 0]; + for (var i = 0; i < 3; i++) { + t3 = h + 1 / 3 * -(i - 1); + if (t3 < 0) { + t3++; + } + if (t3 > 1) { + t3--; + } -const rmkidsSync = (p, options) => { - assert(p) - assert(options) - options.readdirSync(p).forEach(f => rimrafSync(path.join(p, f), options)) + if (6 * t3 < 1) { + val = t1 + (t2 - t1) * 6 * t3; + } else if (2 * t3 < 1) { + val = t2; + } else if (3 * t3 < 2) { + val = t1 + (t2 - t1) * (2 / 3 - t3) * 6; + } else { + val = t1; + } - // We only end up here once we got ENOTEMPTY at least once, and - // at this point, we are guaranteed to have removed all the kids. - // So, we know that it won't be ENOENT or ENOTDIR or anything else. - // try really hard to delete stuff on windows, because it has a - // PROFOUNDLY annoying habit of not closing handles promptly when - // files are deleted, resulting in spurious ENOTEMPTY errors. - const retries = isWindows ? 100 : 1 - let i = 0 - do { - let threw = true - try { - const ret = options.rmdirSync(p, options) - threw = false - return ret - } finally { - if (++i < retries && threw) - continue - } - } while (true) -} + rgb[i] = val * 255; + } -module.exports = rimraf -rimraf.sync = rimrafSync + return rgb; +}; +convert.hsl.hsv = function (hsl) { + var h = hsl[0]; + var s = hsl[1] / 100; + var l = hsl[2] / 100; + var smin = s; + var lmin = Math.max(l, 0.01); + var sv; + var v; -/***/ }), -/* 379 */ -/***/ (function(module, exports, __webpack_require__) { + l *= 2; + s *= (l <= 1) ? l : 2 - l; + smin *= lmin <= 1 ? lmin : 2 - lmin; + v = (l + s) / 2; + sv = l === 0 ? (2 * smin) / (lmin + smin) : (2 * s) / (l + s); -"use strict"; + return [h, sv * 100, v * 100]; +}; -const AggregateError = __webpack_require__(380); +convert.hsv.rgb = function (hsv) { + var h = hsv[0] / 60; + var s = hsv[1] / 100; + var v = hsv[2] / 100; + var hi = Math.floor(h) % 6; -module.exports = async ( - iterable, - mapper, - { - concurrency = Infinity, - stopOnError = true - } = {} -) => { - return new Promise((resolve, reject) => { - if (typeof mapper !== 'function') { - throw new TypeError('Mapper function is required'); - } + var f = h - Math.floor(h); + var p = 255 * v * (1 - s); + var q = 255 * v * (1 - (s * f)); + var t = 255 * v * (1 - (s * (1 - f))); + v *= 255; - if (!(typeof concurrency === 'number' && concurrency >= 1)) { - throw new TypeError(`Expected \`concurrency\` to be a number from 1 and up, got \`${concurrency}\` (${typeof concurrency})`); - } + switch (hi) { + case 0: + return [v, t, p]; + case 1: + return [q, v, p]; + case 2: + return [p, v, t]; + case 3: + return [p, q, v]; + case 4: + return [t, p, v]; + case 5: + return [v, p, q]; + } +}; - const ret = []; - const errors = []; - const iterator = iterable[Symbol.iterator](); - let isRejected = false; - let isIterableDone = false; - let resolvingCount = 0; - let currentIndex = 0; +convert.hsv.hsl = function (hsv) { + var h = hsv[0]; + var s = hsv[1] / 100; + var v = hsv[2] / 100; + var vmin = Math.max(v, 0.01); + var lmin; + var sl; + var l; - const next = () => { - if (isRejected) { - return; - } + l = (2 - s) * v; + lmin = (2 - s) * vmin; + sl = s * vmin; + sl /= (lmin <= 1) ? lmin : 2 - lmin; + sl = sl || 0; + l /= 2; - const nextItem = iterator.next(); - const i = currentIndex; - currentIndex++; + return [h, sl * 100, l * 100]; +}; - if (nextItem.done) { - isIterableDone = true; +// http://dev.w3.org/csswg/css-color/#hwb-to-rgb +convert.hwb.rgb = function (hwb) { + var h = hwb[0] / 360; + var wh = hwb[1] / 100; + var bl = hwb[2] / 100; + var ratio = wh + bl; + var i; + var v; + var f; + var n; - if (resolvingCount === 0) { - if (!stopOnError && errors.length !== 0) { - reject(new AggregateError(errors)); - } else { - resolve(ret); - } - } + // wh + bl cant be > 1 + if (ratio > 1) { + wh /= ratio; + bl /= ratio; + } - return; - } + i = Math.floor(6 * h); + v = 1 - bl; + f = 6 * h - i; - resolvingCount++; + if ((i & 0x01) !== 0) { + f = 1 - f; + } - (async () => { - try { - const element = await nextItem.value; - ret[i] = await mapper(element, i); - resolvingCount--; - next(); - } catch (error) { - if (stopOnError) { - isRejected = true; - reject(error); - } else { - errors.push(error); - resolvingCount--; - next(); - } - } - })(); - }; + n = wh + f * (v - wh); // linear interpolation - for (let i = 0; i < concurrency; i++) { - next(); + var r; + var g; + var b; + switch (i) { + default: + case 6: + case 0: r = v; g = n; b = wh; break; + case 1: r = n; g = v; b = wh; break; + case 2: r = wh; g = v; b = n; break; + case 3: r = wh; g = n; b = v; break; + case 4: r = n; g = wh; b = v; break; + case 5: r = v; g = wh; b = n; break; + } - if (isIterableDone) { - break; - } - } - }); + return [r * 255, g * 255, b * 255]; }; +convert.cmyk.rgb = function (cmyk) { + var c = cmyk[0] / 100; + var m = cmyk[1] / 100; + var y = cmyk[2] / 100; + var k = cmyk[3] / 100; + var r; + var g; + var b; -/***/ }), -/* 380 */ -/***/ (function(module, exports, __webpack_require__) { + r = 1 - Math.min(1, c * (1 - k) + k); + g = 1 - Math.min(1, m * (1 - k) + k); + b = 1 - Math.min(1, y * (1 - k) + k); -"use strict"; + return [r * 255, g * 255, b * 255]; +}; -const indentString = __webpack_require__(381); -const cleanStack = __webpack_require__(382); +convert.xyz.rgb = function (xyz) { + var x = xyz[0] / 100; + var y = xyz[1] / 100; + var z = xyz[2] / 100; + var r; + var g; + var b; -const cleanInternalStack = stack => stack.replace(/\s+at .*aggregate-error\/index.js:\d+:\d+\)?/g, ''); + r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986); + g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415); + b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570); -class AggregateError extends Error { - constructor(errors) { - if (!Array.isArray(errors)) { - throw new TypeError(`Expected input to be an Array, got ${typeof errors}`); - } + // assume sRGB + r = r > 0.0031308 + ? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055) + : r * 12.92; - errors = [...errors].map(error => { - if (error instanceof Error) { - return error; - } + g = g > 0.0031308 + ? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055) + : g * 12.92; - if (error !== null && typeof error === 'object') { - // Handle plain error objects with message property and/or possibly other metadata - return Object.assign(new Error(error.message), error); - } + b = b > 0.0031308 + ? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055) + : b * 12.92; - return new Error(error); - }); + r = Math.min(Math.max(0, r), 1); + g = Math.min(Math.max(0, g), 1); + b = Math.min(Math.max(0, b), 1); - let message = errors - .map(error => { - // The `stack` property is not standardized, so we can't assume it exists - return typeof error.stack === 'string' ? cleanInternalStack(cleanStack(error.stack)) : String(error); - }) - .join('\n'); - message = '\n' + indentString(message, 4); - super(message); + return [r * 255, g * 255, b * 255]; +}; - this.name = 'AggregateError'; +convert.xyz.lab = function (xyz) { + var x = xyz[0]; + var y = xyz[1]; + var z = xyz[2]; + var l; + var a; + var b; - Object.defineProperty(this, '_errors', {value: errors}); - } + x /= 95.047; + y /= 100; + z /= 108.883; - * [Symbol.iterator]() { - for (const error of this._errors) { - yield error; - } - } -} + x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116); + y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116); + z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116); -module.exports = AggregateError; + l = (116 * y) - 16; + a = 500 * (x - y); + b = 200 * (y - z); + return [l, a, b]; +}; -/***/ }), -/* 381 */ -/***/ (function(module, exports, __webpack_require__) { +convert.lab.xyz = function (lab) { + var l = lab[0]; + var a = lab[1]; + var b = lab[2]; + var x; + var y; + var z; -"use strict"; + y = (l + 16) / 116; + x = a / 500 + y; + z = y - b / 200; + var y2 = Math.pow(y, 3); + var x2 = Math.pow(x, 3); + var z2 = Math.pow(z, 3); + y = y2 > 0.008856 ? y2 : (y - 16 / 116) / 7.787; + x = x2 > 0.008856 ? x2 : (x - 16 / 116) / 7.787; + z = z2 > 0.008856 ? z2 : (z - 16 / 116) / 7.787; -module.exports = (string, count = 1, options) => { - options = { - indent: ' ', - includeEmptyLines: false, - ...options - }; + x *= 95.047; + y *= 100; + z *= 108.883; - if (typeof string !== 'string') { - throw new TypeError( - `Expected \`input\` to be a \`string\`, got \`${typeof string}\`` - ); - } + return [x, y, z]; +}; - if (typeof count !== 'number') { - throw new TypeError( - `Expected \`count\` to be a \`number\`, got \`${typeof count}\`` - ); - } +convert.lab.lch = function (lab) { + var l = lab[0]; + var a = lab[1]; + var b = lab[2]; + var hr; + var h; + var c; - if (typeof options.indent !== 'string') { - throw new TypeError( - `Expected \`options.indent\` to be a \`string\`, got \`${typeof options.indent}\`` - ); - } + hr = Math.atan2(b, a); + h = hr * 360 / 2 / Math.PI; - if (count === 0) { - return string; + if (h < 0) { + h += 360; } - const regex = options.includeEmptyLines ? /^/gm : /^(?!\s*$)/gm; + c = Math.sqrt(a * a + b * b); - return string.replace(regex, options.indent.repeat(count)); + return [l, c, h]; }; +convert.lch.lab = function (lch) { + var l = lch[0]; + var c = lch[1]; + var h = lch[2]; + var a; + var b; + var hr; -/***/ }), -/* 382 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; + hr = h / 360 * 2 * Math.PI; + a = c * Math.cos(hr); + b = c * Math.sin(hr); -const os = __webpack_require__(120); + return [l, a, b]; +}; -const extractPathRegex = /\s+at.*(?:\(|\s)(.*)\)?/; -const pathRegex = /^(?:(?:(?:node|(?:internal\/[\w/]*|.*node_modules\/(?:babel-polyfill|pirates)\/.*)?\w+)\.js:\d+:\d+)|native)/; -const homeDir = typeof os.homedir === 'undefined' ? '' : os.homedir(); +convert.rgb.ansi16 = function (args) { + var r = args[0]; + var g = args[1]; + var b = args[2]; + var value = 1 in arguments ? arguments[1] : convert.rgb.hsv(args)[2]; // hsv -> ansi16 optimization -module.exports = (stack, options) => { - options = Object.assign({pretty: false}, options); + value = Math.round(value / 50); - return stack.replace(/\\/g, '/') - .split('\n') - .filter(line => { - const pathMatches = line.match(extractPathRegex); - if (pathMatches === null || !pathMatches[1]) { - return true; - } + if (value === 0) { + return 30; + } - const match = pathMatches[1]; + var ansi = 30 + + ((Math.round(b / 255) << 2) + | (Math.round(g / 255) << 1) + | Math.round(r / 255)); - // Electron - if ( - match.includes('.app/Contents/Resources/electron.asar') || - match.includes('.app/Contents/Resources/default_app.asar') - ) { - return false; - } + if (value === 2) { + ansi += 60; + } - return !pathRegex.test(match); - }) - .filter(line => line.trim() !== '') - .map(line => { - if (options.pretty) { - return line.replace(extractPathRegex, (m, p1) => m.replace(p1, p1.replace(homeDir, '~'))); - } + return ansi; +}; - return line; - }) - .join('\n'); +convert.hsv.ansi16 = function (args) { + // optimization here; we already know the value and don't need to get + // it converted for us. + return convert.rgb.ansi16(convert.hsv.rgb(args), args[2]); }; +convert.rgb.ansi256 = function (args) { + var r = args[0]; + var g = args[1]; + var b = args[2]; -/***/ }), -/* 383 */ -/***/ (function(module, exports, __webpack_require__) { + // we use the extended greyscale palette here, with the exception of + // black and white. normal palette only has 4 greyscale shades. + if (r === g && g === b) { + if (r < 8) { + return 16; + } -"use strict"; + if (r > 248) { + return 231; + } -const chalk = __webpack_require__(384); -const cliCursor = __webpack_require__(387); -const cliSpinners = __webpack_require__(391); -const logSymbols = __webpack_require__(393); + return Math.round(((r - 8) / 247) * 24) + 232; + } -class Ora { - constructor(options) { - if (typeof options === 'string') { - options = { - text: options - }; - } + var ansi = 16 + + (36 * Math.round(r / 255 * 5)) + + (6 * Math.round(g / 255 * 5)) + + Math.round(b / 255 * 5); - this.options = Object.assign({ - text: '', - color: 'cyan', - stream: process.stderr - }, options); + return ansi; +}; - const sp = this.options.spinner; - this.spinner = typeof sp === 'object' ? sp : (process.platform === 'win32' ? cliSpinners.line : (cliSpinners[sp] || cliSpinners.dots)); // eslint-disable-line no-nested-ternary +convert.ansi16.rgb = function (args) { + var color = args % 10; - if (this.spinner.frames === undefined) { - throw new Error('Spinner must define `frames`'); + // handle greyscale + if (color === 0 || color === 7) { + if (args > 50) { + color += 3.5; } - this.text = this.options.text; - this.color = this.options.color; - this.interval = this.options.interval || this.spinner.interval || 100; - this.stream = this.options.stream; - this.id = null; - this.frameIndex = 0; - this.enabled = typeof this.options.enabled === 'boolean' ? this.options.enabled : ((this.stream && this.stream.isTTY) && !process.env.CI); + color = color / 10.5 * 255; + + return [color, color, color]; } - frame() { - const frames = this.spinner.frames; - let frame = frames[this.frameIndex]; - if (this.color) { - frame = chalk[this.color](frame); - } + var mult = (~~(args > 50) + 1) * 0.5; + var r = ((color & 1) * mult) * 255; + var g = (((color >> 1) & 1) * mult) * 255; + var b = (((color >> 2) & 1) * mult) * 255; - this.frameIndex = ++this.frameIndex % frames.length; + return [r, g, b]; +}; - return frame + ' ' + this.text; +convert.ansi256.rgb = function (args) { + // handle greyscale + if (args >= 232) { + var c = (args - 232) * 10 + 8; + return [c, c, c]; } - clear() { - if (!this.enabled) { - return this; - } - this.stream.clearLine(); - this.stream.cursorTo(0); + args -= 16; - return this; - } - render() { - this.clear(); - this.stream.write(this.frame()); + var rem; + var r = Math.floor(args / 36) / 5 * 255; + var g = Math.floor((rem = args % 36) / 6) / 5 * 255; + var b = (rem % 6) / 5 * 255; - return this; - } - start(text) { - if (text) { - this.text = text; - } + return [r, g, b]; +}; - if (!this.enabled || this.id) { - return this; - } +convert.rgb.hex = function (args) { + var integer = ((Math.round(args[0]) & 0xFF) << 16) + + ((Math.round(args[1]) & 0xFF) << 8) + + (Math.round(args[2]) & 0xFF); - cliCursor.hide(this.stream); - this.render(); - this.id = setInterval(this.render.bind(this), this.interval); + var string = integer.toString(16).toUpperCase(); + return '000000'.substring(string.length) + string; +}; - return this; +convert.hex.rgb = function (args) { + var match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i); + if (!match) { + return [0, 0, 0]; } - stop() { - if (!this.enabled) { - return this; - } - clearInterval(this.id); - this.id = null; - this.frameIndex = 0; - this.clear(); - cliCursor.show(this.stream); + var colorString = match[0]; - return this; - } - succeed(text) { - return this.stopAndPersist({symbol: logSymbols.success, text}); - } - fail(text) { - return this.stopAndPersist({symbol: logSymbols.error, text}); + if (match[0].length === 3) { + colorString = colorString.split('').map(function (char) { + return char + char; + }).join(''); } - warn(text) { - return this.stopAndPersist({symbol: logSymbols.warning, text}); + + var integer = parseInt(colorString, 16); + var r = (integer >> 16) & 0xFF; + var g = (integer >> 8) & 0xFF; + var b = integer & 0xFF; + + return [r, g, b]; +}; + +convert.rgb.hcg = function (rgb) { + var r = rgb[0] / 255; + var g = rgb[1] / 255; + var b = rgb[2] / 255; + var max = Math.max(Math.max(r, g), b); + var min = Math.min(Math.min(r, g), b); + var chroma = (max - min); + var grayscale; + var hue; + + if (chroma < 1) { + grayscale = min / (1 - chroma); + } else { + grayscale = 0; } - info(text) { - return this.stopAndPersist({symbol: logSymbols.info, text}); + + if (chroma <= 0) { + hue = 0; + } else + if (max === r) { + hue = ((g - b) / chroma) % 6; + } else + if (max === g) { + hue = 2 + (b - r) / chroma; + } else { + hue = 4 + (r - g) / chroma + 4; } - stopAndPersist(options) { - if (!this.enabled) { - return this; - } - // Legacy argument - // TODO: Deprecate sometime in the future - if (typeof options === 'string') { - options = { - symbol: options - }; - } + hue /= 6; + hue %= 1; + + return [hue * 360, chroma * 100, grayscale * 100]; +}; - options = options || {}; +convert.hsl.hcg = function (hsl) { + var s = hsl[1] / 100; + var l = hsl[2] / 100; + var c = 1; + var f = 0; - this.stop(); - this.stream.write(`${options.symbol || ' '} ${options.text || this.text}\n`); + if (l < 0.5) { + c = 2.0 * s * l; + } else { + c = 2.0 * s * (1.0 - l); + } - return this; + if (c < 1.0) { + f = (l - 0.5 * c) / (1.0 - c); } -} -module.exports = function (opts) { - return new Ora(opts); + return [hsl[0], c * 100, f * 100]; }; -module.exports.promise = (action, options) => { - if (typeof action.then !== 'function') { - throw new TypeError('Parameter `action` must be a Promise'); - } +convert.hsv.hcg = function (hsv) { + var s = hsv[1] / 100; + var v = hsv[2] / 100; - const spinner = new Ora(options); - spinner.start(); + var c = s * v; + var f = 0; - action.then( - () => { - spinner.succeed(); - }, - () => { - spinner.fail(); - } - ); + if (c < 1.0) { + f = (v - c) / (1 - c); + } - return spinner; + return [hsv[0], c * 100, f * 100]; }; +convert.hcg.rgb = function (hcg) { + var h = hcg[0] / 360; + var c = hcg[1] / 100; + var g = hcg[2] / 100; -/***/ }), -/* 384 */ -/***/ (function(module, exports, __webpack_require__) { + if (c === 0.0) { + return [g * 255, g * 255, g * 255]; + } -"use strict"; + var pure = [0, 0, 0]; + var hi = (h % 1) * 6; + var v = hi % 1; + var w = 1 - v; + var mg = 0; -const escapeStringRegexp = __webpack_require__(178); -const ansiStyles = __webpack_require__(385); -const stdoutColor = __webpack_require__(184).stdout; + switch (Math.floor(hi)) { + case 0: + pure[0] = 1; pure[1] = v; pure[2] = 0; break; + case 1: + pure[0] = w; pure[1] = 1; pure[2] = 0; break; + case 2: + pure[0] = 0; pure[1] = 1; pure[2] = v; break; + case 3: + pure[0] = 0; pure[1] = w; pure[2] = 1; break; + case 4: + pure[0] = v; pure[1] = 0; pure[2] = 1; break; + default: + pure[0] = 1; pure[1] = 0; pure[2] = w; + } -const template = __webpack_require__(386); + mg = (1.0 - c) * g; -const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm'); + return [ + (c * pure[0] + mg) * 255, + (c * pure[1] + mg) * 255, + (c * pure[2] + mg) * 255 + ]; +}; -// `supportsColor.level` → `ansiStyles.color[name]` mapping -const levelMapping = ['ansi', 'ansi', 'ansi256', 'ansi16m']; +convert.hcg.hsv = function (hcg) { + var c = hcg[1] / 100; + var g = hcg[2] / 100; -// `color-convert` models to exclude from the Chalk API due to conflicts and such -const skipModels = new Set(['gray']); + var v = c + g * (1.0 - c); + var f = 0; -const styles = Object.create(null); + if (v > 0.0) { + f = c / v; + } -function applyOptions(obj, options) { - options = options || {}; + return [hcg[0], f * 100, v * 100]; +}; - // Detect level if not set manually - const scLevel = stdoutColor ? stdoutColor.level : 0; - obj.level = options.level === undefined ? scLevel : options.level; - obj.enabled = 'enabled' in options ? options.enabled : obj.level > 0; -} +convert.hcg.hsl = function (hcg) { + var c = hcg[1] / 100; + var g = hcg[2] / 100; -function Chalk(options) { - // We check for this.template here since calling `chalk.constructor()` - // by itself will have a `this` of a previously constructed chalk object - if (!this || !(this instanceof Chalk) || this.template) { - const chalk = {}; - applyOptions(chalk, options); + var l = g * (1.0 - c) + 0.5 * c; + var s = 0; - chalk.template = function () { - const args = [].slice.call(arguments); - return chalkTag.apply(null, [chalk.template].concat(args)); - }; + if (l > 0.0 && l < 0.5) { + s = c / (2 * l); + } else + if (l >= 0.5 && l < 1.0) { + s = c / (2 * (1 - l)); + } - Object.setPrototypeOf(chalk, Chalk.prototype); - Object.setPrototypeOf(chalk.template, chalk); + return [hcg[0], s * 100, l * 100]; +}; - chalk.template.constructor = Chalk; +convert.hcg.hwb = function (hcg) { + var c = hcg[1] / 100; + var g = hcg[2] / 100; + var v = c + g * (1.0 - c); + return [hcg[0], (v - c) * 100, (1 - v) * 100]; +}; - return chalk.template; +convert.hwb.hcg = function (hwb) { + var w = hwb[1] / 100; + var b = hwb[2] / 100; + var v = 1 - b; + var c = v - w; + var g = 0; + + if (c < 1) { + g = (v - c) / (1 - c); } - applyOptions(this, options); -} + return [hwb[0], c * 100, g * 100]; +}; -// Use bright blue on Windows as the normal blue color is illegible -if (isSimpleWindowsTerm) { - ansiStyles.blue.open = '\u001B[94m'; -} +convert.apple.rgb = function (apple) { + return [(apple[0] / 65535) * 255, (apple[1] / 65535) * 255, (apple[2] / 65535) * 255]; +}; -for (const key of Object.keys(ansiStyles)) { - ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g'); +convert.rgb.apple = function (rgb) { + return [(rgb[0] / 255) * 65535, (rgb[1] / 255) * 65535, (rgb[2] / 255) * 65535]; +}; - styles[key] = { - get() { - const codes = ansiStyles[key]; - return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, key); - } - }; -} +convert.gray.rgb = function (args) { + return [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255]; +}; -styles.visible = { - get() { - return build.call(this, this._styles || [], true, 'visible'); - } +convert.gray.hsl = convert.gray.hsv = function (args) { + return [0, 0, args[0]]; }; -ansiStyles.color.closeRe = new RegExp(escapeStringRegexp(ansiStyles.color.close), 'g'); -for (const model of Object.keys(ansiStyles.color.ansi)) { - if (skipModels.has(model)) { - continue; - } +convert.gray.hwb = function (gray) { + return [0, 100, gray[0]]; +}; - styles[model] = { - get() { - const level = this.level; - return function () { - const open = ansiStyles.color[levelMapping[level]][model].apply(null, arguments); - const codes = { - open, - close: ansiStyles.color.close, - closeRe: ansiStyles.color.closeRe - }; - return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model); - }; - } - }; -} +convert.gray.cmyk = function (gray) { + return [0, 0, 0, gray[0]]; +}; -ansiStyles.bgColor.closeRe = new RegExp(escapeStringRegexp(ansiStyles.bgColor.close), 'g'); -for (const model of Object.keys(ansiStyles.bgColor.ansi)) { - if (skipModels.has(model)) { - continue; - } +convert.gray.lab = function (gray) { + return [gray[0], 0, 0]; +}; - const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1); - styles[bgModel] = { - get() { - const level = this.level; - return function () { - const open = ansiStyles.bgColor[levelMapping[level]][model].apply(null, arguments); - const codes = { - open, - close: ansiStyles.bgColor.close, - closeRe: ansiStyles.bgColor.closeRe - }; - return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model); - }; - } - }; -} +convert.gray.hex = function (gray) { + var val = Math.round(gray[0] / 100 * 255) & 0xFF; + var integer = (val << 16) + (val << 8) + val; -const proto = Object.defineProperties(() => {}, styles); + var string = integer.toString(16).toUpperCase(); + return '000000'.substring(string.length) + string; +}; -function build(_styles, _empty, key) { - const builder = function () { - return applyStyle.apply(builder, arguments); - }; +convert.rgb.gray = function (rgb) { + var val = (rgb[0] + rgb[1] + rgb[2]) / 3; + return [val / 255 * 100]; +}; - builder._styles = _styles; - builder._empty = _empty; - const self = this; +/***/ }), +/* 380 */ +/***/ (function(module, exports, __webpack_require__) { - Object.defineProperty(builder, 'level', { - enumerable: true, - get() { - return self.level; - }, - set(level) { - self.level = level; - } - }); +"use strict"; + + +module.exports = { + "aliceblue": [240, 248, 255], + "antiquewhite": [250, 235, 215], + "aqua": [0, 255, 255], + "aquamarine": [127, 255, 212], + "azure": [240, 255, 255], + "beige": [245, 245, 220], + "bisque": [255, 228, 196], + "black": [0, 0, 0], + "blanchedalmond": [255, 235, 205], + "blue": [0, 0, 255], + "blueviolet": [138, 43, 226], + "brown": [165, 42, 42], + "burlywood": [222, 184, 135], + "cadetblue": [95, 158, 160], + "chartreuse": [127, 255, 0], + "chocolate": [210, 105, 30], + "coral": [255, 127, 80], + "cornflowerblue": [100, 149, 237], + "cornsilk": [255, 248, 220], + "crimson": [220, 20, 60], + "cyan": [0, 255, 255], + "darkblue": [0, 0, 139], + "darkcyan": [0, 139, 139], + "darkgoldenrod": [184, 134, 11], + "darkgray": [169, 169, 169], + "darkgreen": [0, 100, 0], + "darkgrey": [169, 169, 169], + "darkkhaki": [189, 183, 107], + "darkmagenta": [139, 0, 139], + "darkolivegreen": [85, 107, 47], + "darkorange": [255, 140, 0], + "darkorchid": [153, 50, 204], + "darkred": [139, 0, 0], + "darksalmon": [233, 150, 122], + "darkseagreen": [143, 188, 143], + "darkslateblue": [72, 61, 139], + "darkslategray": [47, 79, 79], + "darkslategrey": [47, 79, 79], + "darkturquoise": [0, 206, 209], + "darkviolet": [148, 0, 211], + "deeppink": [255, 20, 147], + "deepskyblue": [0, 191, 255], + "dimgray": [105, 105, 105], + "dimgrey": [105, 105, 105], + "dodgerblue": [30, 144, 255], + "firebrick": [178, 34, 34], + "floralwhite": [255, 250, 240], + "forestgreen": [34, 139, 34], + "fuchsia": [255, 0, 255], + "gainsboro": [220, 220, 220], + "ghostwhite": [248, 248, 255], + "gold": [255, 215, 0], + "goldenrod": [218, 165, 32], + "gray": [128, 128, 128], + "green": [0, 128, 0], + "greenyellow": [173, 255, 47], + "grey": [128, 128, 128], + "honeydew": [240, 255, 240], + "hotpink": [255, 105, 180], + "indianred": [205, 92, 92], + "indigo": [75, 0, 130], + "ivory": [255, 255, 240], + "khaki": [240, 230, 140], + "lavender": [230, 230, 250], + "lavenderblush": [255, 240, 245], + "lawngreen": [124, 252, 0], + "lemonchiffon": [255, 250, 205], + "lightblue": [173, 216, 230], + "lightcoral": [240, 128, 128], + "lightcyan": [224, 255, 255], + "lightgoldenrodyellow": [250, 250, 210], + "lightgray": [211, 211, 211], + "lightgreen": [144, 238, 144], + "lightgrey": [211, 211, 211], + "lightpink": [255, 182, 193], + "lightsalmon": [255, 160, 122], + "lightseagreen": [32, 178, 170], + "lightskyblue": [135, 206, 250], + "lightslategray": [119, 136, 153], + "lightslategrey": [119, 136, 153], + "lightsteelblue": [176, 196, 222], + "lightyellow": [255, 255, 224], + "lime": [0, 255, 0], + "limegreen": [50, 205, 50], + "linen": [250, 240, 230], + "magenta": [255, 0, 255], + "maroon": [128, 0, 0], + "mediumaquamarine": [102, 205, 170], + "mediumblue": [0, 0, 205], + "mediumorchid": [186, 85, 211], + "mediumpurple": [147, 112, 219], + "mediumseagreen": [60, 179, 113], + "mediumslateblue": [123, 104, 238], + "mediumspringgreen": [0, 250, 154], + "mediumturquoise": [72, 209, 204], + "mediumvioletred": [199, 21, 133], + "midnightblue": [25, 25, 112], + "mintcream": [245, 255, 250], + "mistyrose": [255, 228, 225], + "moccasin": [255, 228, 181], + "navajowhite": [255, 222, 173], + "navy": [0, 0, 128], + "oldlace": [253, 245, 230], + "olive": [128, 128, 0], + "olivedrab": [107, 142, 35], + "orange": [255, 165, 0], + "orangered": [255, 69, 0], + "orchid": [218, 112, 214], + "palegoldenrod": [238, 232, 170], + "palegreen": [152, 251, 152], + "paleturquoise": [175, 238, 238], + "palevioletred": [219, 112, 147], + "papayawhip": [255, 239, 213], + "peachpuff": [255, 218, 185], + "peru": [205, 133, 63], + "pink": [255, 192, 203], + "plum": [221, 160, 221], + "powderblue": [176, 224, 230], + "purple": [128, 0, 128], + "rebeccapurple": [102, 51, 153], + "red": [255, 0, 0], + "rosybrown": [188, 143, 143], + "royalblue": [65, 105, 225], + "saddlebrown": [139, 69, 19], + "salmon": [250, 128, 114], + "sandybrown": [244, 164, 96], + "seagreen": [46, 139, 87], + "seashell": [255, 245, 238], + "sienna": [160, 82, 45], + "silver": [192, 192, 192], + "skyblue": [135, 206, 235], + "slateblue": [106, 90, 205], + "slategray": [112, 128, 144], + "slategrey": [112, 128, 144], + "snow": [255, 250, 250], + "springgreen": [0, 255, 127], + "steelblue": [70, 130, 180], + "tan": [210, 180, 140], + "teal": [0, 128, 128], + "thistle": [216, 191, 216], + "tomato": [255, 99, 71], + "turquoise": [64, 224, 208], + "violet": [238, 130, 238], + "wheat": [245, 222, 179], + "white": [255, 255, 255], + "whitesmoke": [245, 245, 245], + "yellow": [255, 255, 0], + "yellowgreen": [154, 205, 50] +}; - Object.defineProperty(builder, 'enabled', { - enumerable: true, - get() { - return self.enabled; - }, - set(enabled) { - self.enabled = enabled; - } - }); - // See below for fix regarding invisible grey/dim combination on Windows - builder.hasGrey = this.hasGrey || key === 'gray' || key === 'grey'; +/***/ }), +/* 381 */ +/***/ (function(module, exports, __webpack_require__) { - // `__proto__` is used because we must return a function, but there is - // no way to create a function with a different prototype - builder.__proto__ = proto; // eslint-disable-line no-proto +var conversions = __webpack_require__(379); - return builder; -} +/* + this function routes a model to all other models. -function applyStyle() { - // Support varags, but simply cast to string in case there's only one arg - const args = arguments; - const argsLen = args.length; - let str = String(arguments[0]); + all functions that are routed have a property `.conversion` attached + to the returned synthetic function. This property is an array + of strings, each with the steps in between the 'from' and 'to' + color models (inclusive). - if (argsLen === 0) { - return ''; - } + conversions that are not possible simply are not included. +*/ - if (argsLen > 1) { - // Don't slice `arguments`, it prevents V8 optimizations - for (let a = 1; a < argsLen; a++) { - str += ' ' + args[a]; - } - } +function buildGraph() { + var graph = {}; + // https://jsperf.com/object-keys-vs-for-in-with-closure/3 + var models = Object.keys(conversions); - if (!this.enabled || this.level <= 0 || !str) { - return this._empty ? '' : str; + for (var len = models.length, i = 0; i < len; i++) { + graph[models[i]] = { + // http://jsperf.com/1-vs-infinity + // micro-opt, but this is simple. + distance: -1, + parent: null + }; } - // Turns out that on Windows dimmed gray text becomes invisible in cmd.exe, - // see https://github.com/chalk/chalk/issues/58 - // If we're on Windows and we're dealing with a gray color, temporarily make 'dim' a noop. - const originalDim = ansiStyles.dim.open; - if (isSimpleWindowsTerm && this.hasGrey) { - ansiStyles.dim.open = ''; - } + return graph; +} - for (const code of this._styles.slice().reverse()) { - // Replace any instances already present with a re-opening code - // otherwise only the part of the string until said closing code - // will be colored, and the rest will simply be 'plain'. - str = code.open + str.replace(code.closeRe, code.open) + code.close; +// https://en.wikipedia.org/wiki/Breadth-first_search +function deriveBFS(fromModel) { + var graph = buildGraph(); + var queue = [fromModel]; // unshift -> queue -> pop - // Close the styling before a linebreak and reopen - // after next line to fix a bleed issue on macOS - // https://github.com/chalk/chalk/pull/92 - str = str.replace(/\r?\n/g, `${code.close}$&${code.open}`); + graph[fromModel].distance = 0; + + while (queue.length) { + var current = queue.pop(); + var adjacents = Object.keys(conversions[current]); + + for (var len = adjacents.length, i = 0; i < len; i++) { + var adjacent = adjacents[i]; + var node = graph[adjacent]; + + if (node.distance === -1) { + node.distance = graph[current].distance + 1; + node.parent = current; + queue.unshift(adjacent); + } + } } - // Reset the original `dim` if we changed it to work around the Windows dimmed gray issue - ansiStyles.dim.open = originalDim; - - return str; + return graph; } -function chalkTag(chalk, strings) { - if (!Array.isArray(strings)) { - // If chalk() was called by itself or with a string, - // return the string itself as a string. - return [].slice.call(arguments, 1).join(' '); - } +function link(from, to) { + return function (args) { + return to(from(args)); + }; +} - const args = [].slice.call(arguments, 2); - const parts = [strings.raw[0]]; +function wrapConversion(toModel, graph) { + var path = [graph[toModel].parent, toModel]; + var fn = conversions[graph[toModel].parent][toModel]; - for (let i = 1; i < strings.length; i++) { - parts.push(String(args[i - 1]).replace(/[{}\\]/g, '\\$&')); - parts.push(String(strings.raw[i])); + var cur = graph[toModel].parent; + while (graph[cur].parent) { + path.unshift(graph[cur].parent); + fn = link(conversions[graph[cur].parent][cur], fn); + cur = graph[cur].parent; } - return template(chalk, parts.join('')); + fn.conversion = path; + return fn; } -Object.defineProperties(Chalk.prototype, styles); +module.exports = function (fromModel) { + var graph = deriveBFS(fromModel); + var conversion = {}; + + var models = Object.keys(graph); + for (var len = models.length, i = 0; i < len; i++) { + var toModel = models[i]; + var node = graph[toModel]; + + if (node.parent === null) { + // no possible conversion, or this node is the source model. + continue; + } + + conversion[toModel] = wrapConversion(toModel, graph); + } + + return conversion; +}; -module.exports = Chalk(); // eslint-disable-line new-cap -module.exports.supportsColor = stdoutColor; -module.exports.default = module.exports; // For TypeScript /***/ }), -/* 385 */ +/* 382 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -/* WEBPACK VAR INJECTION */(function(module) { -const colorConvert = __webpack_require__(180); - -const wrapAnsi16 = (fn, offset) => function () { - const code = fn.apply(colorConvert, arguments); - return `\u001B[${code + offset}m`; -}; -const wrapAnsi256 = (fn, offset) => function () { - const code = fn.apply(colorConvert, arguments); - return `\u001B[${38 + offset};5;${code}m`; -}; +const os = __webpack_require__(120); +const hasFlag = __webpack_require__(383); -const wrapAnsi16m = (fn, offset) => function () { - const rgb = fn.apply(colorConvert, arguments); - return `\u001B[${38 + offset};2;${rgb[0]};${rgb[1]};${rgb[2]}m`; -}; +const env = process.env; -function assembleStyles() { - const codes = new Map(); - const styles = { - modifier: { - reset: [0, 0], - // 21 isn't widely supported and 22 does the same thing - bold: [1, 22], - dim: [2, 22], - italic: [3, 23], - underline: [4, 24], - inverse: [7, 27], - hidden: [8, 28], - strikethrough: [9, 29] - }, - color: { - black: [30, 39], - red: [31, 39], - green: [32, 39], - yellow: [33, 39], - blue: [34, 39], - magenta: [35, 39], - cyan: [36, 39], - white: [37, 39], - gray: [90, 39], +let forceColor; +if (hasFlag('no-color') || + hasFlag('no-colors') || + hasFlag('color=false')) { + forceColor = false; +} else if (hasFlag('color') || + hasFlag('colors') || + hasFlag('color=true') || + hasFlag('color=always')) { + forceColor = true; +} +if ('FORCE_COLOR' in env) { + forceColor = env.FORCE_COLOR.length === 0 || parseInt(env.FORCE_COLOR, 10) !== 0; +} - // Bright color - redBright: [91, 39], - greenBright: [92, 39], - yellowBright: [93, 39], - blueBright: [94, 39], - magentaBright: [95, 39], - cyanBright: [96, 39], - whiteBright: [97, 39] - }, - bgColor: { - bgBlack: [40, 49], - bgRed: [41, 49], - bgGreen: [42, 49], - bgYellow: [43, 49], - bgBlue: [44, 49], - bgMagenta: [45, 49], - bgCyan: [46, 49], - bgWhite: [47, 49], +function translateLevel(level) { + if (level === 0) { + return false; + } - // Bright color - bgBlackBright: [100, 49], - bgRedBright: [101, 49], - bgGreenBright: [102, 49], - bgYellowBright: [103, 49], - bgBlueBright: [104, 49], - bgMagentaBright: [105, 49], - bgCyanBright: [106, 49], - bgWhiteBright: [107, 49] - } + return { + level, + hasBasic: true, + has256: level >= 2, + has16m: level >= 3 }; +} - // Fix humans - styles.color.grey = styles.color.gray; +function supportsColor(stream) { + if (forceColor === false) { + return 0; + } - for (const groupName of Object.keys(styles)) { - const group = styles[groupName]; + if (hasFlag('color=16m') || + hasFlag('color=full') || + hasFlag('color=truecolor')) { + return 3; + } - for (const styleName of Object.keys(group)) { - const style = group[styleName]; + if (hasFlag('color=256')) { + return 2; + } - styles[styleName] = { - open: `\u001B[${style[0]}m`, - close: `\u001B[${style[1]}m` - }; + if (stream && !stream.isTTY && forceColor !== true) { + return 0; + } - group[styleName] = styles[styleName]; + const min = forceColor ? 1 : 0; - codes.set(style[0], style[1]); + if (process.platform === 'win32') { + // Node.js 7.5.0 is the first version of Node.js to include a patch to + // libuv that enables 256 color output on Windows. Anything earlier and it + // won't work. However, here we target Node.js 8 at minimum as it is an LTS + // release, and Node.js 7 is not. Windows 10 build 10586 is the first Windows + // release that supports 256 colors. Windows 10 build 14931 is the first release + // that supports 16m/TrueColor. + const osRelease = os.release().split('.'); + if ( + Number(process.versions.node.split('.')[0]) >= 8 && + Number(osRelease[0]) >= 10 && + Number(osRelease[2]) >= 10586 + ) { + return Number(osRelease[2]) >= 14931 ? 3 : 2; } - Object.defineProperty(styles, groupName, { - value: group, - enumerable: false - }); - - Object.defineProperty(styles, 'codes', { - value: codes, - enumerable: false - }); + return 1; } - const ansi2ansi = n => n; - const rgb2rgb = (r, g, b) => [r, g, b]; - - styles.color.close = '\u001B[39m'; - styles.bgColor.close = '\u001B[49m'; + if ('CI' in env) { + if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI'].some(sign => sign in env) || env.CI_NAME === 'codeship') { + return 1; + } - styles.color.ansi = { - ansi: wrapAnsi16(ansi2ansi, 0) - }; - styles.color.ansi256 = { - ansi256: wrapAnsi256(ansi2ansi, 0) - }; - styles.color.ansi16m = { - rgb: wrapAnsi16m(rgb2rgb, 0) - }; + return min; + } - styles.bgColor.ansi = { - ansi: wrapAnsi16(ansi2ansi, 10) - }; - styles.bgColor.ansi256 = { - ansi256: wrapAnsi256(ansi2ansi, 10) - }; - styles.bgColor.ansi16m = { - rgb: wrapAnsi16m(rgb2rgb, 10) - }; + if ('TEAMCITY_VERSION' in env) { + return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0; + } - for (let key of Object.keys(colorConvert)) { - if (typeof colorConvert[key] !== 'object') { - continue; - } + if (env.COLORTERM === 'truecolor') { + return 3; + } - const suite = colorConvert[key]; + if ('TERM_PROGRAM' in env) { + const version = parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10); - if (key === 'ansi16') { - key = 'ansi'; + switch (env.TERM_PROGRAM) { + case 'iTerm.app': + return version >= 3 ? 3 : 2; + case 'Apple_Terminal': + return 2; + // No default } + } - if ('ansi16' in suite) { - styles.color.ansi[key] = wrapAnsi16(suite.ansi16, 0); - styles.bgColor.ansi[key] = wrapAnsi16(suite.ansi16, 10); - } + if (/-256(color)?$/i.test(env.TERM)) { + return 2; + } - if ('ansi256' in suite) { - styles.color.ansi256[key] = wrapAnsi256(suite.ansi256, 0); - styles.bgColor.ansi256[key] = wrapAnsi256(suite.ansi256, 10); - } + if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) { + return 1; + } - if ('rgb' in suite) { - styles.color.ansi16m[key] = wrapAnsi16m(suite.rgb, 0); - styles.bgColor.ansi16m[key] = wrapAnsi16m(suite.rgb, 10); - } + if ('COLORTERM' in env) { + return 1; } - return styles; + if (env.TERM === 'dumb') { + return min; + } + + return min; } -// Make the export immutable -Object.defineProperty(module, 'exports', { - enumerable: true, - get: assembleStyles -}); +function getSupportLevel(stream) { + const level = supportsColor(stream); + return translateLevel(level); +} + +module.exports = { + supportsColor: getSupportLevel, + stdout: getSupportLevel(process.stdout), + stderr: getSupportLevel(process.stderr) +}; -/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(114)(module))) /***/ }), -/* 386 */ +/* 383 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +module.exports = (flag, argv) => { + argv = argv || process.argv; + const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--'); + const pos = argv.indexOf(prefix + flag); + const terminatorPos = argv.indexOf('--'); + return pos !== -1 && (terminatorPos === -1 ? true : pos < terminatorPos); +}; + + +/***/ }), +/* 384 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -50339,12 +50194,12 @@ module.exports = (chalk, tmp) => { /***/ }), -/* 387 */ +/* 385 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const restoreCursor = __webpack_require__(388); +const restoreCursor = __webpack_require__(386); let hidden = false; @@ -50385,13 +50240,13 @@ exports.toggle = (force, stream) => { /***/ }), -/* 388 */ +/* 386 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const onetime = __webpack_require__(389); -const signalExit = __webpack_require__(225); +const onetime = __webpack_require__(387); +const signalExit = __webpack_require__(217); module.exports = onetime(() => { signalExit(() => { @@ -50401,12 +50256,12 @@ module.exports = onetime(() => { /***/ }), -/* 389 */ +/* 387 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const mimicFn = __webpack_require__(390); +const mimicFn = __webpack_require__(388); module.exports = (fn, opts) => { // TODO: Remove this in v3 @@ -50447,7 +50302,7 @@ module.exports = (fn, opts) => { /***/ }), -/* 390 */ +/* 388 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -50463,27 +50318,27 @@ module.exports = (to, from) => { /***/ }), -/* 391 */ +/* 389 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -module.exports = __webpack_require__(392); +module.exports = __webpack_require__(390); /***/ }), -/* 392 */ +/* 390 */ /***/ (function(module) { module.exports = JSON.parse("{\"dots\":{\"interval\":80,\"frames\":[\"⠋\",\"⠙\",\"⠹\",\"⠸\",\"⠼\",\"⠴\",\"⠦\",\"⠧\",\"⠇\",\"⠏\"]},\"dots2\":{\"interval\":80,\"frames\":[\"⣾\",\"⣽\",\"⣻\",\"⢿\",\"⡿\",\"⣟\",\"⣯\",\"⣷\"]},\"dots3\":{\"interval\":80,\"frames\":[\"⠋\",\"⠙\",\"⠚\",\"⠞\",\"⠖\",\"⠦\",\"⠴\",\"⠲\",\"⠳\",\"⠓\"]},\"dots4\":{\"interval\":80,\"frames\":[\"⠄\",\"⠆\",\"⠇\",\"⠋\",\"⠙\",\"⠸\",\"⠰\",\"⠠\",\"⠰\",\"⠸\",\"⠙\",\"⠋\",\"⠇\",\"⠆\"]},\"dots5\":{\"interval\":80,\"frames\":[\"⠋\",\"⠙\",\"⠚\",\"⠒\",\"⠂\",\"⠂\",\"⠒\",\"⠲\",\"⠴\",\"⠦\",\"⠖\",\"⠒\",\"⠐\",\"⠐\",\"⠒\",\"⠓\",\"⠋\"]},\"dots6\":{\"interval\":80,\"frames\":[\"⠁\",\"⠉\",\"⠙\",\"⠚\",\"⠒\",\"⠂\",\"⠂\",\"⠒\",\"⠲\",\"⠴\",\"⠤\",\"⠄\",\"⠄\",\"⠤\",\"⠴\",\"⠲\",\"⠒\",\"⠂\",\"⠂\",\"⠒\",\"⠚\",\"⠙\",\"⠉\",\"⠁\"]},\"dots7\":{\"interval\":80,\"frames\":[\"⠈\",\"⠉\",\"⠋\",\"⠓\",\"⠒\",\"⠐\",\"⠐\",\"⠒\",\"⠖\",\"⠦\",\"⠤\",\"⠠\",\"⠠\",\"⠤\",\"⠦\",\"⠖\",\"⠒\",\"⠐\",\"⠐\",\"⠒\",\"⠓\",\"⠋\",\"⠉\",\"⠈\"]},\"dots8\":{\"interval\":80,\"frames\":[\"⠁\",\"⠁\",\"⠉\",\"⠙\",\"⠚\",\"⠒\",\"⠂\",\"⠂\",\"⠒\",\"⠲\",\"⠴\",\"⠤\",\"⠄\",\"⠄\",\"⠤\",\"⠠\",\"⠠\",\"⠤\",\"⠦\",\"⠖\",\"⠒\",\"⠐\",\"⠐\",\"⠒\",\"⠓\",\"⠋\",\"⠉\",\"⠈\",\"⠈\"]},\"dots9\":{\"interval\":80,\"frames\":[\"⢹\",\"⢺\",\"⢼\",\"⣸\",\"⣇\",\"⡧\",\"⡗\",\"⡏\"]},\"dots10\":{\"interval\":80,\"frames\":[\"⢄\",\"⢂\",\"⢁\",\"⡁\",\"⡈\",\"⡐\",\"⡠\"]},\"dots11\":{\"interval\":100,\"frames\":[\"⠁\",\"⠂\",\"⠄\",\"⡀\",\"⢀\",\"⠠\",\"⠐\",\"⠈\"]},\"dots12\":{\"interval\":80,\"frames\":[\"⢀⠀\",\"⡀⠀\",\"⠄⠀\",\"⢂⠀\",\"⡂⠀\",\"⠅⠀\",\"⢃⠀\",\"⡃⠀\",\"⠍⠀\",\"⢋⠀\",\"⡋⠀\",\"⠍⠁\",\"⢋⠁\",\"⡋⠁\",\"⠍⠉\",\"⠋⠉\",\"⠋⠉\",\"⠉⠙\",\"⠉⠙\",\"⠉⠩\",\"⠈⢙\",\"⠈⡙\",\"⢈⠩\",\"⡀⢙\",\"⠄⡙\",\"⢂⠩\",\"⡂⢘\",\"⠅⡘\",\"⢃⠨\",\"⡃⢐\",\"⠍⡐\",\"⢋⠠\",\"⡋⢀\",\"⠍⡁\",\"⢋⠁\",\"⡋⠁\",\"⠍⠉\",\"⠋⠉\",\"⠋⠉\",\"⠉⠙\",\"⠉⠙\",\"⠉⠩\",\"⠈⢙\",\"⠈⡙\",\"⠈⠩\",\"⠀⢙\",\"⠀⡙\",\"⠀⠩\",\"⠀⢘\",\"⠀⡘\",\"⠀⠨\",\"⠀⢐\",\"⠀⡐\",\"⠀⠠\",\"⠀⢀\",\"⠀⡀\"]},\"line\":{\"interval\":130,\"frames\":[\"-\",\"\\\\\",\"|\",\"/\"]},\"line2\":{\"interval\":100,\"frames\":[\"⠂\",\"-\",\"–\",\"—\",\"–\",\"-\"]},\"pipe\":{\"interval\":100,\"frames\":[\"┤\",\"┘\",\"┴\",\"└\",\"├\",\"┌\",\"┬\",\"┐\"]},\"simpleDots\":{\"interval\":400,\"frames\":[\". \",\".. \",\"...\",\" \"]},\"simpleDotsScrolling\":{\"interval\":200,\"frames\":[\". \",\".. \",\"...\",\" ..\",\" .\",\" \"]},\"star\":{\"interval\":70,\"frames\":[\"✶\",\"✸\",\"✹\",\"✺\",\"✹\",\"✷\"]},\"star2\":{\"interval\":80,\"frames\":[\"+\",\"x\",\"*\"]},\"flip\":{\"interval\":70,\"frames\":[\"_\",\"_\",\"_\",\"-\",\"`\",\"`\",\"'\",\"´\",\"-\",\"_\",\"_\",\"_\"]},\"hamburger\":{\"interval\":100,\"frames\":[\"☱\",\"☲\",\"☴\"]},\"growVertical\":{\"interval\":120,\"frames\":[\"▁\",\"▃\",\"▄\",\"▅\",\"▆\",\"▇\",\"▆\",\"▅\",\"▄\",\"▃\"]},\"growHorizontal\":{\"interval\":120,\"frames\":[\"▏\",\"▎\",\"▍\",\"▌\",\"▋\",\"▊\",\"▉\",\"▊\",\"▋\",\"▌\",\"▍\",\"▎\"]},\"balloon\":{\"interval\":140,\"frames\":[\" \",\".\",\"o\",\"O\",\"@\",\"*\",\" \"]},\"balloon2\":{\"interval\":120,\"frames\":[\".\",\"o\",\"O\",\"°\",\"O\",\"o\",\".\"]},\"noise\":{\"interval\":100,\"frames\":[\"▓\",\"▒\",\"░\"]},\"bounce\":{\"interval\":120,\"frames\":[\"⠁\",\"⠂\",\"⠄\",\"⠂\"]},\"boxBounce\":{\"interval\":120,\"frames\":[\"▖\",\"▘\",\"▝\",\"▗\"]},\"boxBounce2\":{\"interval\":100,\"frames\":[\"▌\",\"▀\",\"▐\",\"▄\"]},\"triangle\":{\"interval\":50,\"frames\":[\"◢\",\"◣\",\"◤\",\"◥\"]},\"arc\":{\"interval\":100,\"frames\":[\"◜\",\"◠\",\"◝\",\"◞\",\"◡\",\"◟\"]},\"circle\":{\"interval\":120,\"frames\":[\"◡\",\"⊙\",\"◠\"]},\"squareCorners\":{\"interval\":180,\"frames\":[\"◰\",\"◳\",\"◲\",\"◱\"]},\"circleQuarters\":{\"interval\":120,\"frames\":[\"◴\",\"◷\",\"◶\",\"◵\"]},\"circleHalves\":{\"interval\":50,\"frames\":[\"◐\",\"◓\",\"◑\",\"◒\"]},\"squish\":{\"interval\":100,\"frames\":[\"╫\",\"╪\"]},\"toggle\":{\"interval\":250,\"frames\":[\"⊶\",\"⊷\"]},\"toggle2\":{\"interval\":80,\"frames\":[\"▫\",\"▪\"]},\"toggle3\":{\"interval\":120,\"frames\":[\"□\",\"■\"]},\"toggle4\":{\"interval\":100,\"frames\":[\"■\",\"□\",\"▪\",\"▫\"]},\"toggle5\":{\"interval\":100,\"frames\":[\"▮\",\"▯\"]},\"toggle6\":{\"interval\":300,\"frames\":[\"ဝ\",\"၀\"]},\"toggle7\":{\"interval\":80,\"frames\":[\"⦾\",\"⦿\"]},\"toggle8\":{\"interval\":100,\"frames\":[\"◍\",\"◌\"]},\"toggle9\":{\"interval\":100,\"frames\":[\"◉\",\"◎\"]},\"toggle10\":{\"interval\":100,\"frames\":[\"㊂\",\"㊀\",\"㊁\"]},\"toggle11\":{\"interval\":50,\"frames\":[\"⧇\",\"⧆\"]},\"toggle12\":{\"interval\":120,\"frames\":[\"☗\",\"☖\"]},\"toggle13\":{\"interval\":80,\"frames\":[\"=\",\"*\",\"-\"]},\"arrow\":{\"interval\":100,\"frames\":[\"←\",\"↖\",\"↑\",\"↗\",\"→\",\"↘\",\"↓\",\"↙\"]},\"arrow2\":{\"interval\":80,\"frames\":[\"⬆️ \",\"↗️ \",\"➡️ \",\"↘️ \",\"⬇️ \",\"↙️ \",\"⬅️ \",\"↖️ \"]},\"arrow3\":{\"interval\":120,\"frames\":[\"▹▹▹▹▹\",\"▸▹▹▹▹\",\"▹▸▹▹▹\",\"▹▹▸▹▹\",\"▹▹▹▸▹\",\"▹▹▹▹▸\"]},\"bouncingBar\":{\"interval\":80,\"frames\":[\"[ ]\",\"[= ]\",\"[== ]\",\"[=== ]\",\"[ ===]\",\"[ ==]\",\"[ =]\",\"[ ]\",\"[ =]\",\"[ ==]\",\"[ ===]\",\"[====]\",\"[=== ]\",\"[== ]\",\"[= ]\"]},\"bouncingBall\":{\"interval\":80,\"frames\":[\"( ● )\",\"( ● )\",\"( ● )\",\"( ● )\",\"( ●)\",\"( ● )\",\"( ● )\",\"( ● )\",\"( ● )\",\"(● )\"]},\"smiley\":{\"interval\":200,\"frames\":[\"😄 \",\"😝 \"]},\"monkey\":{\"interval\":300,\"frames\":[\"🙈 \",\"🙈 \",\"🙉 \",\"🙊 \"]},\"hearts\":{\"interval\":100,\"frames\":[\"💛 \",\"💙 \",\"💜 \",\"💚 \",\"❤️ \"]},\"clock\":{\"interval\":100,\"frames\":[\"🕐 \",\"🕑 \",\"🕒 \",\"🕓 \",\"🕔 \",\"🕕 \",\"🕖 \",\"🕗 \",\"🕘 \",\"🕙 \",\"🕚 \"]},\"earth\":{\"interval\":180,\"frames\":[\"🌍 \",\"🌎 \",\"🌏 \"]},\"moon\":{\"interval\":80,\"frames\":[\"🌑 \",\"🌒 \",\"🌓 \",\"🌔 \",\"🌕 \",\"🌖 \",\"🌗 \",\"🌘 \"]},\"runner\":{\"interval\":140,\"frames\":[\"🚶 \",\"🏃 \"]},\"pong\":{\"interval\":80,\"frames\":[\"▐⠂ ▌\",\"▐⠈ ▌\",\"▐ ⠂ ▌\",\"▐ ⠠ ▌\",\"▐ ⡀ ▌\",\"▐ ⠠ ▌\",\"▐ ⠂ ▌\",\"▐ ⠈ ▌\",\"▐ ⠂ ▌\",\"▐ ⠠ ▌\",\"▐ ⡀ ▌\",\"▐ ⠠ ▌\",\"▐ ⠂ ▌\",\"▐ ⠈ ▌\",\"▐ ⠂▌\",\"▐ ⠠▌\",\"▐ ⡀▌\",\"▐ ⠠ ▌\",\"▐ ⠂ ▌\",\"▐ ⠈ ▌\",\"▐ ⠂ ▌\",\"▐ ⠠ ▌\",\"▐ ⡀ ▌\",\"▐ ⠠ ▌\",\"▐ ⠂ ▌\",\"▐ ⠈ ▌\",\"▐ ⠂ ▌\",\"▐ ⠠ ▌\",\"▐ ⡀ ▌\",\"▐⠠ ▌\"]},\"shark\":{\"interval\":120,\"frames\":[\"▐|\\\\____________▌\",\"▐_|\\\\___________▌\",\"▐__|\\\\__________▌\",\"▐___|\\\\_________▌\",\"▐____|\\\\________▌\",\"▐_____|\\\\_______▌\",\"▐______|\\\\______▌\",\"▐_______|\\\\_____▌\",\"▐________|\\\\____▌\",\"▐_________|\\\\___▌\",\"▐__________|\\\\__▌\",\"▐___________|\\\\_▌\",\"▐____________|\\\\▌\",\"▐____________/|▌\",\"▐___________/|_▌\",\"▐__________/|__▌\",\"▐_________/|___▌\",\"▐________/|____▌\",\"▐_______/|_____▌\",\"▐______/|______▌\",\"▐_____/|_______▌\",\"▐____/|________▌\",\"▐___/|_________▌\",\"▐__/|__________▌\",\"▐_/|___________▌\",\"▐/|____________▌\"]},\"dqpb\":{\"interval\":100,\"frames\":[\"d\",\"q\",\"p\",\"b\"]},\"weather\":{\"interval\":100,\"frames\":[\"☀️ \",\"☀️ \",\"☀️ \",\"🌤 \",\"⛅️ \",\"🌥 \",\"☁️ \",\"🌧 \",\"🌨 \",\"🌧 \",\"🌨 \",\"🌧 \",\"🌨 \",\"⛈ \",\"🌨 \",\"🌧 \",\"🌨 \",\"☁️ \",\"🌥 \",\"⛅️ \",\"🌤 \",\"☀️ \",\"☀️ \"]},\"christmas\":{\"interval\":400,\"frames\":[\"🌲\",\"🎄\"]}}"); /***/ }), -/* 393 */ +/* 391 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const chalk = __webpack_require__(394); +const chalk = __webpack_require__(392); const isSupported = process.platform !== 'win32' || process.env.CI || process.env.TERM === 'xterm-256color'; @@ -50505,16 +50360,16 @@ module.exports = isSupported ? main : fallbacks; /***/ }), -/* 394 */ +/* 392 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const escapeStringRegexp = __webpack_require__(178); -const ansiStyles = __webpack_require__(395); +const ansiStyles = __webpack_require__(393); const stdoutColor = __webpack_require__(184).stdout; -const template = __webpack_require__(396); +const template = __webpack_require__(394); const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm'); @@ -50740,7 +50595,7 @@ module.exports.default = module.exports; // For TypeScript /***/ }), -/* 395 */ +/* 393 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -50913,7 +50768,7 @@ Object.defineProperty(module, 'exports', { /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(114)(module))) /***/ }), -/* 396 */ +/* 394 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -51048,7 +50903,7 @@ module.exports = (chalk, tmp) => { /***/ }), -/* 397 */ +/* 395 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -51109,7 +50964,7 @@ const RunCommand = { }; /***/ }), -/* 398 */ +/* 396 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -51119,7 +50974,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); /* harmony import */ var _utils_parallelize__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(144); /* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(145); -/* harmony import */ var _utils_watch__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(399); +/* harmony import */ var _utils_watch__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(397); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -51204,14 +51059,14 @@ const WatchCommand = { }; /***/ }), -/* 399 */ +/* 397 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "waitUntilWatchIsReady", function() { return waitUntilWatchIsReady; }); /* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8); -/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(400); +/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(398); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -51278,141 +51133,141 @@ function waitUntilWatchIsReady(stream, opts = {}) { } /***/ }), -/* 400 */ +/* 398 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony import */ var _internal_operators_audit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(401); +/* harmony import */ var _internal_operators_audit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(399); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "audit", function() { return _internal_operators_audit__WEBPACK_IMPORTED_MODULE_0__["audit"]; }); -/* harmony import */ var _internal_operators_auditTime__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(402); +/* harmony import */ var _internal_operators_auditTime__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(400); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "auditTime", function() { return _internal_operators_auditTime__WEBPACK_IMPORTED_MODULE_1__["auditTime"]; }); -/* harmony import */ var _internal_operators_buffer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(403); +/* harmony import */ var _internal_operators_buffer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(401); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "buffer", function() { return _internal_operators_buffer__WEBPACK_IMPORTED_MODULE_2__["buffer"]; }); -/* harmony import */ var _internal_operators_bufferCount__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(404); +/* harmony import */ var _internal_operators_bufferCount__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(402); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "bufferCount", function() { return _internal_operators_bufferCount__WEBPACK_IMPORTED_MODULE_3__["bufferCount"]; }); -/* harmony import */ var _internal_operators_bufferTime__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(405); +/* harmony import */ var _internal_operators_bufferTime__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(403); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "bufferTime", function() { return _internal_operators_bufferTime__WEBPACK_IMPORTED_MODULE_4__["bufferTime"]; }); -/* harmony import */ var _internal_operators_bufferToggle__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(406); +/* harmony import */ var _internal_operators_bufferToggle__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(404); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "bufferToggle", function() { return _internal_operators_bufferToggle__WEBPACK_IMPORTED_MODULE_5__["bufferToggle"]; }); -/* harmony import */ var _internal_operators_bufferWhen__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(407); +/* harmony import */ var _internal_operators_bufferWhen__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(405); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "bufferWhen", function() { return _internal_operators_bufferWhen__WEBPACK_IMPORTED_MODULE_6__["bufferWhen"]; }); -/* harmony import */ var _internal_operators_catchError__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(408); +/* harmony import */ var _internal_operators_catchError__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(406); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "catchError", function() { return _internal_operators_catchError__WEBPACK_IMPORTED_MODULE_7__["catchError"]; }); -/* harmony import */ var _internal_operators_combineAll__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(409); +/* harmony import */ var _internal_operators_combineAll__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(407); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "combineAll", function() { return _internal_operators_combineAll__WEBPACK_IMPORTED_MODULE_8__["combineAll"]; }); -/* harmony import */ var _internal_operators_combineLatest__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(410); +/* harmony import */ var _internal_operators_combineLatest__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(408); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "combineLatest", function() { return _internal_operators_combineLatest__WEBPACK_IMPORTED_MODULE_9__["combineLatest"]; }); -/* harmony import */ var _internal_operators_concat__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(411); +/* harmony import */ var _internal_operators_concat__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(409); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "concat", function() { return _internal_operators_concat__WEBPACK_IMPORTED_MODULE_10__["concat"]; }); /* harmony import */ var _internal_operators_concatAll__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(80); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "concatAll", function() { return _internal_operators_concatAll__WEBPACK_IMPORTED_MODULE_11__["concatAll"]; }); -/* harmony import */ var _internal_operators_concatMap__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(412); +/* harmony import */ var _internal_operators_concatMap__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(410); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "concatMap", function() { return _internal_operators_concatMap__WEBPACK_IMPORTED_MODULE_12__["concatMap"]; }); -/* harmony import */ var _internal_operators_concatMapTo__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(413); +/* harmony import */ var _internal_operators_concatMapTo__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(411); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "concatMapTo", function() { return _internal_operators_concatMapTo__WEBPACK_IMPORTED_MODULE_13__["concatMapTo"]; }); -/* harmony import */ var _internal_operators_count__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(414); +/* harmony import */ var _internal_operators_count__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(412); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "count", function() { return _internal_operators_count__WEBPACK_IMPORTED_MODULE_14__["count"]; }); -/* harmony import */ var _internal_operators_debounce__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(415); +/* harmony import */ var _internal_operators_debounce__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(413); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "debounce", function() { return _internal_operators_debounce__WEBPACK_IMPORTED_MODULE_15__["debounce"]; }); -/* harmony import */ var _internal_operators_debounceTime__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(416); +/* harmony import */ var _internal_operators_debounceTime__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(414); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "debounceTime", function() { return _internal_operators_debounceTime__WEBPACK_IMPORTED_MODULE_16__["debounceTime"]; }); -/* harmony import */ var _internal_operators_defaultIfEmpty__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(417); +/* harmony import */ var _internal_operators_defaultIfEmpty__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(415); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "defaultIfEmpty", function() { return _internal_operators_defaultIfEmpty__WEBPACK_IMPORTED_MODULE_17__["defaultIfEmpty"]; }); -/* harmony import */ var _internal_operators_delay__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(418); +/* harmony import */ var _internal_operators_delay__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(416); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "delay", function() { return _internal_operators_delay__WEBPACK_IMPORTED_MODULE_18__["delay"]; }); -/* harmony import */ var _internal_operators_delayWhen__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(420); +/* harmony import */ var _internal_operators_delayWhen__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(418); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "delayWhen", function() { return _internal_operators_delayWhen__WEBPACK_IMPORTED_MODULE_19__["delayWhen"]; }); -/* harmony import */ var _internal_operators_dematerialize__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(421); +/* harmony import */ var _internal_operators_dematerialize__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(419); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "dematerialize", function() { return _internal_operators_dematerialize__WEBPACK_IMPORTED_MODULE_20__["dematerialize"]; }); -/* harmony import */ var _internal_operators_distinct__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(422); +/* harmony import */ var _internal_operators_distinct__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(420); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "distinct", function() { return _internal_operators_distinct__WEBPACK_IMPORTED_MODULE_21__["distinct"]; }); -/* harmony import */ var _internal_operators_distinctUntilChanged__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(423); +/* harmony import */ var _internal_operators_distinctUntilChanged__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(421); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "distinctUntilChanged", function() { return _internal_operators_distinctUntilChanged__WEBPACK_IMPORTED_MODULE_22__["distinctUntilChanged"]; }); -/* harmony import */ var _internal_operators_distinctUntilKeyChanged__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(424); +/* harmony import */ var _internal_operators_distinctUntilKeyChanged__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(422); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "distinctUntilKeyChanged", function() { return _internal_operators_distinctUntilKeyChanged__WEBPACK_IMPORTED_MODULE_23__["distinctUntilKeyChanged"]; }); -/* harmony import */ var _internal_operators_elementAt__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(425); +/* harmony import */ var _internal_operators_elementAt__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(423); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "elementAt", function() { return _internal_operators_elementAt__WEBPACK_IMPORTED_MODULE_24__["elementAt"]; }); -/* harmony import */ var _internal_operators_endWith__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(428); +/* harmony import */ var _internal_operators_endWith__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(426); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "endWith", function() { return _internal_operators_endWith__WEBPACK_IMPORTED_MODULE_25__["endWith"]; }); -/* harmony import */ var _internal_operators_every__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(429); +/* harmony import */ var _internal_operators_every__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(427); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "every", function() { return _internal_operators_every__WEBPACK_IMPORTED_MODULE_26__["every"]; }); -/* harmony import */ var _internal_operators_exhaust__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(430); +/* harmony import */ var _internal_operators_exhaust__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(428); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "exhaust", function() { return _internal_operators_exhaust__WEBPACK_IMPORTED_MODULE_27__["exhaust"]; }); -/* harmony import */ var _internal_operators_exhaustMap__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(431); +/* harmony import */ var _internal_operators_exhaustMap__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(429); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "exhaustMap", function() { return _internal_operators_exhaustMap__WEBPACK_IMPORTED_MODULE_28__["exhaustMap"]; }); -/* harmony import */ var _internal_operators_expand__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(432); +/* harmony import */ var _internal_operators_expand__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(430); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "expand", function() { return _internal_operators_expand__WEBPACK_IMPORTED_MODULE_29__["expand"]; }); /* harmony import */ var _internal_operators_filter__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(104); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "filter", function() { return _internal_operators_filter__WEBPACK_IMPORTED_MODULE_30__["filter"]; }); -/* harmony import */ var _internal_operators_finalize__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(433); +/* harmony import */ var _internal_operators_finalize__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(431); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "finalize", function() { return _internal_operators_finalize__WEBPACK_IMPORTED_MODULE_31__["finalize"]; }); -/* harmony import */ var _internal_operators_find__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(434); +/* harmony import */ var _internal_operators_find__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(432); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "find", function() { return _internal_operators_find__WEBPACK_IMPORTED_MODULE_32__["find"]; }); -/* harmony import */ var _internal_operators_findIndex__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(435); +/* harmony import */ var _internal_operators_findIndex__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(433); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "findIndex", function() { return _internal_operators_findIndex__WEBPACK_IMPORTED_MODULE_33__["findIndex"]; }); -/* harmony import */ var _internal_operators_first__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(436); +/* harmony import */ var _internal_operators_first__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(434); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "first", function() { return _internal_operators_first__WEBPACK_IMPORTED_MODULE_34__["first"]; }); /* harmony import */ var _internal_operators_groupBy__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(31); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "groupBy", function() { return _internal_operators_groupBy__WEBPACK_IMPORTED_MODULE_35__["groupBy"]; }); -/* harmony import */ var _internal_operators_ignoreElements__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(437); +/* harmony import */ var _internal_operators_ignoreElements__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(435); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ignoreElements", function() { return _internal_operators_ignoreElements__WEBPACK_IMPORTED_MODULE_36__["ignoreElements"]; }); -/* harmony import */ var _internal_operators_isEmpty__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(438); +/* harmony import */ var _internal_operators_isEmpty__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(436); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "isEmpty", function() { return _internal_operators_isEmpty__WEBPACK_IMPORTED_MODULE_37__["isEmpty"]; }); -/* harmony import */ var _internal_operators_last__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(439); +/* harmony import */ var _internal_operators_last__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(437); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "last", function() { return _internal_operators_last__WEBPACK_IMPORTED_MODULE_38__["last"]; }); /* harmony import */ var _internal_operators_map__WEBPACK_IMPORTED_MODULE_39__ = __webpack_require__(66); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "map", function() { return _internal_operators_map__WEBPACK_IMPORTED_MODULE_39__["map"]; }); -/* harmony import */ var _internal_operators_mapTo__WEBPACK_IMPORTED_MODULE_40__ = __webpack_require__(441); +/* harmony import */ var _internal_operators_mapTo__WEBPACK_IMPORTED_MODULE_40__ = __webpack_require__(439); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "mapTo", function() { return _internal_operators_mapTo__WEBPACK_IMPORTED_MODULE_40__["mapTo"]; }); -/* harmony import */ var _internal_operators_materialize__WEBPACK_IMPORTED_MODULE_41__ = __webpack_require__(442); +/* harmony import */ var _internal_operators_materialize__WEBPACK_IMPORTED_MODULE_41__ = __webpack_require__(440); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "materialize", function() { return _internal_operators_materialize__WEBPACK_IMPORTED_MODULE_41__["materialize"]; }); -/* harmony import */ var _internal_operators_max__WEBPACK_IMPORTED_MODULE_42__ = __webpack_require__(443); +/* harmony import */ var _internal_operators_max__WEBPACK_IMPORTED_MODULE_42__ = __webpack_require__(441); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "max", function() { return _internal_operators_max__WEBPACK_IMPORTED_MODULE_42__["max"]; }); -/* harmony import */ var _internal_operators_merge__WEBPACK_IMPORTED_MODULE_43__ = __webpack_require__(446); +/* harmony import */ var _internal_operators_merge__WEBPACK_IMPORTED_MODULE_43__ = __webpack_require__(444); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "merge", function() { return _internal_operators_merge__WEBPACK_IMPORTED_MODULE_43__["merge"]; }); /* harmony import */ var _internal_operators_mergeAll__WEBPACK_IMPORTED_MODULE_44__ = __webpack_require__(81); @@ -51423,175 +51278,175 @@ __webpack_require__.r(__webpack_exports__); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "flatMap", function() { return _internal_operators_mergeMap__WEBPACK_IMPORTED_MODULE_45__["mergeMap"]; }); -/* harmony import */ var _internal_operators_mergeMapTo__WEBPACK_IMPORTED_MODULE_46__ = __webpack_require__(447); +/* harmony import */ var _internal_operators_mergeMapTo__WEBPACK_IMPORTED_MODULE_46__ = __webpack_require__(445); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "mergeMapTo", function() { return _internal_operators_mergeMapTo__WEBPACK_IMPORTED_MODULE_46__["mergeMapTo"]; }); -/* harmony import */ var _internal_operators_mergeScan__WEBPACK_IMPORTED_MODULE_47__ = __webpack_require__(448); +/* harmony import */ var _internal_operators_mergeScan__WEBPACK_IMPORTED_MODULE_47__ = __webpack_require__(446); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "mergeScan", function() { return _internal_operators_mergeScan__WEBPACK_IMPORTED_MODULE_47__["mergeScan"]; }); -/* harmony import */ var _internal_operators_min__WEBPACK_IMPORTED_MODULE_48__ = __webpack_require__(449); +/* harmony import */ var _internal_operators_min__WEBPACK_IMPORTED_MODULE_48__ = __webpack_require__(447); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "min", function() { return _internal_operators_min__WEBPACK_IMPORTED_MODULE_48__["min"]; }); -/* harmony import */ var _internal_operators_multicast__WEBPACK_IMPORTED_MODULE_49__ = __webpack_require__(450); +/* harmony import */ var _internal_operators_multicast__WEBPACK_IMPORTED_MODULE_49__ = __webpack_require__(448); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "multicast", function() { return _internal_operators_multicast__WEBPACK_IMPORTED_MODULE_49__["multicast"]; }); /* harmony import */ var _internal_operators_observeOn__WEBPACK_IMPORTED_MODULE_50__ = __webpack_require__(41); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "observeOn", function() { return _internal_operators_observeOn__WEBPACK_IMPORTED_MODULE_50__["observeOn"]; }); -/* harmony import */ var _internal_operators_onErrorResumeNext__WEBPACK_IMPORTED_MODULE_51__ = __webpack_require__(451); +/* harmony import */ var _internal_operators_onErrorResumeNext__WEBPACK_IMPORTED_MODULE_51__ = __webpack_require__(449); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "onErrorResumeNext", function() { return _internal_operators_onErrorResumeNext__WEBPACK_IMPORTED_MODULE_51__["onErrorResumeNext"]; }); -/* harmony import */ var _internal_operators_pairwise__WEBPACK_IMPORTED_MODULE_52__ = __webpack_require__(452); +/* harmony import */ var _internal_operators_pairwise__WEBPACK_IMPORTED_MODULE_52__ = __webpack_require__(450); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "pairwise", function() { return _internal_operators_pairwise__WEBPACK_IMPORTED_MODULE_52__["pairwise"]; }); -/* harmony import */ var _internal_operators_partition__WEBPACK_IMPORTED_MODULE_53__ = __webpack_require__(453); +/* harmony import */ var _internal_operators_partition__WEBPACK_IMPORTED_MODULE_53__ = __webpack_require__(451); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "partition", function() { return _internal_operators_partition__WEBPACK_IMPORTED_MODULE_53__["partition"]; }); -/* harmony import */ var _internal_operators_pluck__WEBPACK_IMPORTED_MODULE_54__ = __webpack_require__(454); +/* harmony import */ var _internal_operators_pluck__WEBPACK_IMPORTED_MODULE_54__ = __webpack_require__(452); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "pluck", function() { return _internal_operators_pluck__WEBPACK_IMPORTED_MODULE_54__["pluck"]; }); -/* harmony import */ var _internal_operators_publish__WEBPACK_IMPORTED_MODULE_55__ = __webpack_require__(455); +/* harmony import */ var _internal_operators_publish__WEBPACK_IMPORTED_MODULE_55__ = __webpack_require__(453); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "publish", function() { return _internal_operators_publish__WEBPACK_IMPORTED_MODULE_55__["publish"]; }); -/* harmony import */ var _internal_operators_publishBehavior__WEBPACK_IMPORTED_MODULE_56__ = __webpack_require__(456); +/* harmony import */ var _internal_operators_publishBehavior__WEBPACK_IMPORTED_MODULE_56__ = __webpack_require__(454); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "publishBehavior", function() { return _internal_operators_publishBehavior__WEBPACK_IMPORTED_MODULE_56__["publishBehavior"]; }); -/* harmony import */ var _internal_operators_publishLast__WEBPACK_IMPORTED_MODULE_57__ = __webpack_require__(457); +/* harmony import */ var _internal_operators_publishLast__WEBPACK_IMPORTED_MODULE_57__ = __webpack_require__(455); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "publishLast", function() { return _internal_operators_publishLast__WEBPACK_IMPORTED_MODULE_57__["publishLast"]; }); -/* harmony import */ var _internal_operators_publishReplay__WEBPACK_IMPORTED_MODULE_58__ = __webpack_require__(458); +/* harmony import */ var _internal_operators_publishReplay__WEBPACK_IMPORTED_MODULE_58__ = __webpack_require__(456); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "publishReplay", function() { return _internal_operators_publishReplay__WEBPACK_IMPORTED_MODULE_58__["publishReplay"]; }); -/* harmony import */ var _internal_operators_race__WEBPACK_IMPORTED_MODULE_59__ = __webpack_require__(459); +/* harmony import */ var _internal_operators_race__WEBPACK_IMPORTED_MODULE_59__ = __webpack_require__(457); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "race", function() { return _internal_operators_race__WEBPACK_IMPORTED_MODULE_59__["race"]; }); -/* harmony import */ var _internal_operators_reduce__WEBPACK_IMPORTED_MODULE_60__ = __webpack_require__(444); +/* harmony import */ var _internal_operators_reduce__WEBPACK_IMPORTED_MODULE_60__ = __webpack_require__(442); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "reduce", function() { return _internal_operators_reduce__WEBPACK_IMPORTED_MODULE_60__["reduce"]; }); -/* harmony import */ var _internal_operators_repeat__WEBPACK_IMPORTED_MODULE_61__ = __webpack_require__(460); +/* harmony import */ var _internal_operators_repeat__WEBPACK_IMPORTED_MODULE_61__ = __webpack_require__(458); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "repeat", function() { return _internal_operators_repeat__WEBPACK_IMPORTED_MODULE_61__["repeat"]; }); -/* harmony import */ var _internal_operators_repeatWhen__WEBPACK_IMPORTED_MODULE_62__ = __webpack_require__(461); +/* harmony import */ var _internal_operators_repeatWhen__WEBPACK_IMPORTED_MODULE_62__ = __webpack_require__(459); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "repeatWhen", function() { return _internal_operators_repeatWhen__WEBPACK_IMPORTED_MODULE_62__["repeatWhen"]; }); -/* harmony import */ var _internal_operators_retry__WEBPACK_IMPORTED_MODULE_63__ = __webpack_require__(462); +/* harmony import */ var _internal_operators_retry__WEBPACK_IMPORTED_MODULE_63__ = __webpack_require__(460); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "retry", function() { return _internal_operators_retry__WEBPACK_IMPORTED_MODULE_63__["retry"]; }); -/* harmony import */ var _internal_operators_retryWhen__WEBPACK_IMPORTED_MODULE_64__ = __webpack_require__(463); +/* harmony import */ var _internal_operators_retryWhen__WEBPACK_IMPORTED_MODULE_64__ = __webpack_require__(461); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "retryWhen", function() { return _internal_operators_retryWhen__WEBPACK_IMPORTED_MODULE_64__["retryWhen"]; }); /* harmony import */ var _internal_operators_refCount__WEBPACK_IMPORTED_MODULE_65__ = __webpack_require__(30); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "refCount", function() { return _internal_operators_refCount__WEBPACK_IMPORTED_MODULE_65__["refCount"]; }); -/* harmony import */ var _internal_operators_sample__WEBPACK_IMPORTED_MODULE_66__ = __webpack_require__(464); +/* harmony import */ var _internal_operators_sample__WEBPACK_IMPORTED_MODULE_66__ = __webpack_require__(462); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "sample", function() { return _internal_operators_sample__WEBPACK_IMPORTED_MODULE_66__["sample"]; }); -/* harmony import */ var _internal_operators_sampleTime__WEBPACK_IMPORTED_MODULE_67__ = __webpack_require__(465); +/* harmony import */ var _internal_operators_sampleTime__WEBPACK_IMPORTED_MODULE_67__ = __webpack_require__(463); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "sampleTime", function() { return _internal_operators_sampleTime__WEBPACK_IMPORTED_MODULE_67__["sampleTime"]; }); -/* harmony import */ var _internal_operators_scan__WEBPACK_IMPORTED_MODULE_68__ = __webpack_require__(445); +/* harmony import */ var _internal_operators_scan__WEBPACK_IMPORTED_MODULE_68__ = __webpack_require__(443); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "scan", function() { return _internal_operators_scan__WEBPACK_IMPORTED_MODULE_68__["scan"]; }); -/* harmony import */ var _internal_operators_sequenceEqual__WEBPACK_IMPORTED_MODULE_69__ = __webpack_require__(466); +/* harmony import */ var _internal_operators_sequenceEqual__WEBPACK_IMPORTED_MODULE_69__ = __webpack_require__(464); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "sequenceEqual", function() { return _internal_operators_sequenceEqual__WEBPACK_IMPORTED_MODULE_69__["sequenceEqual"]; }); -/* harmony import */ var _internal_operators_share__WEBPACK_IMPORTED_MODULE_70__ = __webpack_require__(467); +/* harmony import */ var _internal_operators_share__WEBPACK_IMPORTED_MODULE_70__ = __webpack_require__(465); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "share", function() { return _internal_operators_share__WEBPACK_IMPORTED_MODULE_70__["share"]; }); -/* harmony import */ var _internal_operators_shareReplay__WEBPACK_IMPORTED_MODULE_71__ = __webpack_require__(468); +/* harmony import */ var _internal_operators_shareReplay__WEBPACK_IMPORTED_MODULE_71__ = __webpack_require__(466); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "shareReplay", function() { return _internal_operators_shareReplay__WEBPACK_IMPORTED_MODULE_71__["shareReplay"]; }); -/* harmony import */ var _internal_operators_single__WEBPACK_IMPORTED_MODULE_72__ = __webpack_require__(469); +/* harmony import */ var _internal_operators_single__WEBPACK_IMPORTED_MODULE_72__ = __webpack_require__(467); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "single", function() { return _internal_operators_single__WEBPACK_IMPORTED_MODULE_72__["single"]; }); -/* harmony import */ var _internal_operators_skip__WEBPACK_IMPORTED_MODULE_73__ = __webpack_require__(470); +/* harmony import */ var _internal_operators_skip__WEBPACK_IMPORTED_MODULE_73__ = __webpack_require__(468); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "skip", function() { return _internal_operators_skip__WEBPACK_IMPORTED_MODULE_73__["skip"]; }); -/* harmony import */ var _internal_operators_skipLast__WEBPACK_IMPORTED_MODULE_74__ = __webpack_require__(471); +/* harmony import */ var _internal_operators_skipLast__WEBPACK_IMPORTED_MODULE_74__ = __webpack_require__(469); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "skipLast", function() { return _internal_operators_skipLast__WEBPACK_IMPORTED_MODULE_74__["skipLast"]; }); -/* harmony import */ var _internal_operators_skipUntil__WEBPACK_IMPORTED_MODULE_75__ = __webpack_require__(472); +/* harmony import */ var _internal_operators_skipUntil__WEBPACK_IMPORTED_MODULE_75__ = __webpack_require__(470); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "skipUntil", function() { return _internal_operators_skipUntil__WEBPACK_IMPORTED_MODULE_75__["skipUntil"]; }); -/* harmony import */ var _internal_operators_skipWhile__WEBPACK_IMPORTED_MODULE_76__ = __webpack_require__(473); +/* harmony import */ var _internal_operators_skipWhile__WEBPACK_IMPORTED_MODULE_76__ = __webpack_require__(471); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "skipWhile", function() { return _internal_operators_skipWhile__WEBPACK_IMPORTED_MODULE_76__["skipWhile"]; }); -/* harmony import */ var _internal_operators_startWith__WEBPACK_IMPORTED_MODULE_77__ = __webpack_require__(474); +/* harmony import */ var _internal_operators_startWith__WEBPACK_IMPORTED_MODULE_77__ = __webpack_require__(472); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "startWith", function() { return _internal_operators_startWith__WEBPACK_IMPORTED_MODULE_77__["startWith"]; }); -/* harmony import */ var _internal_operators_subscribeOn__WEBPACK_IMPORTED_MODULE_78__ = __webpack_require__(475); +/* harmony import */ var _internal_operators_subscribeOn__WEBPACK_IMPORTED_MODULE_78__ = __webpack_require__(473); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "subscribeOn", function() { return _internal_operators_subscribeOn__WEBPACK_IMPORTED_MODULE_78__["subscribeOn"]; }); -/* harmony import */ var _internal_operators_switchAll__WEBPACK_IMPORTED_MODULE_79__ = __webpack_require__(477); +/* harmony import */ var _internal_operators_switchAll__WEBPACK_IMPORTED_MODULE_79__ = __webpack_require__(475); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "switchAll", function() { return _internal_operators_switchAll__WEBPACK_IMPORTED_MODULE_79__["switchAll"]; }); -/* harmony import */ var _internal_operators_switchMap__WEBPACK_IMPORTED_MODULE_80__ = __webpack_require__(478); +/* harmony import */ var _internal_operators_switchMap__WEBPACK_IMPORTED_MODULE_80__ = __webpack_require__(476); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "switchMap", function() { return _internal_operators_switchMap__WEBPACK_IMPORTED_MODULE_80__["switchMap"]; }); -/* harmony import */ var _internal_operators_switchMapTo__WEBPACK_IMPORTED_MODULE_81__ = __webpack_require__(479); +/* harmony import */ var _internal_operators_switchMapTo__WEBPACK_IMPORTED_MODULE_81__ = __webpack_require__(477); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "switchMapTo", function() { return _internal_operators_switchMapTo__WEBPACK_IMPORTED_MODULE_81__["switchMapTo"]; }); -/* harmony import */ var _internal_operators_take__WEBPACK_IMPORTED_MODULE_82__ = __webpack_require__(427); +/* harmony import */ var _internal_operators_take__WEBPACK_IMPORTED_MODULE_82__ = __webpack_require__(425); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "take", function() { return _internal_operators_take__WEBPACK_IMPORTED_MODULE_82__["take"]; }); -/* harmony import */ var _internal_operators_takeLast__WEBPACK_IMPORTED_MODULE_83__ = __webpack_require__(440); +/* harmony import */ var _internal_operators_takeLast__WEBPACK_IMPORTED_MODULE_83__ = __webpack_require__(438); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "takeLast", function() { return _internal_operators_takeLast__WEBPACK_IMPORTED_MODULE_83__["takeLast"]; }); -/* harmony import */ var _internal_operators_takeUntil__WEBPACK_IMPORTED_MODULE_84__ = __webpack_require__(480); +/* harmony import */ var _internal_operators_takeUntil__WEBPACK_IMPORTED_MODULE_84__ = __webpack_require__(478); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "takeUntil", function() { return _internal_operators_takeUntil__WEBPACK_IMPORTED_MODULE_84__["takeUntil"]; }); -/* harmony import */ var _internal_operators_takeWhile__WEBPACK_IMPORTED_MODULE_85__ = __webpack_require__(481); +/* harmony import */ var _internal_operators_takeWhile__WEBPACK_IMPORTED_MODULE_85__ = __webpack_require__(479); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "takeWhile", function() { return _internal_operators_takeWhile__WEBPACK_IMPORTED_MODULE_85__["takeWhile"]; }); -/* harmony import */ var _internal_operators_tap__WEBPACK_IMPORTED_MODULE_86__ = __webpack_require__(482); +/* harmony import */ var _internal_operators_tap__WEBPACK_IMPORTED_MODULE_86__ = __webpack_require__(480); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "tap", function() { return _internal_operators_tap__WEBPACK_IMPORTED_MODULE_86__["tap"]; }); -/* harmony import */ var _internal_operators_throttle__WEBPACK_IMPORTED_MODULE_87__ = __webpack_require__(483); +/* harmony import */ var _internal_operators_throttle__WEBPACK_IMPORTED_MODULE_87__ = __webpack_require__(481); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "throttle", function() { return _internal_operators_throttle__WEBPACK_IMPORTED_MODULE_87__["throttle"]; }); -/* harmony import */ var _internal_operators_throttleTime__WEBPACK_IMPORTED_MODULE_88__ = __webpack_require__(484); +/* harmony import */ var _internal_operators_throttleTime__WEBPACK_IMPORTED_MODULE_88__ = __webpack_require__(482); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "throttleTime", function() { return _internal_operators_throttleTime__WEBPACK_IMPORTED_MODULE_88__["throttleTime"]; }); -/* harmony import */ var _internal_operators_throwIfEmpty__WEBPACK_IMPORTED_MODULE_89__ = __webpack_require__(426); +/* harmony import */ var _internal_operators_throwIfEmpty__WEBPACK_IMPORTED_MODULE_89__ = __webpack_require__(424); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "throwIfEmpty", function() { return _internal_operators_throwIfEmpty__WEBPACK_IMPORTED_MODULE_89__["throwIfEmpty"]; }); -/* harmony import */ var _internal_operators_timeInterval__WEBPACK_IMPORTED_MODULE_90__ = __webpack_require__(485); +/* harmony import */ var _internal_operators_timeInterval__WEBPACK_IMPORTED_MODULE_90__ = __webpack_require__(483); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "timeInterval", function() { return _internal_operators_timeInterval__WEBPACK_IMPORTED_MODULE_90__["timeInterval"]; }); -/* harmony import */ var _internal_operators_timeout__WEBPACK_IMPORTED_MODULE_91__ = __webpack_require__(486); +/* harmony import */ var _internal_operators_timeout__WEBPACK_IMPORTED_MODULE_91__ = __webpack_require__(484); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "timeout", function() { return _internal_operators_timeout__WEBPACK_IMPORTED_MODULE_91__["timeout"]; }); -/* harmony import */ var _internal_operators_timeoutWith__WEBPACK_IMPORTED_MODULE_92__ = __webpack_require__(487); +/* harmony import */ var _internal_operators_timeoutWith__WEBPACK_IMPORTED_MODULE_92__ = __webpack_require__(485); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "timeoutWith", function() { return _internal_operators_timeoutWith__WEBPACK_IMPORTED_MODULE_92__["timeoutWith"]; }); -/* harmony import */ var _internal_operators_timestamp__WEBPACK_IMPORTED_MODULE_93__ = __webpack_require__(488); +/* harmony import */ var _internal_operators_timestamp__WEBPACK_IMPORTED_MODULE_93__ = __webpack_require__(486); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "timestamp", function() { return _internal_operators_timestamp__WEBPACK_IMPORTED_MODULE_93__["timestamp"]; }); -/* harmony import */ var _internal_operators_toArray__WEBPACK_IMPORTED_MODULE_94__ = __webpack_require__(489); +/* harmony import */ var _internal_operators_toArray__WEBPACK_IMPORTED_MODULE_94__ = __webpack_require__(487); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "toArray", function() { return _internal_operators_toArray__WEBPACK_IMPORTED_MODULE_94__["toArray"]; }); -/* harmony import */ var _internal_operators_window__WEBPACK_IMPORTED_MODULE_95__ = __webpack_require__(490); +/* harmony import */ var _internal_operators_window__WEBPACK_IMPORTED_MODULE_95__ = __webpack_require__(488); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "window", function() { return _internal_operators_window__WEBPACK_IMPORTED_MODULE_95__["window"]; }); -/* harmony import */ var _internal_operators_windowCount__WEBPACK_IMPORTED_MODULE_96__ = __webpack_require__(491); +/* harmony import */ var _internal_operators_windowCount__WEBPACK_IMPORTED_MODULE_96__ = __webpack_require__(489); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "windowCount", function() { return _internal_operators_windowCount__WEBPACK_IMPORTED_MODULE_96__["windowCount"]; }); -/* harmony import */ var _internal_operators_windowTime__WEBPACK_IMPORTED_MODULE_97__ = __webpack_require__(492); +/* harmony import */ var _internal_operators_windowTime__WEBPACK_IMPORTED_MODULE_97__ = __webpack_require__(490); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "windowTime", function() { return _internal_operators_windowTime__WEBPACK_IMPORTED_MODULE_97__["windowTime"]; }); -/* harmony import */ var _internal_operators_windowToggle__WEBPACK_IMPORTED_MODULE_98__ = __webpack_require__(493); +/* harmony import */ var _internal_operators_windowToggle__WEBPACK_IMPORTED_MODULE_98__ = __webpack_require__(491); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "windowToggle", function() { return _internal_operators_windowToggle__WEBPACK_IMPORTED_MODULE_98__["windowToggle"]; }); -/* harmony import */ var _internal_operators_windowWhen__WEBPACK_IMPORTED_MODULE_99__ = __webpack_require__(494); +/* harmony import */ var _internal_operators_windowWhen__WEBPACK_IMPORTED_MODULE_99__ = __webpack_require__(492); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "windowWhen", function() { return _internal_operators_windowWhen__WEBPACK_IMPORTED_MODULE_99__["windowWhen"]; }); -/* harmony import */ var _internal_operators_withLatestFrom__WEBPACK_IMPORTED_MODULE_100__ = __webpack_require__(495); +/* harmony import */ var _internal_operators_withLatestFrom__WEBPACK_IMPORTED_MODULE_100__ = __webpack_require__(493); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "withLatestFrom", function() { return _internal_operators_withLatestFrom__WEBPACK_IMPORTED_MODULE_100__["withLatestFrom"]; }); -/* harmony import */ var _internal_operators_zip__WEBPACK_IMPORTED_MODULE_101__ = __webpack_require__(496); +/* harmony import */ var _internal_operators_zip__WEBPACK_IMPORTED_MODULE_101__ = __webpack_require__(494); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "zip", function() { return _internal_operators_zip__WEBPACK_IMPORTED_MODULE_101__["zip"]; }); -/* harmony import */ var _internal_operators_zipAll__WEBPACK_IMPORTED_MODULE_102__ = __webpack_require__(497); +/* harmony import */ var _internal_operators_zipAll__WEBPACK_IMPORTED_MODULE_102__ = __webpack_require__(495); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "zipAll", function() { return _internal_operators_zipAll__WEBPACK_IMPORTED_MODULE_102__["zipAll"]; }); /** PURE_IMPORTS_START PURE_IMPORTS_END */ @@ -51703,7 +51558,7 @@ __webpack_require__.r(__webpack_exports__); /***/ }), -/* 401 */ +/* 399 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -51784,14 +51639,14 @@ var AuditSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 402 */ +/* 400 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "auditTime", function() { return auditTime; }); /* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(55); -/* harmony import */ var _audit__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(401); +/* harmony import */ var _audit__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(399); /* harmony import */ var _observable_timer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(107); /** PURE_IMPORTS_START _scheduler_async,_audit,_observable_timer PURE_IMPORTS_END */ @@ -51807,7 +51662,7 @@ function auditTime(duration, scheduler) { /***/ }), -/* 403 */ +/* 401 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -51856,7 +51711,7 @@ var BufferSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 404 */ +/* 402 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -51957,7 +51812,7 @@ var BufferSkipCountSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 405 */ +/* 403 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52118,7 +51973,7 @@ function dispatchBufferClose(arg) { /***/ }), -/* 406 */ +/* 404 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52238,7 +52093,7 @@ var BufferToggleSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 407 */ +/* 405 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52333,7 +52188,7 @@ var BufferWhenSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 408 */ +/* 406 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52397,7 +52252,7 @@ var CatchSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 409 */ +/* 407 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52413,7 +52268,7 @@ function combineAll(project) { /***/ }), -/* 410 */ +/* 408 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52445,7 +52300,7 @@ function combineLatest() { /***/ }), -/* 411 */ +/* 409 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52465,7 +52320,7 @@ function concat() { /***/ }), -/* 412 */ +/* 410 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52481,13 +52336,13 @@ function concatMap(project, resultSelector) { /***/ }), -/* 413 */ +/* 411 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "concatMapTo", function() { return concatMapTo; }); -/* harmony import */ var _concatMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(412); +/* harmony import */ var _concatMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(410); /** PURE_IMPORTS_START _concatMap PURE_IMPORTS_END */ function concatMapTo(innerObservable, resultSelector) { @@ -52497,7 +52352,7 @@ function concatMapTo(innerObservable, resultSelector) { /***/ }), -/* 414 */ +/* 412 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52562,7 +52417,7 @@ var CountSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 415 */ +/* 413 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52650,7 +52505,7 @@ var DebounceSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 416 */ +/* 414 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52726,7 +52581,7 @@ function dispatchNext(subscriber) { /***/ }), -/* 417 */ +/* 415 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52776,7 +52631,7 @@ var DefaultIfEmptySubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 418 */ +/* 416 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52784,7 +52639,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "delay", function() { return delay; }); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); /* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(55); -/* harmony import */ var _util_isDate__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(419); +/* harmony import */ var _util_isDate__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(417); /* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(11); /* harmony import */ var _Notification__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(42); /** PURE_IMPORTS_START tslib,_scheduler_async,_util_isDate,_Subscriber,_Notification PURE_IMPORTS_END */ @@ -52883,7 +52738,7 @@ var DelayMessage = /*@__PURE__*/ (function () { /***/ }), -/* 419 */ +/* 417 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52897,7 +52752,7 @@ function isDate(value) { /***/ }), -/* 420 */ +/* 418 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53043,7 +52898,7 @@ var SubscriptionDelaySubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 421 */ +/* 419 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53081,7 +52936,7 @@ var DeMaterializeSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 422 */ +/* 420 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53159,7 +53014,7 @@ var DistinctSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 423 */ +/* 421 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53230,13 +53085,13 @@ var DistinctUntilChangedSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 424 */ +/* 422 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "distinctUntilKeyChanged", function() { return distinctUntilKeyChanged; }); -/* harmony import */ var _distinctUntilChanged__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(423); +/* harmony import */ var _distinctUntilChanged__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(421); /** PURE_IMPORTS_START _distinctUntilChanged PURE_IMPORTS_END */ function distinctUntilKeyChanged(key, compare) { @@ -53246,7 +53101,7 @@ function distinctUntilKeyChanged(key, compare) { /***/ }), -/* 425 */ +/* 423 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53254,9 +53109,9 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "elementAt", function() { return elementAt; }); /* harmony import */ var _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(62); /* harmony import */ var _filter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(104); -/* harmony import */ var _throwIfEmpty__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(426); -/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(417); -/* harmony import */ var _take__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(427); +/* harmony import */ var _throwIfEmpty__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(424); +/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(415); +/* harmony import */ var _take__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(425); /** PURE_IMPORTS_START _util_ArgumentOutOfRangeError,_filter,_throwIfEmpty,_defaultIfEmpty,_take PURE_IMPORTS_END */ @@ -53278,7 +53133,7 @@ function elementAt(index, defaultValue) { /***/ }), -/* 426 */ +/* 424 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53344,7 +53199,7 @@ function defaultErrorFactory() { /***/ }), -/* 427 */ +/* 425 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53406,7 +53261,7 @@ var TakeSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 428 */ +/* 426 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53428,7 +53283,7 @@ function endWith() { /***/ }), -/* 429 */ +/* 427 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53490,7 +53345,7 @@ var EverySubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 430 */ +/* 428 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53547,7 +53402,7 @@ var SwitchFirstSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 431 */ +/* 429 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53647,7 +53502,7 @@ var ExhaustMapSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 432 */ +/* 430 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53766,7 +53621,7 @@ var ExpandSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 433 */ +/* 431 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53804,7 +53659,7 @@ var FinallySubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 434 */ +/* 432 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53876,13 +53731,13 @@ var FindValueSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 435 */ +/* 433 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "findIndex", function() { return findIndex; }); -/* harmony import */ var _operators_find__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(434); +/* harmony import */ var _operators_find__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(432); /** PURE_IMPORTS_START _operators_find PURE_IMPORTS_END */ function findIndex(predicate, thisArg) { @@ -53892,7 +53747,7 @@ function findIndex(predicate, thisArg) { /***/ }), -/* 436 */ +/* 434 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53900,9 +53755,9 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "first", function() { return first; }); /* harmony import */ var _util_EmptyError__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(63); /* harmony import */ var _filter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(104); -/* harmony import */ var _take__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(427); -/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(417); -/* harmony import */ var _throwIfEmpty__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(426); +/* harmony import */ var _take__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(425); +/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(415); +/* harmony import */ var _throwIfEmpty__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(424); /* harmony import */ var _util_identity__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(25); /** PURE_IMPORTS_START _util_EmptyError,_filter,_take,_defaultIfEmpty,_throwIfEmpty,_util_identity PURE_IMPORTS_END */ @@ -53919,7 +53774,7 @@ function first(predicate, defaultValue) { /***/ }), -/* 437 */ +/* 435 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53956,7 +53811,7 @@ var IgnoreElementsSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 438 */ +/* 436 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54000,7 +53855,7 @@ var IsEmptySubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 439 */ +/* 437 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54008,9 +53863,9 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "last", function() { return last; }); /* harmony import */ var _util_EmptyError__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(63); /* harmony import */ var _filter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(104); -/* harmony import */ var _takeLast__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(440); -/* harmony import */ var _throwIfEmpty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(426); -/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(417); +/* harmony import */ var _takeLast__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(438); +/* harmony import */ var _throwIfEmpty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(424); +/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(415); /* harmony import */ var _util_identity__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(25); /** PURE_IMPORTS_START _util_EmptyError,_filter,_takeLast,_throwIfEmpty,_defaultIfEmpty,_util_identity PURE_IMPORTS_END */ @@ -54027,7 +53882,7 @@ function last(predicate, defaultValue) { /***/ }), -/* 440 */ +/* 438 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54104,7 +53959,7 @@ var TakeLastSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 441 */ +/* 439 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54143,7 +53998,7 @@ var MapToSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 442 */ +/* 440 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54193,13 +54048,13 @@ var MaterializeSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 443 */ +/* 441 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "max", function() { return max; }); -/* harmony import */ var _reduce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(444); +/* harmony import */ var _reduce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(442); /** PURE_IMPORTS_START _reduce PURE_IMPORTS_END */ function max(comparer) { @@ -54212,15 +54067,15 @@ function max(comparer) { /***/ }), -/* 444 */ +/* 442 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "reduce", function() { return reduce; }); -/* harmony import */ var _scan__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(445); -/* harmony import */ var _takeLast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(440); -/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(417); +/* harmony import */ var _scan__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(443); +/* harmony import */ var _takeLast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(438); +/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(415); /* harmony import */ var _util_pipe__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(24); /** PURE_IMPORTS_START _scan,_takeLast,_defaultIfEmpty,_util_pipe PURE_IMPORTS_END */ @@ -54241,7 +54096,7 @@ function reduce(accumulator, seed) { /***/ }), -/* 445 */ +/* 443 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54323,7 +54178,7 @@ var ScanSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 446 */ +/* 444 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54343,7 +54198,7 @@ function merge() { /***/ }), -/* 447 */ +/* 445 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54368,7 +54223,7 @@ function mergeMapTo(innerObservable, resultSelector, concurrent) { /***/ }), -/* 448 */ +/* 446 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54483,13 +54338,13 @@ var MergeScanSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 449 */ +/* 447 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "min", function() { return min; }); -/* harmony import */ var _reduce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(444); +/* harmony import */ var _reduce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(442); /** PURE_IMPORTS_START _reduce PURE_IMPORTS_END */ function min(comparer) { @@ -54502,7 +54357,7 @@ function min(comparer) { /***/ }), -/* 450 */ +/* 448 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54551,7 +54406,7 @@ var MulticastOperator = /*@__PURE__*/ (function () { /***/ }), -/* 451 */ +/* 449 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54645,7 +54500,7 @@ var OnErrorResumeNextSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 452 */ +/* 450 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54693,7 +54548,7 @@ var PairwiseSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 453 */ +/* 451 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54716,7 +54571,7 @@ function partition(predicate, thisArg) { /***/ }), -/* 454 */ +/* 452 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54756,14 +54611,14 @@ function plucker(props, length) { /***/ }), -/* 455 */ +/* 453 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "publish", function() { return publish; }); /* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(27); -/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(450); +/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(448); /** PURE_IMPORTS_START _Subject,_multicast PURE_IMPORTS_END */ @@ -54776,14 +54631,14 @@ function publish(selector) { /***/ }), -/* 456 */ +/* 454 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "publishBehavior", function() { return publishBehavior; }); /* harmony import */ var _BehaviorSubject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(32); -/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(450); +/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(448); /** PURE_IMPORTS_START _BehaviorSubject,_multicast PURE_IMPORTS_END */ @@ -54794,14 +54649,14 @@ function publishBehavior(value) { /***/ }), -/* 457 */ +/* 455 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "publishLast", function() { return publishLast; }); /* harmony import */ var _AsyncSubject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(50); -/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(450); +/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(448); /** PURE_IMPORTS_START _AsyncSubject,_multicast PURE_IMPORTS_END */ @@ -54812,14 +54667,14 @@ function publishLast() { /***/ }), -/* 458 */ +/* 456 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "publishReplay", function() { return publishReplay; }); /* harmony import */ var _ReplaySubject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(33); -/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(450); +/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(448); /** PURE_IMPORTS_START _ReplaySubject,_multicast PURE_IMPORTS_END */ @@ -54835,7 +54690,7 @@ function publishReplay(bufferSize, windowTime, selectorOrScheduler, scheduler) { /***/ }), -/* 459 */ +/* 457 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54862,7 +54717,7 @@ function race() { /***/ }), -/* 460 */ +/* 458 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54927,7 +54782,7 @@ var RepeatSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 461 */ +/* 459 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55023,7 +54878,7 @@ var RepeatWhenSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 462 */ +/* 460 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55076,7 +54931,7 @@ var RetrySubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 463 */ +/* 461 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55164,7 +55019,7 @@ var RetryWhenSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 464 */ +/* 462 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55221,7 +55076,7 @@ var SampleSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 465 */ +/* 463 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55281,7 +55136,7 @@ function dispatchNotification(state) { /***/ }), -/* 466 */ +/* 464 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55404,13 +55259,13 @@ var SequenceEqualCompareToSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 467 */ +/* 465 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "share", function() { return share; }); -/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(450); +/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(448); /* harmony import */ var _refCount__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(30); /* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(27); /** PURE_IMPORTS_START _multicast,_refCount,_Subject PURE_IMPORTS_END */ @@ -55427,7 +55282,7 @@ function share() { /***/ }), -/* 468 */ +/* 466 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55492,7 +55347,7 @@ function shareReplayOperator(_a) { /***/ }), -/* 469 */ +/* 467 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55572,7 +55427,7 @@ var SingleSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 470 */ +/* 468 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55614,7 +55469,7 @@ var SkipSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 471 */ +/* 469 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55676,7 +55531,7 @@ var SkipLastSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 472 */ +/* 470 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55737,7 +55592,7 @@ var SkipUntilSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 473 */ +/* 471 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55793,7 +55648,7 @@ var SkipWhileSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 474 */ +/* 472 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55822,13 +55677,13 @@ function startWith() { /***/ }), -/* 475 */ +/* 473 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "subscribeOn", function() { return subscribeOn; }); -/* harmony import */ var _observable_SubscribeOnObservable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(476); +/* harmony import */ var _observable_SubscribeOnObservable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(474); /** PURE_IMPORTS_START _observable_SubscribeOnObservable PURE_IMPORTS_END */ function subscribeOn(scheduler, delay) { @@ -55853,7 +55708,7 @@ var SubscribeOnOperator = /*@__PURE__*/ (function () { /***/ }), -/* 476 */ +/* 474 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55917,13 +55772,13 @@ var SubscribeOnObservable = /*@__PURE__*/ (function (_super) { /***/ }), -/* 477 */ +/* 475 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "switchAll", function() { return switchAll; }); -/* harmony import */ var _switchMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(478); +/* harmony import */ var _switchMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(476); /* harmony import */ var _util_identity__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(25); /** PURE_IMPORTS_START _switchMap,_util_identity PURE_IMPORTS_END */ @@ -55935,7 +55790,7 @@ function switchAll() { /***/ }), -/* 478 */ +/* 476 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56029,13 +55884,13 @@ var SwitchMapSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 479 */ +/* 477 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "switchMapTo", function() { return switchMapTo; }); -/* harmony import */ var _switchMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(478); +/* harmony import */ var _switchMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(476); /** PURE_IMPORTS_START _switchMap PURE_IMPORTS_END */ function switchMapTo(innerObservable, resultSelector) { @@ -56045,7 +55900,7 @@ function switchMapTo(innerObservable, resultSelector) { /***/ }), -/* 480 */ +/* 478 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56095,7 +55950,7 @@ var TakeUntilSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 481 */ +/* 479 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56163,7 +56018,7 @@ var TakeWhileSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 482 */ +/* 480 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56251,7 +56106,7 @@ var TapSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 483 */ +/* 481 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56355,7 +56210,7 @@ var ThrottleSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 484 */ +/* 482 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56364,7 +56219,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); /* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11); /* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(55); -/* harmony import */ var _throttle__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(483); +/* harmony import */ var _throttle__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(481); /** PURE_IMPORTS_START tslib,_Subscriber,_scheduler_async,_throttle PURE_IMPORTS_END */ @@ -56453,7 +56308,7 @@ function dispatchNext(arg) { /***/ }), -/* 485 */ +/* 483 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56461,7 +56316,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "timeInterval", function() { return timeInterval; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TimeInterval", function() { return TimeInterval; }); /* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(55); -/* harmony import */ var _scan__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(445); +/* harmony import */ var _scan__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(443); /* harmony import */ var _observable_defer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(90); /* harmony import */ var _map__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(66); /** PURE_IMPORTS_START _scheduler_async,_scan,_observable_defer,_map PURE_IMPORTS_END */ @@ -56497,7 +56352,7 @@ var TimeInterval = /*@__PURE__*/ (function () { /***/ }), -/* 486 */ +/* 484 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56505,7 +56360,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "timeout", function() { return timeout; }); /* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(55); /* harmony import */ var _util_TimeoutError__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(64); -/* harmony import */ var _timeoutWith__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(487); +/* harmony import */ var _timeoutWith__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(485); /* harmony import */ var _observable_throwError__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(49); /** PURE_IMPORTS_START _scheduler_async,_util_TimeoutError,_timeoutWith,_observable_throwError PURE_IMPORTS_END */ @@ -56522,7 +56377,7 @@ function timeout(due, scheduler) { /***/ }), -/* 487 */ +/* 485 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56530,7 +56385,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "timeoutWith", function() { return timeoutWith; }); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); /* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(55); -/* harmony import */ var _util_isDate__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(419); +/* harmony import */ var _util_isDate__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(417); /* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(69); /* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(70); /** PURE_IMPORTS_START tslib,_scheduler_async,_util_isDate,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ @@ -56604,7 +56459,7 @@ var TimeoutWithSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 488 */ +/* 486 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56634,13 +56489,13 @@ var Timestamp = /*@__PURE__*/ (function () { /***/ }), -/* 489 */ +/* 487 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "toArray", function() { return toArray; }); -/* harmony import */ var _reduce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(444); +/* harmony import */ var _reduce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(442); /** PURE_IMPORTS_START _reduce PURE_IMPORTS_END */ function toArrayReducer(arr, item, index) { @@ -56657,7 +56512,7 @@ function toArray() { /***/ }), -/* 490 */ +/* 488 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56737,7 +56592,7 @@ var WindowSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 491 */ +/* 489 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56827,7 +56682,7 @@ var WindowCountSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 492 */ +/* 490 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56997,7 +56852,7 @@ function dispatchWindowClose(state) { /***/ }), -/* 493 */ +/* 491 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -57140,7 +56995,7 @@ var WindowToggleSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 494 */ +/* 492 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -57237,7 +57092,7 @@ var WindowSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 495 */ +/* 493 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -57332,7 +57187,7 @@ var WithLatestFromSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 496 */ +/* 494 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -57354,7 +57209,7 @@ function zip() { /***/ }), -/* 497 */ +/* 495 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -57370,7 +57225,7 @@ function zipAll(project) { /***/ }), -/* 498 */ +/* 496 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -57379,8 +57234,8 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _utils_errors__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(162); /* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); /* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(145); -/* harmony import */ var _utils_projects_tree__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(499); -/* harmony import */ var _utils_kibana__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(500); +/* harmony import */ var _utils_projects_tree__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(497); +/* harmony import */ var _utils_kibana__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(498); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } @@ -57462,13 +57317,13 @@ function toArray(value) { } /***/ }), -/* 499 */ +/* 497 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "renderProjectsTree", function() { return renderProjectsTree; }); -/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(235); +/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(227); /* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(chalk__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_1__); @@ -57615,7 +57470,7 @@ function addProjectToTree(tree, pathParts, project) { } /***/ }), -/* 500 */ +/* 498 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -57623,12 +57478,12 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Kibana", function() { return Kibana; }); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var multimatch__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(501); +/* harmony import */ var multimatch__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(499); /* harmony import */ var multimatch__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(multimatch__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var is_path_inside__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(377); +/* harmony import */ var is_path_inside__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(369); /* harmony import */ var is_path_inside__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(is_path_inside__WEBPACK_IMPORTED_MODULE_2__); /* harmony import */ var _projects__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(145); -/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(288); +/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(280); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } @@ -57769,15 +57624,15 @@ class Kibana { } /***/ }), -/* 501 */ +/* 499 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const minimatch = __webpack_require__(149); -const arrayUnion = __webpack_require__(502); -const arrayDiffer = __webpack_require__(503); -const arrify = __webpack_require__(504); +const arrayUnion = __webpack_require__(500); +const arrayDiffer = __webpack_require__(501); +const arrify = __webpack_require__(502); module.exports = (list, patterns, options = {}) => { list = arrify(list); @@ -57801,7 +57656,7 @@ module.exports = (list, patterns, options = {}) => { /***/ }), -/* 502 */ +/* 500 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -57813,7 +57668,7 @@ module.exports = (...arguments_) => { /***/ }), -/* 503 */ +/* 501 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -57828,7 +57683,7 @@ module.exports = arrayDiffer; /***/ }), -/* 504 */ +/* 502 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -57858,12 +57713,12 @@ module.exports = arrify; /***/ }), -/* 505 */ +/* 503 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony import */ var _build_production_projects__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(506); +/* harmony import */ var _build_production_projects__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(504); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "buildProductionProjects", function() { return _build_production_projects__WEBPACK_IMPORTED_MODULE_0__["buildProductionProjects"]; }); /* @@ -57887,19 +57742,19 @@ __webpack_require__.r(__webpack_exports__); /***/ }), -/* 506 */ +/* 504 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "buildProductionProjects", function() { return buildProductionProjects; }); -/* harmony import */ var cpy__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(507); +/* harmony import */ var cpy__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(505); /* harmony import */ var cpy__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(cpy__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var del__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(296); +/* harmony import */ var del__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(288); /* harmony import */ var del__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(del__WEBPACK_IMPORTED_MODULE_1__); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(288); +/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(280); /* harmony import */ var _utils_fs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(130); /* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(143); /* harmony import */ var _utils_package_json__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(164); @@ -58035,7 +57890,7 @@ async function copyToBuild(project, kibanaRoot, buildRoot) { } /***/ }), -/* 507 */ +/* 505 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -58043,13 +57898,13 @@ async function copyToBuild(project, kibanaRoot, buildRoot) { const EventEmitter = __webpack_require__(155); const path = __webpack_require__(4); const os = __webpack_require__(120); -const pAll = __webpack_require__(508); -const arrify = __webpack_require__(510); -const globby = __webpack_require__(511); -const isGlob = __webpack_require__(721); -const cpFile = __webpack_require__(722); -const junk = __webpack_require__(734); -const CpyError = __webpack_require__(735); +const pAll = __webpack_require__(506); +const arrify = __webpack_require__(508); +const globby = __webpack_require__(509); +const isGlob = __webpack_require__(719); +const cpFile = __webpack_require__(720); +const junk = __webpack_require__(732); +const CpyError = __webpack_require__(733); const defaultOptions = { ignoreJunk: true @@ -58168,12 +58023,12 @@ module.exports = (source, destination, { /***/ }), -/* 508 */ +/* 506 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const pMap = __webpack_require__(509); +const pMap = __webpack_require__(507); module.exports = (iterable, options) => pMap(iterable, element => element(), options); // TODO: Remove this for the next major release @@ -58181,7 +58036,7 @@ module.exports.default = module.exports; /***/ }), -/* 509 */ +/* 507 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -58260,7 +58115,7 @@ module.exports.default = pMap; /***/ }), -/* 510 */ +/* 508 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -58290,17 +58145,17 @@ module.exports = arrify; /***/ }), -/* 511 */ +/* 509 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const fs = __webpack_require__(133); -const arrayUnion = __webpack_require__(512); +const arrayUnion = __webpack_require__(510); const glob = __webpack_require__(146); -const fastGlob = __webpack_require__(514); -const dirGlob = __webpack_require__(714); -const gitignore = __webpack_require__(717); +const fastGlob = __webpack_require__(512); +const dirGlob = __webpack_require__(712); +const gitignore = __webpack_require__(715); const DEFAULT_FILTER = () => false; @@ -58445,12 +58300,12 @@ module.exports.gitignore = gitignore; /***/ }), -/* 512 */ +/* 510 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var arrayUniq = __webpack_require__(513); +var arrayUniq = __webpack_require__(511); module.exports = function () { return arrayUniq([].concat.apply([], arguments)); @@ -58458,7 +58313,7 @@ module.exports = function () { /***/ }), -/* 513 */ +/* 511 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -58527,10 +58382,10 @@ if ('Set' in global) { /***/ }), -/* 514 */ +/* 512 */ /***/ (function(module, exports, __webpack_require__) { -const pkg = __webpack_require__(515); +const pkg = __webpack_require__(513); module.exports = pkg.async; module.exports.default = pkg.async; @@ -58543,19 +58398,19 @@ module.exports.generateTasks = pkg.generateTasks; /***/ }), -/* 515 */ +/* 513 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var optionsManager = __webpack_require__(516); -var taskManager = __webpack_require__(517); -var reader_async_1 = __webpack_require__(685); -var reader_stream_1 = __webpack_require__(709); -var reader_sync_1 = __webpack_require__(710); -var arrayUtils = __webpack_require__(712); -var streamUtils = __webpack_require__(713); +var optionsManager = __webpack_require__(514); +var taskManager = __webpack_require__(515); +var reader_async_1 = __webpack_require__(683); +var reader_stream_1 = __webpack_require__(707); +var reader_sync_1 = __webpack_require__(708); +var arrayUtils = __webpack_require__(710); +var streamUtils = __webpack_require__(711); /** * Synchronous API. */ @@ -58621,7 +58476,7 @@ function isString(source) { /***/ }), -/* 516 */ +/* 514 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -58659,13 +58514,13 @@ exports.prepare = prepare; /***/ }), -/* 517 */ +/* 515 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var patternUtils = __webpack_require__(518); +var patternUtils = __webpack_require__(516); /** * Generate tasks based on parent directory of each pattern. */ @@ -58756,16 +58611,16 @@ exports.convertPatternGroupToTask = convertPatternGroupToTask; /***/ }), -/* 518 */ +/* 516 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var path = __webpack_require__(4); -var globParent = __webpack_require__(519); -var isGlob = __webpack_require__(522); -var micromatch = __webpack_require__(523); +var globParent = __webpack_require__(517); +var isGlob = __webpack_require__(520); +var micromatch = __webpack_require__(521); var GLOBSTAR = '**'; /** * Return true for static pattern. @@ -58911,15 +58766,15 @@ exports.matchAny = matchAny; /***/ }), -/* 519 */ +/* 517 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var path = __webpack_require__(4); -var isglob = __webpack_require__(520); -var pathDirname = __webpack_require__(521); +var isglob = __webpack_require__(518); +var pathDirname = __webpack_require__(519); var isWin32 = __webpack_require__(120).platform() === 'win32'; module.exports = function globParent(str) { @@ -58942,7 +58797,7 @@ module.exports = function globParent(str) { /***/ }), -/* 520 */ +/* 518 */ /***/ (function(module, exports, __webpack_require__) { /*! @@ -58952,7 +58807,7 @@ module.exports = function globParent(str) { * Licensed under the MIT License. */ -var isExtglob = __webpack_require__(310); +var isExtglob = __webpack_require__(302); module.exports = function isGlob(str) { if (typeof str !== 'string' || str === '') { @@ -58973,7 +58828,7 @@ module.exports = function isGlob(str) { /***/ }), -/* 521 */ +/* 519 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -59123,7 +58978,7 @@ module.exports.win32 = win32; /***/ }), -/* 522 */ +/* 520 */ /***/ (function(module, exports, __webpack_require__) { /*! @@ -59133,7 +58988,7 @@ module.exports.win32 = win32; * Released under the MIT License. */ -var isExtglob = __webpack_require__(310); +var isExtglob = __webpack_require__(302); var chars = { '{': '}', '(': ')', '[': ']'}; module.exports = function isGlob(str, options) { @@ -59175,7 +59030,7 @@ module.exports = function isGlob(str, options) { /***/ }), -/* 523 */ +/* 521 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -59186,18 +59041,18 @@ module.exports = function isGlob(str, options) { */ var util = __webpack_require__(111); -var braces = __webpack_require__(524); -var toRegex = __webpack_require__(637); -var extend = __webpack_require__(645); +var braces = __webpack_require__(522); +var toRegex = __webpack_require__(635); +var extend = __webpack_require__(643); /** * Local dependencies */ -var compilers = __webpack_require__(648); -var parsers = __webpack_require__(681); -var cache = __webpack_require__(682); -var utils = __webpack_require__(683); +var compilers = __webpack_require__(646); +var parsers = __webpack_require__(679); +var cache = __webpack_require__(680); +var utils = __webpack_require__(681); var MAX_LENGTH = 1024 * 64; /** @@ -60059,7 +59914,7 @@ module.exports = micromatch; /***/ }), -/* 524 */ +/* 522 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -60069,18 +59924,18 @@ module.exports = micromatch; * Module dependencies */ -var toRegex = __webpack_require__(525); -var unique = __webpack_require__(539); -var extend = __webpack_require__(534); +var toRegex = __webpack_require__(523); +var unique = __webpack_require__(537); +var extend = __webpack_require__(532); /** * Local dependencies */ -var compilers = __webpack_require__(540); -var parsers = __webpack_require__(557); -var Braces = __webpack_require__(567); -var utils = __webpack_require__(541); +var compilers = __webpack_require__(538); +var parsers = __webpack_require__(555); +var Braces = __webpack_require__(565); +var utils = __webpack_require__(539); var MAX_LENGTH = 1024 * 64; var cache = {}; @@ -60384,15 +60239,15 @@ module.exports = braces; /***/ }), -/* 525 */ +/* 523 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var define = __webpack_require__(526); -var extend = __webpack_require__(534); -var not = __webpack_require__(536); +var define = __webpack_require__(524); +var extend = __webpack_require__(532); +var not = __webpack_require__(534); var MAX_LENGTH = 1024 * 64; /** @@ -60539,7 +60394,7 @@ module.exports.makeRe = makeRe; /***/ }), -/* 526 */ +/* 524 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -60552,7 +60407,7 @@ module.exports.makeRe = makeRe; -var isDescriptor = __webpack_require__(527); +var isDescriptor = __webpack_require__(525); module.exports = function defineProperty(obj, prop, val) { if (typeof obj !== 'object' && typeof obj !== 'function') { @@ -60577,7 +60432,7 @@ module.exports = function defineProperty(obj, prop, val) { /***/ }), -/* 527 */ +/* 525 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -60590,9 +60445,9 @@ module.exports = function defineProperty(obj, prop, val) { -var typeOf = __webpack_require__(528); -var isAccessor = __webpack_require__(529); -var isData = __webpack_require__(532); +var typeOf = __webpack_require__(526); +var isAccessor = __webpack_require__(527); +var isData = __webpack_require__(530); module.exports = function isDescriptor(obj, key) { if (typeOf(obj) !== 'object') { @@ -60606,7 +60461,7 @@ module.exports = function isDescriptor(obj, key) { /***/ }), -/* 528 */ +/* 526 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -60759,7 +60614,7 @@ function isBuffer(val) { /***/ }), -/* 529 */ +/* 527 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -60772,7 +60627,7 @@ function isBuffer(val) { -var typeOf = __webpack_require__(530); +var typeOf = __webpack_require__(528); // accessor descriptor properties var accessor = { @@ -60835,10 +60690,10 @@ module.exports = isAccessorDescriptor; /***/ }), -/* 530 */ +/* 528 */ /***/ (function(module, exports, __webpack_require__) { -var isBuffer = __webpack_require__(531); +var isBuffer = __webpack_require__(529); var toString = Object.prototype.toString; /** @@ -60957,7 +60812,7 @@ module.exports = function kindOf(val) { /***/ }), -/* 531 */ +/* 529 */ /***/ (function(module, exports) { /*! @@ -60984,7 +60839,7 @@ function isSlowBuffer (obj) { /***/ }), -/* 532 */ +/* 530 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -60997,7 +60852,7 @@ function isSlowBuffer (obj) { -var typeOf = __webpack_require__(533); +var typeOf = __webpack_require__(531); // data descriptor properties var data = { @@ -61046,10 +60901,10 @@ module.exports = isDataDescriptor; /***/ }), -/* 533 */ +/* 531 */ /***/ (function(module, exports, __webpack_require__) { -var isBuffer = __webpack_require__(531); +var isBuffer = __webpack_require__(529); var toString = Object.prototype.toString; /** @@ -61168,13 +61023,13 @@ module.exports = function kindOf(val) { /***/ }), -/* 534 */ +/* 532 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isObject = __webpack_require__(535); +var isObject = __webpack_require__(533); module.exports = function extend(o/*, objects*/) { if (!isObject(o)) { o = {}; } @@ -61208,7 +61063,7 @@ function hasOwn(obj, key) { /***/ }), -/* 535 */ +/* 533 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -61228,13 +61083,13 @@ module.exports = function isExtendable(val) { /***/ }), -/* 536 */ +/* 534 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var extend = __webpack_require__(537); +var extend = __webpack_require__(535); /** * The main export is a function that takes a `pattern` string and an `options` object. @@ -61301,13 +61156,13 @@ module.exports = toRegex; /***/ }), -/* 537 */ +/* 535 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isObject = __webpack_require__(538); +var isObject = __webpack_require__(536); module.exports = function extend(o/*, objects*/) { if (!isObject(o)) { o = {}; } @@ -61341,7 +61196,7 @@ function hasOwn(obj, key) { /***/ }), -/* 538 */ +/* 536 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -61361,7 +61216,7 @@ module.exports = function isExtendable(val) { /***/ }), -/* 539 */ +/* 537 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -61411,13 +61266,13 @@ module.exports.immutable = function uniqueImmutable(arr) { /***/ }), -/* 540 */ +/* 538 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var utils = __webpack_require__(541); +var utils = __webpack_require__(539); module.exports = function(braces, options) { braces.compiler @@ -61700,25 +61555,25 @@ function hasQueue(node) { /***/ }), -/* 541 */ +/* 539 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var splitString = __webpack_require__(542); +var splitString = __webpack_require__(540); var utils = module.exports; /** * Module dependencies */ -utils.extend = __webpack_require__(534); -utils.flatten = __webpack_require__(548); -utils.isObject = __webpack_require__(546); -utils.fillRange = __webpack_require__(549); -utils.repeat = __webpack_require__(556); -utils.unique = __webpack_require__(539); +utils.extend = __webpack_require__(532); +utils.flatten = __webpack_require__(546); +utils.isObject = __webpack_require__(544); +utils.fillRange = __webpack_require__(547); +utils.repeat = __webpack_require__(554); +utils.unique = __webpack_require__(537); utils.define = function(obj, key, val) { Object.defineProperty(obj, key, { @@ -62050,7 +61905,7 @@ utils.escapeRegex = function(str) { /***/ }), -/* 542 */ +/* 540 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62063,7 +61918,7 @@ utils.escapeRegex = function(str) { -var extend = __webpack_require__(543); +var extend = __webpack_require__(541); module.exports = function(str, options, fn) { if (typeof str !== 'string') { @@ -62228,14 +62083,14 @@ function keepEscaping(opts, str, idx) { /***/ }), -/* 543 */ +/* 541 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isExtendable = __webpack_require__(544); -var assignSymbols = __webpack_require__(547); +var isExtendable = __webpack_require__(542); +var assignSymbols = __webpack_require__(545); module.exports = Object.assign || function(obj/*, objects*/) { if (obj === null || typeof obj === 'undefined') { @@ -62295,7 +62150,7 @@ function isEnum(obj, key) { /***/ }), -/* 544 */ +/* 542 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62308,7 +62163,7 @@ function isEnum(obj, key) { -var isPlainObject = __webpack_require__(545); +var isPlainObject = __webpack_require__(543); module.exports = function isExtendable(val) { return isPlainObject(val) || typeof val === 'function' || Array.isArray(val); @@ -62316,7 +62171,7 @@ module.exports = function isExtendable(val) { /***/ }), -/* 545 */ +/* 543 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62329,7 +62184,7 @@ module.exports = function isExtendable(val) { -var isObject = __webpack_require__(546); +var isObject = __webpack_require__(544); function isObjectObject(o) { return isObject(o) === true @@ -62360,7 +62215,7 @@ module.exports = function isPlainObject(o) { /***/ }), -/* 546 */ +/* 544 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62379,7 +62234,7 @@ module.exports = function isObject(val) { /***/ }), -/* 547 */ +/* 545 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62426,7 +62281,7 @@ module.exports = function(receiver, objects) { /***/ }), -/* 548 */ +/* 546 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62455,7 +62310,7 @@ function flat(arr, res) { /***/ }), -/* 549 */ +/* 547 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62469,10 +62324,10 @@ function flat(arr, res) { var util = __webpack_require__(111); -var isNumber = __webpack_require__(550); -var extend = __webpack_require__(552); -var repeat = __webpack_require__(554); -var toRegex = __webpack_require__(555); +var isNumber = __webpack_require__(548); +var extend = __webpack_require__(550); +var repeat = __webpack_require__(552); +var toRegex = __webpack_require__(553); /** * Return a range of numbers or letters. @@ -62670,7 +62525,7 @@ module.exports = fillRange; /***/ }), -/* 550 */ +/* 548 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62683,7 +62538,7 @@ module.exports = fillRange; -var typeOf = __webpack_require__(551); +var typeOf = __webpack_require__(549); module.exports = function isNumber(num) { var type = typeOf(num); @@ -62699,10 +62554,10 @@ module.exports = function isNumber(num) { /***/ }), -/* 551 */ +/* 549 */ /***/ (function(module, exports, __webpack_require__) { -var isBuffer = __webpack_require__(531); +var isBuffer = __webpack_require__(529); var toString = Object.prototype.toString; /** @@ -62821,13 +62676,13 @@ module.exports = function kindOf(val) { /***/ }), -/* 552 */ +/* 550 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isObject = __webpack_require__(553); +var isObject = __webpack_require__(551); module.exports = function extend(o/*, objects*/) { if (!isObject(o)) { o = {}; } @@ -62861,7 +62716,7 @@ function hasOwn(obj, key) { /***/ }), -/* 553 */ +/* 551 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62881,7 +62736,7 @@ module.exports = function isExtendable(val) { /***/ }), -/* 554 */ +/* 552 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62958,7 +62813,7 @@ function repeat(str, num) { /***/ }), -/* 555 */ +/* 553 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62971,8 +62826,8 @@ function repeat(str, num) { -var repeat = __webpack_require__(554); -var isNumber = __webpack_require__(550); +var repeat = __webpack_require__(552); +var isNumber = __webpack_require__(548); var cache = {}; function toRegexRange(min, max, options) { @@ -63259,7 +63114,7 @@ module.exports = toRegexRange; /***/ }), -/* 556 */ +/* 554 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -63284,14 +63139,14 @@ module.exports = function repeat(ele, num) { /***/ }), -/* 557 */ +/* 555 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var Node = __webpack_require__(558); -var utils = __webpack_require__(541); +var Node = __webpack_require__(556); +var utils = __webpack_require__(539); /** * Braces parsers @@ -63651,15 +63506,15 @@ function concatNodes(pos, node, parent, options) { /***/ }), -/* 558 */ +/* 556 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isObject = __webpack_require__(546); -var define = __webpack_require__(559); -var utils = __webpack_require__(566); +var isObject = __webpack_require__(544); +var define = __webpack_require__(557); +var utils = __webpack_require__(564); var ownNames; /** @@ -64150,7 +64005,7 @@ exports = module.exports = Node; /***/ }), -/* 559 */ +/* 557 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -64163,7 +64018,7 @@ exports = module.exports = Node; -var isDescriptor = __webpack_require__(560); +var isDescriptor = __webpack_require__(558); module.exports = function defineProperty(obj, prop, val) { if (typeof obj !== 'object' && typeof obj !== 'function') { @@ -64188,7 +64043,7 @@ module.exports = function defineProperty(obj, prop, val) { /***/ }), -/* 560 */ +/* 558 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -64201,9 +64056,9 @@ module.exports = function defineProperty(obj, prop, val) { -var typeOf = __webpack_require__(561); -var isAccessor = __webpack_require__(562); -var isData = __webpack_require__(564); +var typeOf = __webpack_require__(559); +var isAccessor = __webpack_require__(560); +var isData = __webpack_require__(562); module.exports = function isDescriptor(obj, key) { if (typeOf(obj) !== 'object') { @@ -64217,7 +64072,7 @@ module.exports = function isDescriptor(obj, key) { /***/ }), -/* 561 */ +/* 559 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -64352,7 +64207,7 @@ function isBuffer(val) { /***/ }), -/* 562 */ +/* 560 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -64365,7 +64220,7 @@ function isBuffer(val) { -var typeOf = __webpack_require__(563); +var typeOf = __webpack_require__(561); // accessor descriptor properties var accessor = { @@ -64428,7 +64283,7 @@ module.exports = isAccessorDescriptor; /***/ }), -/* 563 */ +/* 561 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -64563,7 +64418,7 @@ function isBuffer(val) { /***/ }), -/* 564 */ +/* 562 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -64576,7 +64431,7 @@ function isBuffer(val) { -var typeOf = __webpack_require__(565); +var typeOf = __webpack_require__(563); module.exports = function isDataDescriptor(obj, prop) { // data descriptor properties @@ -64619,7 +64474,7 @@ module.exports = function isDataDescriptor(obj, prop) { /***/ }), -/* 565 */ +/* 563 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -64754,13 +64609,13 @@ function isBuffer(val) { /***/ }), -/* 566 */ +/* 564 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var typeOf = __webpack_require__(551); +var typeOf = __webpack_require__(549); var utils = module.exports; /** @@ -65780,17 +65635,17 @@ function assert(val, message) { /***/ }), -/* 567 */ +/* 565 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var extend = __webpack_require__(534); -var Snapdragon = __webpack_require__(568); -var compilers = __webpack_require__(540); -var parsers = __webpack_require__(557); -var utils = __webpack_require__(541); +var extend = __webpack_require__(532); +var Snapdragon = __webpack_require__(566); +var compilers = __webpack_require__(538); +var parsers = __webpack_require__(555); +var utils = __webpack_require__(539); /** * Customize Snapdragon parser and renderer @@ -65891,17 +65746,17 @@ module.exports = Braces; /***/ }), -/* 568 */ +/* 566 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var Base = __webpack_require__(569); -var define = __webpack_require__(595); -var Compiler = __webpack_require__(605); -var Parser = __webpack_require__(634); -var utils = __webpack_require__(614); +var Base = __webpack_require__(567); +var define = __webpack_require__(593); +var Compiler = __webpack_require__(603); +var Parser = __webpack_require__(632); +var utils = __webpack_require__(612); var regexCache = {}; var cache = {}; @@ -66072,20 +65927,20 @@ module.exports.Parser = Parser; /***/ }), -/* 569 */ +/* 567 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var util = __webpack_require__(111); -var define = __webpack_require__(570); -var CacheBase = __webpack_require__(571); -var Emitter = __webpack_require__(572); -var isObject = __webpack_require__(546); -var merge = __webpack_require__(589); -var pascal = __webpack_require__(592); -var cu = __webpack_require__(593); +var define = __webpack_require__(568); +var CacheBase = __webpack_require__(569); +var Emitter = __webpack_require__(570); +var isObject = __webpack_require__(544); +var merge = __webpack_require__(587); +var pascal = __webpack_require__(590); +var cu = __webpack_require__(591); /** * Optionally define a custom `cache` namespace to use. @@ -66514,7 +66369,7 @@ module.exports.namespace = namespace; /***/ }), -/* 570 */ +/* 568 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -66527,7 +66382,7 @@ module.exports.namespace = namespace; -var isDescriptor = __webpack_require__(560); +var isDescriptor = __webpack_require__(558); module.exports = function defineProperty(obj, prop, val) { if (typeof obj !== 'object' && typeof obj !== 'function') { @@ -66552,21 +66407,21 @@ module.exports = function defineProperty(obj, prop, val) { /***/ }), -/* 571 */ +/* 569 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isObject = __webpack_require__(546); -var Emitter = __webpack_require__(572); -var visit = __webpack_require__(573); -var toPath = __webpack_require__(576); -var union = __webpack_require__(577); -var del = __webpack_require__(581); -var get = __webpack_require__(579); -var has = __webpack_require__(586); -var set = __webpack_require__(580); +var isObject = __webpack_require__(544); +var Emitter = __webpack_require__(570); +var visit = __webpack_require__(571); +var toPath = __webpack_require__(574); +var union = __webpack_require__(575); +var del = __webpack_require__(579); +var get = __webpack_require__(577); +var has = __webpack_require__(584); +var set = __webpack_require__(578); /** * Create a `Cache` constructor that when instantiated will @@ -66820,7 +66675,7 @@ module.exports.namespace = namespace; /***/ }), -/* 572 */ +/* 570 */ /***/ (function(module, exports, __webpack_require__) { @@ -66989,7 +66844,7 @@ Emitter.prototype.hasListeners = function(event){ /***/ }), -/* 573 */ +/* 571 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67002,8 +66857,8 @@ Emitter.prototype.hasListeners = function(event){ -var visit = __webpack_require__(574); -var mapVisit = __webpack_require__(575); +var visit = __webpack_require__(572); +var mapVisit = __webpack_require__(573); module.exports = function(collection, method, val) { var result; @@ -67026,7 +66881,7 @@ module.exports = function(collection, method, val) { /***/ }), -/* 574 */ +/* 572 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67039,7 +66894,7 @@ module.exports = function(collection, method, val) { -var isObject = __webpack_require__(546); +var isObject = __webpack_require__(544); module.exports = function visit(thisArg, method, target, val) { if (!isObject(thisArg) && typeof thisArg !== 'function') { @@ -67066,14 +66921,14 @@ module.exports = function visit(thisArg, method, target, val) { /***/ }), -/* 575 */ +/* 573 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var util = __webpack_require__(111); -var visit = __webpack_require__(574); +var visit = __webpack_require__(572); /** * Map `visit` over an array of objects. @@ -67110,7 +66965,7 @@ function isObject(val) { /***/ }), -/* 576 */ +/* 574 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67123,7 +66978,7 @@ function isObject(val) { -var typeOf = __webpack_require__(551); +var typeOf = __webpack_require__(549); module.exports = function toPath(args) { if (typeOf(args) !== 'arguments') { @@ -67150,16 +67005,16 @@ function filter(arr) { /***/ }), -/* 577 */ +/* 575 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isObject = __webpack_require__(538); -var union = __webpack_require__(578); -var get = __webpack_require__(579); -var set = __webpack_require__(580); +var isObject = __webpack_require__(536); +var union = __webpack_require__(576); +var get = __webpack_require__(577); +var set = __webpack_require__(578); module.exports = function unionValue(obj, prop, value) { if (!isObject(obj)) { @@ -67187,7 +67042,7 @@ function arrayify(val) { /***/ }), -/* 578 */ +/* 576 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67223,7 +67078,7 @@ module.exports = function union(init) { /***/ }), -/* 579 */ +/* 577 */ /***/ (function(module, exports) { /*! @@ -67279,7 +67134,7 @@ function toString(val) { /***/ }), -/* 580 */ +/* 578 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67292,10 +67147,10 @@ function toString(val) { -var split = __webpack_require__(542); -var extend = __webpack_require__(537); -var isPlainObject = __webpack_require__(545); -var isObject = __webpack_require__(538); +var split = __webpack_require__(540); +var extend = __webpack_require__(535); +var isPlainObject = __webpack_require__(543); +var isObject = __webpack_require__(536); module.exports = function(obj, prop, val) { if (!isObject(obj)) { @@ -67341,7 +67196,7 @@ function isValidKey(key) { /***/ }), -/* 581 */ +/* 579 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67354,8 +67209,8 @@ function isValidKey(key) { -var isObject = __webpack_require__(546); -var has = __webpack_require__(582); +var isObject = __webpack_require__(544); +var has = __webpack_require__(580); module.exports = function unset(obj, prop) { if (!isObject(obj)) { @@ -67380,7 +67235,7 @@ module.exports = function unset(obj, prop) { /***/ }), -/* 582 */ +/* 580 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67393,9 +67248,9 @@ module.exports = function unset(obj, prop) { -var isObject = __webpack_require__(583); -var hasValues = __webpack_require__(585); -var get = __webpack_require__(579); +var isObject = __webpack_require__(581); +var hasValues = __webpack_require__(583); +var get = __webpack_require__(577); module.exports = function(obj, prop, noZero) { if (isObject(obj)) { @@ -67406,7 +67261,7 @@ module.exports = function(obj, prop, noZero) { /***/ }), -/* 583 */ +/* 581 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67419,7 +67274,7 @@ module.exports = function(obj, prop, noZero) { -var isArray = __webpack_require__(584); +var isArray = __webpack_require__(582); module.exports = function isObject(val) { return val != null && typeof val === 'object' && isArray(val) === false; @@ -67427,7 +67282,7 @@ module.exports = function isObject(val) { /***/ }), -/* 584 */ +/* 582 */ /***/ (function(module, exports) { var toString = {}.toString; @@ -67438,7 +67293,7 @@ module.exports = Array.isArray || function (arr) { /***/ }), -/* 585 */ +/* 583 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67481,7 +67336,7 @@ module.exports = function hasValue(o, noZero) { /***/ }), -/* 586 */ +/* 584 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67494,9 +67349,9 @@ module.exports = function hasValue(o, noZero) { -var isObject = __webpack_require__(546); -var hasValues = __webpack_require__(587); -var get = __webpack_require__(579); +var isObject = __webpack_require__(544); +var hasValues = __webpack_require__(585); +var get = __webpack_require__(577); module.exports = function(val, prop) { return hasValues(isObject(val) && prop ? get(val, prop) : val); @@ -67504,7 +67359,7 @@ module.exports = function(val, prop) { /***/ }), -/* 587 */ +/* 585 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67517,8 +67372,8 @@ module.exports = function(val, prop) { -var typeOf = __webpack_require__(588); -var isNumber = __webpack_require__(550); +var typeOf = __webpack_require__(586); +var isNumber = __webpack_require__(548); module.exports = function hasValue(val) { // is-number checks for NaN and other edge cases @@ -67571,10 +67426,10 @@ module.exports = function hasValue(val) { /***/ }), -/* 588 */ +/* 586 */ /***/ (function(module, exports, __webpack_require__) { -var isBuffer = __webpack_require__(531); +var isBuffer = __webpack_require__(529); var toString = Object.prototype.toString; /** @@ -67696,14 +67551,14 @@ module.exports = function kindOf(val) { /***/ }), -/* 589 */ +/* 587 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isExtendable = __webpack_require__(590); -var forIn = __webpack_require__(591); +var isExtendable = __webpack_require__(588); +var forIn = __webpack_require__(589); function mixinDeep(target, objects) { var len = arguments.length, i = 0; @@ -67767,7 +67622,7 @@ module.exports = mixinDeep; /***/ }), -/* 590 */ +/* 588 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67780,7 +67635,7 @@ module.exports = mixinDeep; -var isPlainObject = __webpack_require__(545); +var isPlainObject = __webpack_require__(543); module.exports = function isExtendable(val) { return isPlainObject(val) || typeof val === 'function' || Array.isArray(val); @@ -67788,7 +67643,7 @@ module.exports = function isExtendable(val) { /***/ }), -/* 591 */ +/* 589 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67811,7 +67666,7 @@ module.exports = function forIn(obj, fn, thisArg) { /***/ }), -/* 592 */ +/* 590 */ /***/ (function(module, exports) { /*! @@ -67838,14 +67693,14 @@ module.exports = pascalcase; /***/ }), -/* 593 */ +/* 591 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var util = __webpack_require__(111); -var utils = __webpack_require__(594); +var utils = __webpack_require__(592); /** * Expose class utils @@ -68210,7 +68065,7 @@ cu.bubble = function(Parent, events) { /***/ }), -/* 594 */ +/* 592 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -68224,10 +68079,10 @@ var utils = {}; * Lazily required module dependencies */ -utils.union = __webpack_require__(578); -utils.define = __webpack_require__(595); -utils.isObj = __webpack_require__(546); -utils.staticExtend = __webpack_require__(602); +utils.union = __webpack_require__(576); +utils.define = __webpack_require__(593); +utils.isObj = __webpack_require__(544); +utils.staticExtend = __webpack_require__(600); /** @@ -68238,7 +68093,7 @@ module.exports = utils; /***/ }), -/* 595 */ +/* 593 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -68251,7 +68106,7 @@ module.exports = utils; -var isDescriptor = __webpack_require__(596); +var isDescriptor = __webpack_require__(594); module.exports = function defineProperty(obj, prop, val) { if (typeof obj !== 'object' && typeof obj !== 'function') { @@ -68276,7 +68131,7 @@ module.exports = function defineProperty(obj, prop, val) { /***/ }), -/* 596 */ +/* 594 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -68289,9 +68144,9 @@ module.exports = function defineProperty(obj, prop, val) { -var typeOf = __webpack_require__(597); -var isAccessor = __webpack_require__(598); -var isData = __webpack_require__(600); +var typeOf = __webpack_require__(595); +var isAccessor = __webpack_require__(596); +var isData = __webpack_require__(598); module.exports = function isDescriptor(obj, key) { if (typeOf(obj) !== 'object') { @@ -68305,7 +68160,7 @@ module.exports = function isDescriptor(obj, key) { /***/ }), -/* 597 */ +/* 595 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -68458,7 +68313,7 @@ function isBuffer(val) { /***/ }), -/* 598 */ +/* 596 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -68471,7 +68326,7 @@ function isBuffer(val) { -var typeOf = __webpack_require__(599); +var typeOf = __webpack_require__(597); // accessor descriptor properties var accessor = { @@ -68534,10 +68389,10 @@ module.exports = isAccessorDescriptor; /***/ }), -/* 599 */ +/* 597 */ /***/ (function(module, exports, __webpack_require__) { -var isBuffer = __webpack_require__(531); +var isBuffer = __webpack_require__(529); var toString = Object.prototype.toString; /** @@ -68656,7 +68511,7 @@ module.exports = function kindOf(val) { /***/ }), -/* 600 */ +/* 598 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -68669,7 +68524,7 @@ module.exports = function kindOf(val) { -var typeOf = __webpack_require__(601); +var typeOf = __webpack_require__(599); // data descriptor properties var data = { @@ -68718,10 +68573,10 @@ module.exports = isDataDescriptor; /***/ }), -/* 601 */ +/* 599 */ /***/ (function(module, exports, __webpack_require__) { -var isBuffer = __webpack_require__(531); +var isBuffer = __webpack_require__(529); var toString = Object.prototype.toString; /** @@ -68840,7 +68695,7 @@ module.exports = function kindOf(val) { /***/ }), -/* 602 */ +/* 600 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -68853,8 +68708,8 @@ module.exports = function kindOf(val) { -var copy = __webpack_require__(603); -var define = __webpack_require__(595); +var copy = __webpack_require__(601); +var define = __webpack_require__(593); var util = __webpack_require__(111); /** @@ -68937,15 +68792,15 @@ module.exports = extend; /***/ }), -/* 603 */ +/* 601 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var typeOf = __webpack_require__(551); -var copyDescriptor = __webpack_require__(604); -var define = __webpack_require__(595); +var typeOf = __webpack_require__(549); +var copyDescriptor = __webpack_require__(602); +var define = __webpack_require__(593); /** * Copy static properties, prototype properties, and descriptors from one object to another. @@ -69118,7 +68973,7 @@ module.exports.has = has; /***/ }), -/* 604 */ +/* 602 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -69206,16 +69061,16 @@ function isObject(val) { /***/ }), -/* 605 */ +/* 603 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var use = __webpack_require__(606); -var define = __webpack_require__(595); -var debug = __webpack_require__(608)('snapdragon:compiler'); -var utils = __webpack_require__(614); +var use = __webpack_require__(604); +var define = __webpack_require__(593); +var debug = __webpack_require__(606)('snapdragon:compiler'); +var utils = __webpack_require__(612); /** * Create a new `Compiler` with the given `options`. @@ -69369,7 +69224,7 @@ Compiler.prototype = { // source map support if (opts.sourcemap) { - var sourcemaps = __webpack_require__(633); + var sourcemaps = __webpack_require__(631); sourcemaps(this); this.mapVisit(this.ast.nodes); this.applySourceMaps(); @@ -69390,7 +69245,7 @@ module.exports = Compiler; /***/ }), -/* 606 */ +/* 604 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -69403,7 +69258,7 @@ module.exports = Compiler; -var utils = __webpack_require__(607); +var utils = __webpack_require__(605); module.exports = function base(app, opts) { if (!utils.isObject(app) && typeof app !== 'function') { @@ -69518,7 +69373,7 @@ module.exports = function base(app, opts) { /***/ }), -/* 607 */ +/* 605 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -69532,8 +69387,8 @@ var utils = {}; * Lazily required module dependencies */ -utils.define = __webpack_require__(595); -utils.isObject = __webpack_require__(546); +utils.define = __webpack_require__(593); +utils.isObject = __webpack_require__(544); utils.isString = function(val) { @@ -69548,7 +69403,7 @@ module.exports = utils; /***/ }), -/* 608 */ +/* 606 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -69557,14 +69412,14 @@ module.exports = utils; */ if (typeof process !== 'undefined' && process.type === 'renderer') { - module.exports = __webpack_require__(609); + module.exports = __webpack_require__(607); } else { - module.exports = __webpack_require__(612); + module.exports = __webpack_require__(610); } /***/ }), -/* 609 */ +/* 607 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -69573,7 +69428,7 @@ if (typeof process !== 'undefined' && process.type === 'renderer') { * Expose `debug()` as the module. */ -exports = module.exports = __webpack_require__(610); +exports = module.exports = __webpack_require__(608); exports.log = log; exports.formatArgs = formatArgs; exports.save = save; @@ -69755,7 +69610,7 @@ function localstorage() { /***/ }), -/* 610 */ +/* 608 */ /***/ (function(module, exports, __webpack_require__) { @@ -69771,7 +69626,7 @@ exports.coerce = coerce; exports.disable = disable; exports.enable = enable; exports.enabled = enabled; -exports.humanize = __webpack_require__(611); +exports.humanize = __webpack_require__(609); /** * The currently active debug mode names, and names to skip. @@ -69963,7 +69818,7 @@ function coerce(val) { /***/ }), -/* 611 */ +/* 609 */ /***/ (function(module, exports) { /** @@ -70121,7 +69976,7 @@ function plural(ms, n, name) { /***/ }), -/* 612 */ +/* 610 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -70137,7 +69992,7 @@ var util = __webpack_require__(111); * Expose `debug()` as the module. */ -exports = module.exports = __webpack_require__(610); +exports = module.exports = __webpack_require__(608); exports.init = init; exports.log = log; exports.formatArgs = formatArgs; @@ -70316,7 +70171,7 @@ function createWritableStdioStream (fd) { case 'PIPE': case 'TCP': - var net = __webpack_require__(613); + var net = __webpack_require__(611); stream = new net.Socket({ fd: fd, readable: false, @@ -70375,13 +70230,13 @@ exports.enable(load()); /***/ }), -/* 613 */ +/* 611 */ /***/ (function(module, exports) { module.exports = require("net"); /***/ }), -/* 614 */ +/* 612 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -70391,9 +70246,9 @@ module.exports = require("net"); * Module dependencies */ -exports.extend = __webpack_require__(537); -exports.SourceMap = __webpack_require__(615); -exports.sourceMapResolve = __webpack_require__(626); +exports.extend = __webpack_require__(535); +exports.SourceMap = __webpack_require__(613); +exports.sourceMapResolve = __webpack_require__(624); /** * Convert backslash in the given string to forward slashes @@ -70436,7 +70291,7 @@ exports.last = function(arr, n) { /***/ }), -/* 615 */ +/* 613 */ /***/ (function(module, exports, __webpack_require__) { /* @@ -70444,13 +70299,13 @@ exports.last = function(arr, n) { * Licensed under the New BSD license. See LICENSE.txt or: * http://opensource.org/licenses/BSD-3-Clause */ -exports.SourceMapGenerator = __webpack_require__(616).SourceMapGenerator; -exports.SourceMapConsumer = __webpack_require__(622).SourceMapConsumer; -exports.SourceNode = __webpack_require__(625).SourceNode; +exports.SourceMapGenerator = __webpack_require__(614).SourceMapGenerator; +exports.SourceMapConsumer = __webpack_require__(620).SourceMapConsumer; +exports.SourceNode = __webpack_require__(623).SourceNode; /***/ }), -/* 616 */ +/* 614 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -70460,10 +70315,10 @@ exports.SourceNode = __webpack_require__(625).SourceNode; * http://opensource.org/licenses/BSD-3-Clause */ -var base64VLQ = __webpack_require__(617); -var util = __webpack_require__(619); -var ArraySet = __webpack_require__(620).ArraySet; -var MappingList = __webpack_require__(621).MappingList; +var base64VLQ = __webpack_require__(615); +var util = __webpack_require__(617); +var ArraySet = __webpack_require__(618).ArraySet; +var MappingList = __webpack_require__(619).MappingList; /** * An instance of the SourceMapGenerator represents a source map which is @@ -70872,7 +70727,7 @@ exports.SourceMapGenerator = SourceMapGenerator; /***/ }), -/* 617 */ +/* 615 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -70912,7 +70767,7 @@ exports.SourceMapGenerator = SourceMapGenerator; * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -var base64 = __webpack_require__(618); +var base64 = __webpack_require__(616); // A single base 64 digit can contain 6 bits of data. For the base 64 variable // length quantities we use in the source map spec, the first bit is the sign, @@ -71018,7 +70873,7 @@ exports.decode = function base64VLQ_decode(aStr, aIndex, aOutParam) { /***/ }), -/* 618 */ +/* 616 */ /***/ (function(module, exports) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -71091,7 +70946,7 @@ exports.decode = function (charCode) { /***/ }), -/* 619 */ +/* 617 */ /***/ (function(module, exports) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -71514,7 +71369,7 @@ exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflate /***/ }), -/* 620 */ +/* 618 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -71524,7 +71379,7 @@ exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflate * http://opensource.org/licenses/BSD-3-Clause */ -var util = __webpack_require__(619); +var util = __webpack_require__(617); var has = Object.prototype.hasOwnProperty; var hasNativeMap = typeof Map !== "undefined"; @@ -71641,7 +71496,7 @@ exports.ArraySet = ArraySet; /***/ }), -/* 621 */ +/* 619 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -71651,7 +71506,7 @@ exports.ArraySet = ArraySet; * http://opensource.org/licenses/BSD-3-Clause */ -var util = __webpack_require__(619); +var util = __webpack_require__(617); /** * Determine whether mappingB is after mappingA with respect to generated @@ -71726,7 +71581,7 @@ exports.MappingList = MappingList; /***/ }), -/* 622 */ +/* 620 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -71736,11 +71591,11 @@ exports.MappingList = MappingList; * http://opensource.org/licenses/BSD-3-Clause */ -var util = __webpack_require__(619); -var binarySearch = __webpack_require__(623); -var ArraySet = __webpack_require__(620).ArraySet; -var base64VLQ = __webpack_require__(617); -var quickSort = __webpack_require__(624).quickSort; +var util = __webpack_require__(617); +var binarySearch = __webpack_require__(621); +var ArraySet = __webpack_require__(618).ArraySet; +var base64VLQ = __webpack_require__(615); +var quickSort = __webpack_require__(622).quickSort; function SourceMapConsumer(aSourceMap) { var sourceMap = aSourceMap; @@ -72814,7 +72669,7 @@ exports.IndexedSourceMapConsumer = IndexedSourceMapConsumer; /***/ }), -/* 623 */ +/* 621 */ /***/ (function(module, exports) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -72931,7 +72786,7 @@ exports.search = function search(aNeedle, aHaystack, aCompare, aBias) { /***/ }), -/* 624 */ +/* 622 */ /***/ (function(module, exports) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -73051,7 +72906,7 @@ exports.quickSort = function (ary, comparator) { /***/ }), -/* 625 */ +/* 623 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -73061,8 +72916,8 @@ exports.quickSort = function (ary, comparator) { * http://opensource.org/licenses/BSD-3-Clause */ -var SourceMapGenerator = __webpack_require__(616).SourceMapGenerator; -var util = __webpack_require__(619); +var SourceMapGenerator = __webpack_require__(614).SourceMapGenerator; +var util = __webpack_require__(617); // Matches a Windows-style `\r\n` newline or a `\n` newline used by all other // operating systems these days (capturing the result). @@ -73470,17 +73325,17 @@ exports.SourceNode = SourceNode; /***/ }), -/* 626 */ +/* 624 */ /***/ (function(module, exports, __webpack_require__) { // Copyright 2014, 2015, 2016, 2017 Simon Lydell // X11 (“MIT”) Licensed. (See LICENSE.) -var sourceMappingURL = __webpack_require__(627) -var resolveUrl = __webpack_require__(628) -var decodeUriComponent = __webpack_require__(629) -var urix = __webpack_require__(631) -var atob = __webpack_require__(632) +var sourceMappingURL = __webpack_require__(625) +var resolveUrl = __webpack_require__(626) +var decodeUriComponent = __webpack_require__(627) +var urix = __webpack_require__(629) +var atob = __webpack_require__(630) @@ -73778,7 +73633,7 @@ module.exports = { /***/ }), -/* 627 */ +/* 625 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;// Copyright 2014 Simon Lydell @@ -73841,7 +73696,7 @@ void (function(root, factory) { /***/ }), -/* 628 */ +/* 626 */ /***/ (function(module, exports, __webpack_require__) { // Copyright 2014 Simon Lydell @@ -73859,13 +73714,13 @@ module.exports = resolveUrl /***/ }), -/* 629 */ +/* 627 */ /***/ (function(module, exports, __webpack_require__) { // Copyright 2017 Simon Lydell // X11 (“MIT”) Licensed. (See LICENSE.) -var decodeUriComponent = __webpack_require__(630) +var decodeUriComponent = __webpack_require__(628) function customDecodeUriComponent(string) { // `decodeUriComponent` turns `+` into ` `, but that's not wanted. @@ -73876,7 +73731,7 @@ module.exports = customDecodeUriComponent /***/ }), -/* 630 */ +/* 628 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -73977,7 +73832,7 @@ module.exports = function (encodedURI) { /***/ }), -/* 631 */ +/* 629 */ /***/ (function(module, exports, __webpack_require__) { // Copyright 2014 Simon Lydell @@ -74000,7 +73855,7 @@ module.exports = urix /***/ }), -/* 632 */ +/* 630 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -74014,7 +73869,7 @@ module.exports = atob.atob = atob; /***/ }), -/* 633 */ +/* 631 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -74022,8 +73877,8 @@ module.exports = atob.atob = atob; var fs = __webpack_require__(133); var path = __webpack_require__(4); -var define = __webpack_require__(595); -var utils = __webpack_require__(614); +var define = __webpack_require__(593); +var utils = __webpack_require__(612); /** * Expose `mixin()`. @@ -74166,19 +74021,19 @@ exports.comment = function(node) { /***/ }), -/* 634 */ +/* 632 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var use = __webpack_require__(606); +var use = __webpack_require__(604); var util = __webpack_require__(111); -var Cache = __webpack_require__(635); -var define = __webpack_require__(595); -var debug = __webpack_require__(608)('snapdragon:parser'); -var Position = __webpack_require__(636); -var utils = __webpack_require__(614); +var Cache = __webpack_require__(633); +var define = __webpack_require__(593); +var debug = __webpack_require__(606)('snapdragon:parser'); +var Position = __webpack_require__(634); +var utils = __webpack_require__(612); /** * Create a new `Parser` with the given `input` and `options`. @@ -74706,7 +74561,7 @@ module.exports = Parser; /***/ }), -/* 635 */ +/* 633 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -74813,13 +74668,13 @@ MapCache.prototype.del = function mapDelete(key) { /***/ }), -/* 636 */ +/* 634 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var define = __webpack_require__(595); +var define = __webpack_require__(593); /** * Store position for a node @@ -74834,16 +74689,16 @@ module.exports = function Position(start, parser) { /***/ }), -/* 637 */ +/* 635 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var safe = __webpack_require__(638); -var define = __webpack_require__(644); -var extend = __webpack_require__(645); -var not = __webpack_require__(647); +var safe = __webpack_require__(636); +var define = __webpack_require__(642); +var extend = __webpack_require__(643); +var not = __webpack_require__(645); var MAX_LENGTH = 1024 * 64; /** @@ -74996,10 +74851,10 @@ module.exports.makeRe = makeRe; /***/ }), -/* 638 */ +/* 636 */ /***/ (function(module, exports, __webpack_require__) { -var parse = __webpack_require__(639); +var parse = __webpack_require__(637); var types = parse.types; module.exports = function (re, opts) { @@ -75045,13 +74900,13 @@ function isRegExp (x) { /***/ }), -/* 639 */ +/* 637 */ /***/ (function(module, exports, __webpack_require__) { -var util = __webpack_require__(640); -var types = __webpack_require__(641); -var sets = __webpack_require__(642); -var positions = __webpack_require__(643); +var util = __webpack_require__(638); +var types = __webpack_require__(639); +var sets = __webpack_require__(640); +var positions = __webpack_require__(641); module.exports = function(regexpStr) { @@ -75333,11 +75188,11 @@ module.exports.types = types; /***/ }), -/* 640 */ +/* 638 */ /***/ (function(module, exports, __webpack_require__) { -var types = __webpack_require__(641); -var sets = __webpack_require__(642); +var types = __webpack_require__(639); +var sets = __webpack_require__(640); // All of these are private and only used by randexp. @@ -75450,7 +75305,7 @@ exports.error = function(regexp, msg) { /***/ }), -/* 641 */ +/* 639 */ /***/ (function(module, exports) { module.exports = { @@ -75466,10 +75321,10 @@ module.exports = { /***/ }), -/* 642 */ +/* 640 */ /***/ (function(module, exports, __webpack_require__) { -var types = __webpack_require__(641); +var types = __webpack_require__(639); var INTS = function() { return [{ type: types.RANGE , from: 48, to: 57 }]; @@ -75554,10 +75409,10 @@ exports.anyChar = function() { /***/ }), -/* 643 */ +/* 641 */ /***/ (function(module, exports, __webpack_require__) { -var types = __webpack_require__(641); +var types = __webpack_require__(639); exports.wordBoundary = function() { return { type: types.POSITION, value: 'b' }; @@ -75577,7 +75432,7 @@ exports.end = function() { /***/ }), -/* 644 */ +/* 642 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -75590,8 +75445,8 @@ exports.end = function() { -var isobject = __webpack_require__(546); -var isDescriptor = __webpack_require__(560); +var isobject = __webpack_require__(544); +var isDescriptor = __webpack_require__(558); var define = (typeof Reflect !== 'undefined' && Reflect.defineProperty) ? Reflect.defineProperty : Object.defineProperty; @@ -75622,14 +75477,14 @@ module.exports = function defineProperty(obj, key, val) { /***/ }), -/* 645 */ +/* 643 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isExtendable = __webpack_require__(646); -var assignSymbols = __webpack_require__(547); +var isExtendable = __webpack_require__(644); +var assignSymbols = __webpack_require__(545); module.exports = Object.assign || function(obj/*, objects*/) { if (obj === null || typeof obj === 'undefined') { @@ -75689,7 +75544,7 @@ function isEnum(obj, key) { /***/ }), -/* 646 */ +/* 644 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -75702,7 +75557,7 @@ function isEnum(obj, key) { -var isPlainObject = __webpack_require__(545); +var isPlainObject = __webpack_require__(543); module.exports = function isExtendable(val) { return isPlainObject(val) || typeof val === 'function' || Array.isArray(val); @@ -75710,14 +75565,14 @@ module.exports = function isExtendable(val) { /***/ }), -/* 647 */ +/* 645 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var extend = __webpack_require__(645); -var safe = __webpack_require__(638); +var extend = __webpack_require__(643); +var safe = __webpack_require__(636); /** * The main export is a function that takes a `pattern` string and an `options` object. @@ -75789,14 +75644,14 @@ module.exports = toRegex; /***/ }), -/* 648 */ +/* 646 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var nanomatch = __webpack_require__(649); -var extglob = __webpack_require__(665); +var nanomatch = __webpack_require__(647); +var extglob = __webpack_require__(663); module.exports = function(snapdragon) { var compilers = snapdragon.compiler.compilers; @@ -75873,7 +75728,7 @@ function escapeExtglobs(compiler) { /***/ }), -/* 649 */ +/* 647 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -75884,17 +75739,17 @@ function escapeExtglobs(compiler) { */ var util = __webpack_require__(111); -var toRegex = __webpack_require__(650); -var extend = __webpack_require__(651); +var toRegex = __webpack_require__(648); +var extend = __webpack_require__(649); /** * Local dependencies */ -var compilers = __webpack_require__(653); -var parsers = __webpack_require__(654); -var cache = __webpack_require__(657); -var utils = __webpack_require__(659); +var compilers = __webpack_require__(651); +var parsers = __webpack_require__(652); +var cache = __webpack_require__(655); +var utils = __webpack_require__(657); var MAX_LENGTH = 1024 * 64; /** @@ -76718,15 +76573,15 @@ module.exports = nanomatch; /***/ }), -/* 650 */ +/* 648 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var define = __webpack_require__(595); -var extend = __webpack_require__(537); -var not = __webpack_require__(536); +var define = __webpack_require__(593); +var extend = __webpack_require__(535); +var not = __webpack_require__(534); var MAX_LENGTH = 1024 * 64; /** @@ -76873,14 +76728,14 @@ module.exports.makeRe = makeRe; /***/ }), -/* 651 */ +/* 649 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isExtendable = __webpack_require__(652); -var assignSymbols = __webpack_require__(547); +var isExtendable = __webpack_require__(650); +var assignSymbols = __webpack_require__(545); module.exports = Object.assign || function(obj/*, objects*/) { if (obj === null || typeof obj === 'undefined') { @@ -76940,7 +76795,7 @@ function isEnum(obj, key) { /***/ }), -/* 652 */ +/* 650 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -76953,7 +76808,7 @@ function isEnum(obj, key) { -var isPlainObject = __webpack_require__(545); +var isPlainObject = __webpack_require__(543); module.exports = function isExtendable(val) { return isPlainObject(val) || typeof val === 'function' || Array.isArray(val); @@ -76961,7 +76816,7 @@ module.exports = function isExtendable(val) { /***/ }), -/* 653 */ +/* 651 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -77307,15 +77162,15 @@ module.exports = function(nanomatch, options) { /***/ }), -/* 654 */ +/* 652 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var regexNot = __webpack_require__(536); -var toRegex = __webpack_require__(650); -var isOdd = __webpack_require__(655); +var regexNot = __webpack_require__(534); +var toRegex = __webpack_require__(648); +var isOdd = __webpack_require__(653); /** * Characters to use in negation regex (we want to "not" match @@ -77701,7 +77556,7 @@ module.exports.not = NOT_REGEX; /***/ }), -/* 655 */ +/* 653 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -77714,7 +77569,7 @@ module.exports.not = NOT_REGEX; -var isNumber = __webpack_require__(656); +var isNumber = __webpack_require__(654); module.exports = function isOdd(i) { if (!isNumber(i)) { @@ -77728,7 +77583,7 @@ module.exports = function isOdd(i) { /***/ }), -/* 656 */ +/* 654 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -77756,14 +77611,14 @@ module.exports = function isNumber(num) { /***/ }), -/* 657 */ +/* 655 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = new (__webpack_require__(658))(); +module.exports = new (__webpack_require__(656))(); /***/ }), -/* 658 */ +/* 656 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -77776,7 +77631,7 @@ module.exports = new (__webpack_require__(658))(); -var MapCache = __webpack_require__(635); +var MapCache = __webpack_require__(633); /** * Create a new `FragmentCache` with an optional object to use for `caches`. @@ -77898,7 +77753,7 @@ exports = module.exports = FragmentCache; /***/ }), -/* 659 */ +/* 657 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -77911,14 +77766,14 @@ var path = __webpack_require__(4); * Module dependencies */ -var isWindows = __webpack_require__(660)(); -var Snapdragon = __webpack_require__(568); -utils.define = __webpack_require__(661); -utils.diff = __webpack_require__(662); -utils.extend = __webpack_require__(651); -utils.pick = __webpack_require__(663); -utils.typeOf = __webpack_require__(664); -utils.unique = __webpack_require__(539); +var isWindows = __webpack_require__(658)(); +var Snapdragon = __webpack_require__(566); +utils.define = __webpack_require__(659); +utils.diff = __webpack_require__(660); +utils.extend = __webpack_require__(649); +utils.pick = __webpack_require__(661); +utils.typeOf = __webpack_require__(662); +utils.unique = __webpack_require__(537); /** * Returns true if the given value is effectively an empty string @@ -78284,7 +78139,7 @@ utils.unixify = function(options) { /***/ }), -/* 660 */ +/* 658 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! @@ -78312,7 +78167,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ /***/ }), -/* 661 */ +/* 659 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -78325,8 +78180,8 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ -var isobject = __webpack_require__(546); -var isDescriptor = __webpack_require__(560); +var isobject = __webpack_require__(544); +var isDescriptor = __webpack_require__(558); var define = (typeof Reflect !== 'undefined' && Reflect.defineProperty) ? Reflect.defineProperty : Object.defineProperty; @@ -78357,7 +78212,7 @@ module.exports = function defineProperty(obj, key, val) { /***/ }), -/* 662 */ +/* 660 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -78411,7 +78266,7 @@ function diffArray(one, two) { /***/ }), -/* 663 */ +/* 661 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -78424,7 +78279,7 @@ function diffArray(one, two) { -var isObject = __webpack_require__(546); +var isObject = __webpack_require__(544); module.exports = function pick(obj, keys) { if (!isObject(obj) && typeof obj !== 'function') { @@ -78453,7 +78308,7 @@ module.exports = function pick(obj, keys) { /***/ }), -/* 664 */ +/* 662 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -78588,7 +78443,7 @@ function isBuffer(val) { /***/ }), -/* 665 */ +/* 663 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -78598,18 +78453,18 @@ function isBuffer(val) { * Module dependencies */ -var extend = __webpack_require__(537); -var unique = __webpack_require__(539); -var toRegex = __webpack_require__(650); +var extend = __webpack_require__(535); +var unique = __webpack_require__(537); +var toRegex = __webpack_require__(648); /** * Local dependencies */ -var compilers = __webpack_require__(666); -var parsers = __webpack_require__(677); -var Extglob = __webpack_require__(680); -var utils = __webpack_require__(679); +var compilers = __webpack_require__(664); +var parsers = __webpack_require__(675); +var Extglob = __webpack_require__(678); +var utils = __webpack_require__(677); var MAX_LENGTH = 1024 * 64; /** @@ -78926,13 +78781,13 @@ module.exports = extglob; /***/ }), -/* 666 */ +/* 664 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var brackets = __webpack_require__(667); +var brackets = __webpack_require__(665); /** * Extglob compilers @@ -79102,7 +78957,7 @@ module.exports = function(extglob) { /***/ }), -/* 667 */ +/* 665 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -79112,17 +78967,17 @@ module.exports = function(extglob) { * Local dependencies */ -var compilers = __webpack_require__(668); -var parsers = __webpack_require__(670); +var compilers = __webpack_require__(666); +var parsers = __webpack_require__(668); /** * Module dependencies */ -var debug = __webpack_require__(672)('expand-brackets'); -var extend = __webpack_require__(537); -var Snapdragon = __webpack_require__(568); -var toRegex = __webpack_require__(650); +var debug = __webpack_require__(670)('expand-brackets'); +var extend = __webpack_require__(535); +var Snapdragon = __webpack_require__(566); +var toRegex = __webpack_require__(648); /** * Parses the given POSIX character class `pattern` and returns a @@ -79320,13 +79175,13 @@ module.exports = brackets; /***/ }), -/* 668 */ +/* 666 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var posix = __webpack_require__(669); +var posix = __webpack_require__(667); module.exports = function(brackets) { brackets.compiler @@ -79414,7 +79269,7 @@ module.exports = function(brackets) { /***/ }), -/* 669 */ +/* 667 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -79443,14 +79298,14 @@ module.exports = { /***/ }), -/* 670 */ +/* 668 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var utils = __webpack_require__(671); -var define = __webpack_require__(595); +var utils = __webpack_require__(669); +var define = __webpack_require__(593); /** * Text regex @@ -79669,14 +79524,14 @@ module.exports.TEXT_REGEX = TEXT_REGEX; /***/ }), -/* 671 */ +/* 669 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var toRegex = __webpack_require__(650); -var regexNot = __webpack_require__(536); +var toRegex = __webpack_require__(648); +var regexNot = __webpack_require__(534); var cached; /** @@ -79710,7 +79565,7 @@ exports.createRegex = function(pattern, include) { /***/ }), -/* 672 */ +/* 670 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -79719,14 +79574,14 @@ exports.createRegex = function(pattern, include) { */ if (typeof process !== 'undefined' && process.type === 'renderer') { - module.exports = __webpack_require__(673); + module.exports = __webpack_require__(671); } else { - module.exports = __webpack_require__(676); + module.exports = __webpack_require__(674); } /***/ }), -/* 673 */ +/* 671 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -79735,7 +79590,7 @@ if (typeof process !== 'undefined' && process.type === 'renderer') { * Expose `debug()` as the module. */ -exports = module.exports = __webpack_require__(674); +exports = module.exports = __webpack_require__(672); exports.log = log; exports.formatArgs = formatArgs; exports.save = save; @@ -79917,7 +79772,7 @@ function localstorage() { /***/ }), -/* 674 */ +/* 672 */ /***/ (function(module, exports, __webpack_require__) { @@ -79933,7 +79788,7 @@ exports.coerce = coerce; exports.disable = disable; exports.enable = enable; exports.enabled = enabled; -exports.humanize = __webpack_require__(675); +exports.humanize = __webpack_require__(673); /** * The currently active debug mode names, and names to skip. @@ -80125,7 +79980,7 @@ function coerce(val) { /***/ }), -/* 675 */ +/* 673 */ /***/ (function(module, exports) { /** @@ -80283,7 +80138,7 @@ function plural(ms, n, name) { /***/ }), -/* 676 */ +/* 674 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -80299,7 +80154,7 @@ var util = __webpack_require__(111); * Expose `debug()` as the module. */ -exports = module.exports = __webpack_require__(674); +exports = module.exports = __webpack_require__(672); exports.init = init; exports.log = log; exports.formatArgs = formatArgs; @@ -80478,7 +80333,7 @@ function createWritableStdioStream (fd) { case 'PIPE': case 'TCP': - var net = __webpack_require__(613); + var net = __webpack_require__(611); stream = new net.Socket({ fd: fd, readable: false, @@ -80537,15 +80392,15 @@ exports.enable(load()); /***/ }), -/* 677 */ +/* 675 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var brackets = __webpack_require__(667); -var define = __webpack_require__(678); -var utils = __webpack_require__(679); +var brackets = __webpack_require__(665); +var define = __webpack_require__(676); +var utils = __webpack_require__(677); /** * Characters to use in text regex (we want to "not" match @@ -80700,7 +80555,7 @@ module.exports = parsers; /***/ }), -/* 678 */ +/* 676 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -80713,7 +80568,7 @@ module.exports = parsers; -var isDescriptor = __webpack_require__(560); +var isDescriptor = __webpack_require__(558); module.exports = function defineProperty(obj, prop, val) { if (typeof obj !== 'object' && typeof obj !== 'function') { @@ -80738,14 +80593,14 @@ module.exports = function defineProperty(obj, prop, val) { /***/ }), -/* 679 */ +/* 677 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var regex = __webpack_require__(536); -var Cache = __webpack_require__(658); +var regex = __webpack_require__(534); +var Cache = __webpack_require__(656); /** * Utils @@ -80814,7 +80669,7 @@ utils.createRegex = function(str) { /***/ }), -/* 680 */ +/* 678 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -80824,16 +80679,16 @@ utils.createRegex = function(str) { * Module dependencies */ -var Snapdragon = __webpack_require__(568); -var define = __webpack_require__(678); -var extend = __webpack_require__(537); +var Snapdragon = __webpack_require__(566); +var define = __webpack_require__(676); +var extend = __webpack_require__(535); /** * Local dependencies */ -var compilers = __webpack_require__(666); -var parsers = __webpack_require__(677); +var compilers = __webpack_require__(664); +var parsers = __webpack_require__(675); /** * Customize Snapdragon parser and renderer @@ -80899,16 +80754,16 @@ module.exports = Extglob; /***/ }), -/* 681 */ +/* 679 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var extglob = __webpack_require__(665); -var nanomatch = __webpack_require__(649); -var regexNot = __webpack_require__(536); -var toRegex = __webpack_require__(637); +var extglob = __webpack_require__(663); +var nanomatch = __webpack_require__(647); +var regexNot = __webpack_require__(534); +var toRegex = __webpack_require__(635); var not; /** @@ -80989,14 +80844,14 @@ function textRegex(pattern) { /***/ }), -/* 682 */ +/* 680 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = new (__webpack_require__(658))(); +module.exports = new (__webpack_require__(656))(); /***/ }), -/* 683 */ +/* 681 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -81009,13 +80864,13 @@ var path = __webpack_require__(4); * Module dependencies */ -var Snapdragon = __webpack_require__(568); -utils.define = __webpack_require__(644); -utils.diff = __webpack_require__(662); -utils.extend = __webpack_require__(645); -utils.pick = __webpack_require__(663); -utils.typeOf = __webpack_require__(684); -utils.unique = __webpack_require__(539); +var Snapdragon = __webpack_require__(566); +utils.define = __webpack_require__(642); +utils.diff = __webpack_require__(660); +utils.extend = __webpack_require__(643); +utils.pick = __webpack_require__(661); +utils.typeOf = __webpack_require__(682); +utils.unique = __webpack_require__(537); /** * Returns true if the platform is windows, or `path.sep` is `\\`. @@ -81312,7 +81167,7 @@ utils.unixify = function(options) { /***/ }), -/* 684 */ +/* 682 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -81447,7 +81302,7 @@ function isBuffer(val) { /***/ }), -/* 685 */ +/* 683 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -81466,9 +81321,9 @@ var __extends = (this && this.__extends) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -var readdir = __webpack_require__(686); -var reader_1 = __webpack_require__(699); -var fs_stream_1 = __webpack_require__(703); +var readdir = __webpack_require__(684); +var reader_1 = __webpack_require__(697); +var fs_stream_1 = __webpack_require__(701); var ReaderAsync = /** @class */ (function (_super) { __extends(ReaderAsync, _super); function ReaderAsync() { @@ -81529,15 +81384,15 @@ exports.default = ReaderAsync; /***/ }), -/* 686 */ +/* 684 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const readdirSync = __webpack_require__(687); -const readdirAsync = __webpack_require__(695); -const readdirStream = __webpack_require__(698); +const readdirSync = __webpack_require__(685); +const readdirAsync = __webpack_require__(693); +const readdirStream = __webpack_require__(696); module.exports = exports = readdirAsyncPath; exports.readdir = exports.readdirAsync = exports.async = readdirAsyncPath; @@ -81621,7 +81476,7 @@ function readdirStreamStat (dir, options) { /***/ }), -/* 687 */ +/* 685 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -81629,11 +81484,11 @@ function readdirStreamStat (dir, options) { module.exports = readdirSync; -const DirectoryReader = __webpack_require__(688); +const DirectoryReader = __webpack_require__(686); let syncFacade = { - fs: __webpack_require__(693), - forEach: __webpack_require__(694), + fs: __webpack_require__(691), + forEach: __webpack_require__(692), sync: true }; @@ -81662,7 +81517,7 @@ function readdirSync (dir, options, internalOptions) { /***/ }), -/* 688 */ +/* 686 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -81671,9 +81526,9 @@ function readdirSync (dir, options, internalOptions) { const Readable = __webpack_require__(137).Readable; const EventEmitter = __webpack_require__(155).EventEmitter; const path = __webpack_require__(4); -const normalizeOptions = __webpack_require__(689); -const stat = __webpack_require__(691); -const call = __webpack_require__(692); +const normalizeOptions = __webpack_require__(687); +const stat = __webpack_require__(689); +const call = __webpack_require__(690); /** * Asynchronously reads the contents of a directory and streams the results @@ -82049,14 +81904,14 @@ module.exports = DirectoryReader; /***/ }), -/* 689 */ +/* 687 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const path = __webpack_require__(4); -const globToRegExp = __webpack_require__(690); +const globToRegExp = __webpack_require__(688); module.exports = normalizeOptions; @@ -82233,7 +82088,7 @@ function normalizeOptions (options, internalOptions) { /***/ }), -/* 690 */ +/* 688 */ /***/ (function(module, exports) { module.exports = function (glob, opts) { @@ -82370,13 +82225,13 @@ module.exports = function (glob, opts) { /***/ }), -/* 691 */ +/* 689 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const call = __webpack_require__(692); +const call = __webpack_require__(690); module.exports = stat; @@ -82451,7 +82306,7 @@ function symlinkStat (fs, path, lstats, callback) { /***/ }), -/* 692 */ +/* 690 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -82512,14 +82367,14 @@ function callOnce (fn) { /***/ }), -/* 693 */ +/* 691 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const fs = __webpack_require__(133); -const call = __webpack_require__(692); +const call = __webpack_require__(690); /** * A facade around {@link fs.readdirSync} that allows it to be called @@ -82583,7 +82438,7 @@ exports.lstat = function (path, callback) { /***/ }), -/* 694 */ +/* 692 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -82612,7 +82467,7 @@ function syncForEach (array, iterator, done) { /***/ }), -/* 695 */ +/* 693 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -82620,12 +82475,12 @@ function syncForEach (array, iterator, done) { module.exports = readdirAsync; -const maybe = __webpack_require__(696); -const DirectoryReader = __webpack_require__(688); +const maybe = __webpack_require__(694); +const DirectoryReader = __webpack_require__(686); let asyncFacade = { fs: __webpack_require__(133), - forEach: __webpack_require__(697), + forEach: __webpack_require__(695), async: true }; @@ -82667,7 +82522,7 @@ function readdirAsync (dir, options, callback, internalOptions) { /***/ }), -/* 696 */ +/* 694 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -82694,7 +82549,7 @@ module.exports = function maybe (cb, promise) { /***/ }), -/* 697 */ +/* 695 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -82730,7 +82585,7 @@ function asyncForEach (array, iterator, done) { /***/ }), -/* 698 */ +/* 696 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -82738,11 +82593,11 @@ function asyncForEach (array, iterator, done) { module.exports = readdirStream; -const DirectoryReader = __webpack_require__(688); +const DirectoryReader = __webpack_require__(686); let streamFacade = { fs: __webpack_require__(133), - forEach: __webpack_require__(697), + forEach: __webpack_require__(695), async: true }; @@ -82762,16 +82617,16 @@ function readdirStream (dir, options, internalOptions) { /***/ }), -/* 699 */ +/* 697 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var path = __webpack_require__(4); -var deep_1 = __webpack_require__(700); -var entry_1 = __webpack_require__(702); -var pathUtil = __webpack_require__(701); +var deep_1 = __webpack_require__(698); +var entry_1 = __webpack_require__(700); +var pathUtil = __webpack_require__(699); var Reader = /** @class */ (function () { function Reader(options) { this.options = options; @@ -82837,14 +82692,14 @@ exports.default = Reader; /***/ }), -/* 700 */ +/* 698 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var pathUtils = __webpack_require__(701); -var patternUtils = __webpack_require__(518); +var pathUtils = __webpack_require__(699); +var patternUtils = __webpack_require__(516); var DeepFilter = /** @class */ (function () { function DeepFilter(options, micromatchOptions) { this.options = options; @@ -82927,7 +82782,7 @@ exports.default = DeepFilter; /***/ }), -/* 701 */ +/* 699 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -82958,14 +82813,14 @@ exports.makeAbsolute = makeAbsolute; /***/ }), -/* 702 */ +/* 700 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var pathUtils = __webpack_require__(701); -var patternUtils = __webpack_require__(518); +var pathUtils = __webpack_require__(699); +var patternUtils = __webpack_require__(516); var EntryFilter = /** @class */ (function () { function EntryFilter(options, micromatchOptions) { this.options = options; @@ -83050,7 +82905,7 @@ exports.default = EntryFilter; /***/ }), -/* 703 */ +/* 701 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83070,8 +82925,8 @@ var __extends = (this && this.__extends) || (function () { })(); Object.defineProperty(exports, "__esModule", { value: true }); var stream = __webpack_require__(137); -var fsStat = __webpack_require__(704); -var fs_1 = __webpack_require__(708); +var fsStat = __webpack_require__(702); +var fs_1 = __webpack_require__(706); var FileSystemStream = /** @class */ (function (_super) { __extends(FileSystemStream, _super); function FileSystemStream() { @@ -83121,14 +82976,14 @@ exports.default = FileSystemStream; /***/ }), -/* 704 */ +/* 702 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const optionsManager = __webpack_require__(705); -const statProvider = __webpack_require__(707); +const optionsManager = __webpack_require__(703); +const statProvider = __webpack_require__(705); /** * Asynchronous API. */ @@ -83159,13 +83014,13 @@ exports.statSync = statSync; /***/ }), -/* 705 */ +/* 703 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const fsAdapter = __webpack_require__(706); +const fsAdapter = __webpack_require__(704); function prepare(opts) { const options = Object.assign({ fs: fsAdapter.getFileSystemAdapter(opts ? opts.fs : undefined), @@ -83178,7 +83033,7 @@ exports.prepare = prepare; /***/ }), -/* 706 */ +/* 704 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83201,7 +83056,7 @@ exports.getFileSystemAdapter = getFileSystemAdapter; /***/ }), -/* 707 */ +/* 705 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83253,7 +83108,7 @@ exports.isFollowedSymlink = isFollowedSymlink; /***/ }), -/* 708 */ +/* 706 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83284,7 +83139,7 @@ exports.default = FileSystem; /***/ }), -/* 709 */ +/* 707 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83304,9 +83159,9 @@ var __extends = (this && this.__extends) || (function () { })(); Object.defineProperty(exports, "__esModule", { value: true }); var stream = __webpack_require__(137); -var readdir = __webpack_require__(686); -var reader_1 = __webpack_require__(699); -var fs_stream_1 = __webpack_require__(703); +var readdir = __webpack_require__(684); +var reader_1 = __webpack_require__(697); +var fs_stream_1 = __webpack_require__(701); var TransformStream = /** @class */ (function (_super) { __extends(TransformStream, _super); function TransformStream(reader) { @@ -83374,7 +83229,7 @@ exports.default = ReaderStream; /***/ }), -/* 710 */ +/* 708 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83393,9 +83248,9 @@ var __extends = (this && this.__extends) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -var readdir = __webpack_require__(686); -var reader_1 = __webpack_require__(699); -var fs_sync_1 = __webpack_require__(711); +var readdir = __webpack_require__(684); +var reader_1 = __webpack_require__(697); +var fs_sync_1 = __webpack_require__(709); var ReaderSync = /** @class */ (function (_super) { __extends(ReaderSync, _super); function ReaderSync() { @@ -83455,7 +83310,7 @@ exports.default = ReaderSync; /***/ }), -/* 711 */ +/* 709 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83474,8 +83329,8 @@ var __extends = (this && this.__extends) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -var fsStat = __webpack_require__(704); -var fs_1 = __webpack_require__(708); +var fsStat = __webpack_require__(702); +var fs_1 = __webpack_require__(706); var FileSystemSync = /** @class */ (function (_super) { __extends(FileSystemSync, _super); function FileSystemSync() { @@ -83521,7 +83376,7 @@ exports.default = FileSystemSync; /***/ }), -/* 712 */ +/* 710 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83537,13 +83392,13 @@ exports.flatten = flatten; /***/ }), -/* 713 */ +/* 711 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var merge2 = __webpack_require__(299); +var merge2 = __webpack_require__(291); /** * Merge multiple streams and propagate their errors into one stream in parallel. */ @@ -83558,13 +83413,13 @@ exports.merge = merge; /***/ }), -/* 714 */ +/* 712 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const path = __webpack_require__(4); -const pathType = __webpack_require__(715); +const pathType = __webpack_require__(713); const getExtensions = extensions => extensions.length > 1 ? `{${extensions.join(',')}}` : extensions[0]; @@ -83630,13 +83485,13 @@ module.exports.sync = (input, opts) => { /***/ }), -/* 715 */ +/* 713 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const fs = __webpack_require__(133); -const pify = __webpack_require__(716); +const pify = __webpack_require__(714); function type(fn, fn2, fp) { if (typeof fp !== 'string') { @@ -83679,7 +83534,7 @@ exports.symlinkSync = typeSync.bind(null, 'lstatSync', 'isSymbolicLink'); /***/ }), -/* 716 */ +/* 714 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83770,17 +83625,17 @@ module.exports = (obj, opts) => { /***/ }), -/* 717 */ +/* 715 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const fs = __webpack_require__(133); const path = __webpack_require__(4); -const fastGlob = __webpack_require__(514); -const gitIgnore = __webpack_require__(718); -const pify = __webpack_require__(719); -const slash = __webpack_require__(720); +const fastGlob = __webpack_require__(512); +const gitIgnore = __webpack_require__(716); +const pify = __webpack_require__(717); +const slash = __webpack_require__(718); const DEFAULT_IGNORE = [ '**/node_modules/**', @@ -83878,7 +83733,7 @@ module.exports.sync = options => { /***/ }), -/* 718 */ +/* 716 */ /***/ (function(module, exports) { // A simple implementation of make-array @@ -84347,7 +84202,7 @@ module.exports = options => new IgnoreBase(options) /***/ }), -/* 719 */ +/* 717 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -84422,7 +84277,7 @@ module.exports = (input, options) => { /***/ }), -/* 720 */ +/* 718 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -84440,7 +84295,7 @@ module.exports = input => { /***/ }), -/* 721 */ +/* 719 */ /***/ (function(module, exports, __webpack_require__) { /*! @@ -84450,7 +84305,7 @@ module.exports = input => { * Released under the MIT License. */ -var isExtglob = __webpack_require__(310); +var isExtglob = __webpack_require__(302); var chars = { '{': '}', '(': ')', '[': ']'}; var strictRegex = /\\(.)|(^!|\*|[\].+)]\?|\[[^\\\]]+\]|\{[^\\}]+\}|\(\?[:!=][^\\)]+\)|\([^|]+\|[^\\)]+\))/; var relaxedRegex = /\\(.)|(^!|[*?{}()[\]]|\(\?)/; @@ -84494,17 +84349,17 @@ module.exports = function isGlob(str, options) { /***/ }), -/* 722 */ +/* 720 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const path = __webpack_require__(4); const {constants: fsConstants} = __webpack_require__(133); -const pEvent = __webpack_require__(723); -const CpFileError = __webpack_require__(726); -const fs = __webpack_require__(730); -const ProgressEmitter = __webpack_require__(733); +const pEvent = __webpack_require__(721); +const CpFileError = __webpack_require__(724); +const fs = __webpack_require__(728); +const ProgressEmitter = __webpack_require__(731); const cpFileAsync = async (source, destination, options, progressEmitter) => { let readError; @@ -84618,12 +84473,12 @@ module.exports.sync = (source, destination, options) => { /***/ }), -/* 723 */ +/* 721 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const pTimeout = __webpack_require__(724); +const pTimeout = __webpack_require__(722); const symbolAsyncIterator = Symbol.asyncIterator || '@@asyncIterator'; @@ -84914,12 +84769,12 @@ module.exports.iterator = (emitter, event, options) => { /***/ }), -/* 724 */ +/* 722 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const pFinally = __webpack_require__(725); +const pFinally = __webpack_require__(723); class TimeoutError extends Error { constructor(message) { @@ -84965,7 +84820,7 @@ module.exports.TimeoutError = TimeoutError; /***/ }), -/* 725 */ +/* 723 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -84987,12 +84842,12 @@ module.exports = (promise, onFinally) => { /***/ }), -/* 726 */ +/* 724 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const NestedError = __webpack_require__(727); +const NestedError = __webpack_require__(725); class CpFileError extends NestedError { constructor(message, nested) { @@ -85006,10 +84861,10 @@ module.exports = CpFileError; /***/ }), -/* 727 */ +/* 725 */ /***/ (function(module, exports, __webpack_require__) { -var inherits = __webpack_require__(728); +var inherits = __webpack_require__(726); var NestedError = function (message, nested) { this.nested = nested; @@ -85060,7 +84915,7 @@ module.exports = NestedError; /***/ }), -/* 728 */ +/* 726 */ /***/ (function(module, exports, __webpack_require__) { try { @@ -85068,12 +84923,12 @@ try { if (typeof util.inherits !== 'function') throw ''; module.exports = util.inherits; } catch (e) { - module.exports = __webpack_require__(729); + module.exports = __webpack_require__(727); } /***/ }), -/* 729 */ +/* 727 */ /***/ (function(module, exports) { if (typeof Object.create === 'function') { @@ -85102,16 +84957,16 @@ if (typeof Object.create === 'function') { /***/ }), -/* 730 */ +/* 728 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const {promisify} = __webpack_require__(111); const fs = __webpack_require__(132); -const makeDir = __webpack_require__(731); -const pEvent = __webpack_require__(723); -const CpFileError = __webpack_require__(726); +const makeDir = __webpack_require__(729); +const pEvent = __webpack_require__(721); +const CpFileError = __webpack_require__(724); const stat = promisify(fs.stat); const lstat = promisify(fs.lstat); @@ -85208,7 +85063,7 @@ exports.copyFileSync = (source, destination, flags) => { /***/ }), -/* 731 */ +/* 729 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -85216,7 +85071,7 @@ exports.copyFileSync = (source, destination, flags) => { const fs = __webpack_require__(133); const path = __webpack_require__(4); const {promisify} = __webpack_require__(111); -const semver = __webpack_require__(732); +const semver = __webpack_require__(730); const useNativeRecursiveOption = semver.satisfies(process.version, '>=10.12.0'); @@ -85371,7 +85226,7 @@ module.exports.sync = (input, options) => { /***/ }), -/* 732 */ +/* 730 */ /***/ (function(module, exports) { exports = module.exports = SemVer @@ -86973,7 +86828,7 @@ function coerce (version, options) { /***/ }), -/* 733 */ +/* 731 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -87014,7 +86869,7 @@ module.exports = ProgressEmitter; /***/ }), -/* 734 */ +/* 732 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -87060,12 +86915,12 @@ exports.default = module.exports; /***/ }), -/* 735 */ +/* 733 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const NestedError = __webpack_require__(736); +const NestedError = __webpack_require__(734); class CpyError extends NestedError { constructor(message, nested) { @@ -87079,7 +86934,7 @@ module.exports = CpyError; /***/ }), -/* 736 */ +/* 734 */ /***/ (function(module, exports, __webpack_require__) { var inherits = __webpack_require__(111).inherits; diff --git a/scripts/generate_plugin.js b/scripts/generate_plugin.js index e080afb183aa8..f695eabb30f21 100644 --- a/scripts/generate_plugin.js +++ b/scripts/generate_plugin.js @@ -17,5 +17,5 @@ * under the License. */ -require('../src/setup_node_env'); -require('@kbn/plugin-generator').run(process.argv.slice(2)); +require('../src/setup_node_env/prebuilt_dev_only_entry'); +require('@kbn/plugin-generator').runCli(); diff --git a/src/dev/file.ts b/src/dev/file.ts index 32998d3e776ef..1209cc323c4c3 100644 --- a/src/dev/file.ts +++ b/src/dev/file.ts @@ -17,7 +17,7 @@ * under the License. */ -import { dirname, extname, join, relative, resolve, sep } from 'path'; +import { dirname, extname, join, relative, resolve, sep, basename } from 'path'; export class File { private path: string; @@ -38,6 +38,12 @@ export class File { return this.relativePath; } + public getWithoutExtension() { + const directory = dirname(this.path); + const stem = basename(this.path, this.ext); + return new File(resolve(directory, stem)); + } + public isJs() { return this.ext === '.js'; } diff --git a/src/dev/i18n/tasks/extract_untracked_translations.ts b/src/dev/i18n/tasks/extract_untracked_translations.ts index 21ab47641f2f0..928997aced801 100644 --- a/src/dev/i18n/tasks/extract_untracked_translations.ts +++ b/src/dev/i18n/tasks/extract_untracked_translations.ts @@ -47,7 +47,7 @@ export async function extractUntrackedMessagesTask({ '**/build/**', '**/__fixtures__/**', '**/packages/kbn-i18n/**', - '**/packages/kbn-plugin-generator/sao_template/**', + '**/packages/kbn-plugin-generator/template/**', '**/packages/kbn-ui-framework/generator-kui/**', '**/target/**', '**/test/**', diff --git a/src/dev/precommit_hook/casing_check_config.js b/src/dev/precommit_hook/casing_check_config.js index 19d03e41ac5a9..e22dc03cf57aa 100644 --- a/src/dev/precommit_hook/casing_check_config.js +++ b/src/dev/precommit_hook/casing_check_config.js @@ -109,6 +109,14 @@ export const IGNORE_DIRECTORY_GLOBS = [ 'packages/kbn-optimizer/src/__fixtures__/mock_repo/x-pack', ]; +/** + * These patterns identify files which should have the extension stripped + * to reveal the actual name that should be checked. + * + * @type {Array} + */ +export const REMOVE_EXTENSION = ['packages/kbn-plugin-generator/template/**/*.ejs']; + /** * DO NOT ADD FILES TO THIS LIST!! * diff --git a/src/dev/precommit_hook/check_file_casing.js b/src/dev/precommit_hook/check_file_casing.js index ec77d9a8bad3c..243818d35a90b 100644 --- a/src/dev/precommit_hook/check_file_casing.js +++ b/src/dev/precommit_hook/check_file_casing.js @@ -29,6 +29,7 @@ import { IGNORE_FILE_GLOBS, TEMPORARILY_IGNORED_PATHS, KEBAB_CASE_DIRECTORY_GLOBS, + REMOVE_EXTENSION, } from './casing_check_config'; const NON_SNAKE_CASE_RE = /[A-Z \-]/; @@ -143,6 +144,10 @@ async function checkForSnakeCase(log, files) { } export async function checkFileCasing(log, files) { + files = files.map((f) => + matchesAnyGlob(f.getRelativePath(), REMOVE_EXTENSION) ? f.getWithoutExtension() : f + ); + await checkForKebabCase(log, files); await checkForSnakeCase(log, files); } diff --git a/yarn.lock b/yarn.lock index d13db64ad8b79..ed9dda820d66a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3663,6 +3663,11 @@ resolved "https://registry.yarnpkg.com/@types/dragselect/-/dragselect-1.13.1.tgz#f19b7b41063a7c9d5963194c83c3c364e84d46ee" integrity sha512-3m0fvSM0cSs0DXvprytV/ZY92hNX3jJuEb/vkdqU+4QMzV2jxYKgBFTuaT2fflqbmfzUqHHIkGP55WIuigElQw== +"@types/ejs@^3.0.4": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/ejs/-/ejs-3.0.4.tgz#8851fcdedb96e410fbb24f83b8be6763ef9afa77" + integrity sha512-ZxnwyBGO4KX/82AsFHTX82eMw0PsoBcIngEat+zx0y+3yxoNDJucAihg9nAcrc+g4Cwiv/4WcWsX4oiy0ySrRQ== + "@types/elasticsearch@^5.0.33": version "5.0.33" resolved "https://registry.yarnpkg.com/@types/elasticsearch/-/elasticsearch-5.0.33.tgz#b0fd37dc674f498223b6d68c313bdfd71f4d812b" @@ -3942,6 +3947,14 @@ "@types/through" "*" rxjs "^6.4.0" +"@types/inquirer@^7.3.1": + version "7.3.1" + resolved "https://registry.yarnpkg.com/@types/inquirer/-/inquirer-7.3.1.tgz#1f231224e7df11ccfaf4cf9acbcc3b935fea292d" + integrity sha512-osD38QVIfcdgsPCT0V3lD7eH0OFurX71Jft18bZrsVQWVRt6TuxRzlr0GJLrxoHZR2V5ph7/qP8se/dcnI7o0g== + dependencies: + "@types/through" "*" + rxjs "^6.4.0" + "@types/intl-relativeformat@^2.1.0": version "2.1.0" resolved "https://registry.yarnpkg.com/@types/intl-relativeformat/-/intl-relativeformat-2.1.0.tgz#3a2b0043380388f39c666665ec517e11412f1358" @@ -4348,6 +4361,11 @@ resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-1.19.1.tgz#33509849f8e679e4add158959fdb086440e9553f" integrity sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ== +"@types/prettier@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.0.2.tgz#5bb52ee68d0f8efa9cc0099920e56be6cc4e37f3" + integrity sha512-IkVfat549ggtkZUthUzEX49562eGikhSYeVGX97SkMFn+sTZrgRewXjQ4tPKFPCykZHkX1Zfd9OoELGqKU2jJA== + "@types/pretty-ms@^5.0.0": version "5.0.1" resolved "https://registry.yarnpkg.com/@types/pretty-ms/-/pretty-ms-5.0.1.tgz#f2f0d7be58caf8613d149053d446e0282ae11ff3" @@ -6535,6 +6553,11 @@ async-value@^1.2.2: resolved "https://registry.yarnpkg.com/async-value/-/async-value-1.2.2.tgz#84517a1e7cb6b1a5b5e181fa31be10437b7fb125" integrity sha1-hFF6Hny2saW14YH6Mb4QQ3t/sSU= +async@0.9.x: + version "0.9.2" + resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" + integrity sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0= + async@^1.4.2, async@^1.5.2, async@~1.5.2: version "1.5.2" resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" @@ -7485,7 +7508,7 @@ bowser@^1.7.3: resolved "https://registry.yarnpkg.com/bowser/-/bowser-1.9.4.tgz#890c58a2813a9d3243704334fa81b96a5c150c9a" integrity sha512-9IdMmj2KjigRq6oWhmwv1W36pDuA4STQZ8q6YO9um+x07xgYNCD3Oou+WP/3L1HNz7iqythGet3/p4wvc8AAwQ== -boxen@^1.2.1, boxen@^1.2.2: +boxen@^1.2.1: version "1.3.0" resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b" integrity sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw== @@ -7749,15 +7772,6 @@ buffer-xor@^1.0.3: resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= -buffer@^3.0.1: - version "3.6.0" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-3.6.0.tgz#a72c936f77b96bf52f5f7e7b467180628551defb" - integrity sha1-pyyTb3e5a/UvX357RnGAYoVR3vs= - dependencies: - base64-js "0.0.8" - ieee754 "^1.1.4" - isarray "^1.0.0" - buffer@^4.3.0: version "4.9.1" resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" @@ -7800,31 +7814,6 @@ bytes@3.1.0: resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== -cac@^3.0.3: - version "3.0.4" - resolved "https://registry.yarnpkg.com/cac/-/cac-3.0.4.tgz#6d24ceec372efe5c9b798808bc7f49b47242a4ef" - integrity sha1-bSTO7Dcu/lybeYgIvH9JtHJCpO8= - dependencies: - camelcase-keys "^3.0.0" - chalk "^1.1.3" - indent-string "^3.0.0" - minimist "^1.2.0" - read-pkg-up "^1.0.1" - suffix "^0.1.0" - text-table "^0.2.0" - -cac@^4.3.4: - version "4.4.1" - resolved "https://registry.yarnpkg.com/cac/-/cac-4.4.1.tgz#c6867f731c4be7b0c270689d1689400b914c7788" - integrity sha512-Ab4JHxgvSNI6niHz5M3JCYRXnzERhY314HDwkndOh7FmIyOX7xY+iUqsl0nE17wjt8+kdvxw+b1HDtmFMiVPNA== - dependencies: - chalk "^2.0.1" - minimost "^1.0.0" - read-pkg-up "^2.0.0" - redent "^2.0.0" - string-width "^2.1.1" - text-table "^0.2.0" - cacache@^12.0.2: version "12.0.4" resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.4.tgz#668bcbd105aeb5f1d92fe25570ec9525c8faa40c" @@ -8035,14 +8024,6 @@ camelcase-keys@^2.0.0: camelcase "^2.0.0" map-obj "^1.0.0" -camelcase-keys@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-3.0.0.tgz#fc0c6c360363f7377e3793b9a16bccf1070c1ca4" - integrity sha1-/AxsNgNj9zd+N5O5oWvM8QcMHKQ= - dependencies: - camelcase "^3.0.0" - map-obj "^1.0.0" - camelcase-keys@^4.0.0: version "4.2.0" resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-4.2.0.tgz#a2aa5fb1af688758259c32c141426d78923b9b77" @@ -8176,16 +8157,6 @@ catbox@10.x.x: hoek "5.x.x" joi "13.x.x" -caw@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/caw/-/caw-2.0.1.tgz#6c3ca071fc194720883c2dc5da9b074bfc7e9e95" - integrity sha512-Cg8/ZSBEa8ZVY9HspcGUYaK63d/bN7rqS3CYCzEGUxuYv6UlmcjzDUz2fCFFHyTvUW5Pk0I+3hkA3iXlIj6guA== - dependencies: - get-proxy "^2.0.0" - isurl "^1.0.0-alpha5" - tunnel-agent "^0.6.0" - url-to-options "^1.0.1" - ccount@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.0.3.tgz#f1cec43f332e2ea5a569fd46f9f5bde4e6102aff" @@ -8336,11 +8307,6 @@ chardet@^0.4.0: resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" integrity sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I= -chardet@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.5.0.tgz#fe3ac73c00c3d865ffcc02a0682e2c20b6a06029" - integrity sha512-9ZTaoBaePSCFvNlNGrsyI8ZVACP2svUtq0DkM7t4K2ClAa96sqOIRjAzDTc8zXzFt1cZR46rRzLTiHFSJ+Qw0g== - chardet@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" @@ -8850,11 +8816,6 @@ cmd-shim@^2.1.0: graceful-fs "^4.1.2" mkdirp "~0.5.0" -co@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/co/-/co-3.1.0.tgz#4ea54ea5a08938153185e15210c68d9092bc1b78" - integrity sha1-TqVOpaCJOBUxheFSEMaNkJK8G3g= - co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" @@ -9086,13 +9047,6 @@ commander@^5.0.0: resolved "https://registry.yarnpkg.com/commander/-/commander-5.0.0.tgz#dbf1909b49e5044f8fdaf0adc809f0c0722bdfd0" integrity sha512-JrDGPAKjMGSP1G0DUoaceEJ3DZgAfr/q6X7FVk4+U5KxUSKviYGM2k6zWkfyyBHy5rAtzgYJFa1ro2O9PtoxwQ== -commander@~2.8.1: - version "2.8.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.8.1.tgz#06be367febfda0c330aa1e2a072d3dc9762425d4" - integrity sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ= - dependencies: - graceful-readlink ">= 1.0.0" - common-tags@1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.0.tgz#8e3153e542d4a39e9b10554434afaaf98956a937" @@ -9197,7 +9151,7 @@ concat-stream@~2.0.0: readable-stream "^3.0.2" typedarray "^0.0.6" -conf@^1.1.2, conf@^1.3.1: +conf@^1.3.1: version "1.4.0" resolved "https://registry.yarnpkg.com/conf/-/conf-1.4.0.tgz#1ea66c9d7a9b601674a5bb9d2b8dc3c726625e67" integrity sha512-bzlVWS2THbMetHqXKB8ypsXN4DQ/1qopGwNJi1eYbpwesJcd86FBjFciCQX/YwAhp9bM7NVnPFqZ5LpV7gP0Dg== @@ -9702,15 +9656,7 @@ cross-spawn@^3.0.0: lru-cache "^4.0.1" which "^1.2.9" -cross-spawn@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41" - integrity sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE= - dependencies: - lru-cache "^4.0.1" - which "^1.2.9" - -cross-spawn@^5.0.1, cross-spawn@^5.1.0: +cross-spawn@^5.0.1: version "5.1.0" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= @@ -10382,59 +10328,6 @@ decompress-response@^5.0.0: dependencies: mimic-response "^2.0.0" -decompress-tar@^4.0.0, decompress-tar@^4.1.0, decompress-tar@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/decompress-tar/-/decompress-tar-4.1.1.tgz#718cbd3fcb16209716e70a26b84e7ba4592e5af1" - integrity sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ== - dependencies: - file-type "^5.2.0" - is-stream "^1.1.0" - tar-stream "^1.5.2" - -decompress-tarbz2@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz#3082a5b880ea4043816349f378b56c516be1a39b" - integrity sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A== - dependencies: - decompress-tar "^4.1.0" - file-type "^6.1.0" - is-stream "^1.1.0" - seek-bzip "^1.0.5" - unbzip2-stream "^1.0.9" - -decompress-targz@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/decompress-targz/-/decompress-targz-4.1.1.tgz#c09bc35c4d11f3de09f2d2da53e9de23e7ce1eee" - integrity sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w== - dependencies: - decompress-tar "^4.1.1" - file-type "^5.2.0" - is-stream "^1.1.0" - -decompress-unzip@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/decompress-unzip/-/decompress-unzip-4.0.1.tgz#deaaccdfd14aeaf85578f733ae8210f9b4848f69" - integrity sha1-3qrM39FK6vhVePczroIQ+bSEj2k= - dependencies: - file-type "^3.8.0" - get-stream "^2.2.0" - pify "^2.3.0" - yauzl "^2.4.2" - -decompress@^4.0.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/decompress/-/decompress-4.2.1.tgz#007f55cc6a62c055afa37c07eb6a4ee1b773f118" - integrity sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ== - dependencies: - decompress-tar "^4.0.0" - decompress-tarbz2 "^4.0.0" - decompress-targz "^4.0.0" - decompress-unzip "^4.0.1" - graceful-fs "^4.1.10" - make-dir "^1.0.0" - pify "^2.3.0" - strip-dirs "^2.0.0" - dedent@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" @@ -11180,28 +11073,6 @@ downgrade-root@^1.0.0: default-uid "^1.0.0" is-root "^1.0.0" -download-git-repo@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/download-git-repo/-/download-git-repo-1.0.2.tgz#0b93a62057e41e2f21b1a06c95e7b26362b108ff" - integrity sha512-PwAUr0/w74AGB7bukOycXyLnDlt9Lfb3JzsliAWyZCHa/TvbuMYQvH1er2DWXHE4EuI/NjAzRXw+89Waynapgw== - dependencies: - download "^5.0.3" - git-clone "^0.1.0" - rimraf "^2.6.1" - -download@^5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/download/-/download-5.0.3.tgz#63537f977f99266a30eb8a2a2fbd1f20b8000f7a" - integrity sha1-Y1N/l3+ZJmow64oqL70fILgAD3o= - dependencies: - caw "^2.0.0" - decompress "^4.0.0" - filenamify "^2.0.0" - get-stream "^3.0.0" - got "^6.3.0" - mkdirp "^0.5.1" - pify "^2.3.0" - dragselect@1.13.1: version "1.13.1" resolved "https://registry.yarnpkg.com/dragselect/-/dragselect-1.13.1.tgz#aa4166e1164b51ed5ee0cd89e0c5310a9c35be6a" @@ -11313,20 +11184,17 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= -ejs@^2.2.4, ejs@^2.3.1: - version "2.5.7" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.5.7.tgz#cc872c168880ae3c7189762fd5ffc00896c9518a" - integrity sha1-zIcsFoiArjxxiXYv1f/ACJbJUYo= - -ejs@^2.7.4: +ejs@^2.3.1, ejs@^2.7.4: version "2.7.4" resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.7.4.tgz#48661287573dcc53e366c7a1ae52c3a120eec9ba" integrity sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA== -ejs@^3.0.1: - version "3.0.2" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.0.2.tgz#745b01cdcfe38c1c6a2da3bbb2d9957060a31226" - integrity sha512-IncmUpn1yN84hy2shb0POJ80FWrfGNY0cxO9f4v+/sG7qcBvAtVWUA1IdzY/8EYUmOVhoKJVdJjNd3AZcnxOjA== +ejs@^3.0.1, ejs@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.5.tgz#aed723844dc20acb4b170cd9ab1017e476a0d93b" + integrity sha512-dldq3ZfFtgVTJMLjOe+/3sROTzALlL9E34V4/sDtUd/KlBSS0s6U1/+WPE1B4sj9CXHJpL1M6rhNJnc9Wbal9w== + dependencies: + jake "^10.6.1" elastic-apm-http-client@^9.4.0: version "9.4.0" @@ -12714,15 +12582,6 @@ external-editor@^1.1.0: spawn-sync "^1.0.15" tmp "^0.0.29" -external-editor@^2.0.4: - version "2.1.0" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.1.0.tgz#3d026a21b7f95b5726387d4200ac160d372c3b48" - integrity sha512-E44iT5QVOUJBKij4IIV3uvxuNlbKS38Tw1HiupxEIHPv9qtC2PrDYohbXV5U+1jnfIXttny8gUhj+oZvflFlzA== - dependencies: - chardet "^0.4.0" - iconv-lite "^0.4.17" - tmp "^0.0.33" - external-editor@^2.1.0: version "2.2.0" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" @@ -12732,19 +12591,10 @@ external-editor@^2.1.0: iconv-lite "^0.4.17" tmp "^0.0.33" -external-editor@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.0.0.tgz#dc35c48c6f98a30ca27a20e9687d7f3c77704bb6" - integrity sha512-mpkfj0FEdxrIhOC04zk85X7StNtr0yXnG7zCb+8ikO8OJi2jsHh5YGoknNTyXgsbHOf1WOOcVU3kPFWT2WgCkQ== - dependencies: - chardet "^0.5.0" - iconv-lite "^0.4.22" - tmp "^0.0.33" - external-editor@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.0.3.tgz#5866db29a97826dbe4bf3afd24070ead9ea43a27" - integrity sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA== + version "3.1.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" + integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== dependencies: chardet "^0.7.0" iconv-lite "^0.4.24" @@ -12939,7 +12789,7 @@ fb-watchman@^2.0.0: dependencies: bser "^2.0.0" -fbjs@^0.8.0, fbjs@^0.8.1, fbjs@^0.8.16: +fbjs@^0.8.0, fbjs@^0.8.1, fbjs@^0.8.16, fbjs@^0.8.4, fbjs@^0.8.9: version "0.8.17" resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.17.tgz#c4d598ead6949112653d6588b01a5cdcd9f90fdd" integrity sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90= @@ -12952,19 +12802,6 @@ fbjs@^0.8.0, fbjs@^0.8.1, fbjs@^0.8.16: setimmediate "^1.0.5" ua-parser-js "^0.7.18" -fbjs@^0.8.4, fbjs@^0.8.9: - version "0.8.16" - resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db" - integrity sha1-XmdDL1UNxBtXK/VYR7ispk5TN9s= - dependencies: - core-js "^1.0.0" - isomorphic-fetch "^2.1.1" - loose-envify "^1.0.0" - object-assign "^4.1.0" - promise "^7.1.1" - setimmediate "^1.0.5" - ua-parser-js "^0.7.9" - fd-slicer@1.1.0, fd-slicer@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" @@ -12972,13 +12809,6 @@ fd-slicer@1.1.0, fd-slicer@~1.1.0: dependencies: pend "~1.2.0" -fd-slicer@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.0.1.tgz#8b5bcbd9ec327c5041bf9ab023fd6750f1177e65" - integrity sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU= - dependencies: - pend "~1.2.0" - fecha@^2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/fecha/-/fecha-2.3.3.tgz#948e74157df1a32fd1b12c3a3c3cdcb6ec9d96cd" @@ -13079,21 +12909,6 @@ file-type@^10.9.0: resolved "https://registry.yarnpkg.com/file-type/-/file-type-10.9.0.tgz#f6c12c7cb9e6b8aeefd6917555fd4f9eadf31891" integrity sha512-9C5qtGR/fNibHC5gzuMmmgnjH3QDDLKMa8lYe9CiZVmAnI4aUaoMh40QyUPzzs0RYo837SOBKh7TYwle4G8E4w== -file-type@^3.8.0: - version "3.9.0" - resolved "https://registry.yarnpkg.com/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9" - integrity sha1-JXoHg4TR24CHvESdEH1SpSZyuek= - -file-type@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/file-type/-/file-type-5.2.0.tgz#2ddbea7c73ffe36368dfae49dc338c058c2b8ad6" - integrity sha1-LdvqfHP/42No365J3DOMBYwritY= - -file-type@^6.1.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/file-type/-/file-type-6.2.0.tgz#e50cd75d356ffed4e306dc4f5bcf52a79903a919" - integrity sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg== - file-type@^9.0.0: version "9.0.0" resolved "https://registry.yarnpkg.com/file-type/-/file-type-9.0.0.tgz#a68d5ad07f486414dfb2c8866f73161946714a18" @@ -13104,19 +12919,12 @@ file-uri-to-path@1.0.0: resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== -filename-reserved-regex@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz#abf73dfab735d045440abfea2d91f389ebbfa229" - integrity sha1-q/c9+rc10EVECr/qLZHzieu/oik= - -filenamify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/filenamify/-/filenamify-2.0.0.tgz#bd162262c0b6e94bfbcdcf19a3bbb3764f785695" - integrity sha1-vRYiYsC26Uv7zc8Zo7uzdk94VpU= +filelist@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.1.tgz#f10d1a3ae86c1694808e8f20906f43d4c9132dbb" + integrity sha512-8zSK6Nu0DQIC08mUC46sWGXi+q3GGpKydAG36k+JDba6VRpkevvOWUW5a/PhShij4+vHT9M+ghgG7eM+a9JDUQ== dependencies: - filename-reserved-regex "^2.0.0" - strip-outer "^1.0.0" - trim-repeated "^1.0.0" + minimatch "^3.0.4" filesize@3.6.1: version "3.6.1" @@ -13618,11 +13426,6 @@ fs-constants@^1.0.0: resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== -fs-exists-sync@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz#982d6893af918e72d08dec9e8673ff2b5a8d6add" - integrity sha1-mC1ok6+RjnLQjeyehnP/K1qNat0= - fs-extra@8.1.0, fs-extra@^8.0.1, fs-extra@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" @@ -13652,15 +13455,6 @@ fs-extra@^3.0.1: jsonfile "^3.0.0" universalify "^0.1.0" -fs-extra@^4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" - integrity sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg== - dependencies: - graceful-fs "^4.1.2" - jsonfile "^4.0.0" - universalify "^0.1.0" - fs-extra@^7.0.0, fs-extra@^7.0.1, fs-extra@~7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" @@ -13905,13 +13699,6 @@ get-port@^4.2.0: resolved "https://registry.yarnpkg.com/get-port/-/get-port-4.2.0.tgz#e37368b1e863b7629c43c5a323625f95cf24b119" integrity sha512-/b3jarXkH8KJoOMQc3uVGHASwGLPq3gSFJ7tgJm2diza+bydJPTGOibin2steecKeOylE8oY2JERlVWkAJO6yw== -get-proxy@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/get-proxy/-/get-proxy-2.1.0.tgz#349f2b4d91d44c4d4d4e9cba2ad90143fac5ef93" - integrity sha512-zmZIaQTWnNQb4R4fJUEp/FC51eZsc6EkErspy3xtIYStaq8EB/hDIWipxsal+E8rz0qD7f2sL/NA9Xee4RInJw== - dependencies: - npm-conf "^1.1.0" - get-stdin@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" @@ -13927,14 +13714,6 @@ get-stream@3.0.0, get-stream@^3.0.0: resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= -get-stream@^2.2.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de" - integrity sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4= - dependencies: - object-assign "^4.0.1" - pinkie-promise "^2.0.0" - get-stream@^4.0.0, get-stream@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" @@ -13999,20 +13778,6 @@ gifwrap@^0.9.2: image-q "^1.1.1" omggif "^1.0.10" -git-clone@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/git-clone/-/git-clone-0.1.0.tgz#0d76163778093aef7f1c30238f2a9ef3f07a2eb9" - integrity sha1-DXYWN3gJOu9/HDAjjyqe8/B6Lrk= - -git-config-path@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/git-config-path/-/git-config-path-1.0.1.tgz#6d33f7ed63db0d0e118131503bab3aca47d54664" - integrity sha1-bTP37WPbDQ4RgTFQO6s6ykfVRmQ= - dependencies: - extend-shallow "^2.0.1" - fs-exists-sync "^0.1.0" - homedir-polyfill "^1.0.0" - git-up@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/git-up/-/git-up-4.0.1.tgz#cb2ef086653640e721d2042fe3104857d89007c0" @@ -14480,7 +14245,7 @@ got@^3.2.0: read-all-stream "^3.0.0" timed-out "^2.0.0" -got@^6.2.0, got@^6.3.0, got@^6.7.1: +got@^6.2.0, got@^6.7.1: version "6.7.1" resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" integrity sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA= @@ -14557,27 +14322,7 @@ got@^9.6.0: to-readable-stream "^1.0.0" url-parse-lax "^3.0.0" -graceful-fs@4.X, graceful-fs@^4.0.0, graceful-fs@^4.1.10, graceful-fs@^4.1.11, graceful-fs@^4.1.4: - version "4.1.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" - integrity sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg= - -graceful-fs@^4.1.15, graceful-fs@^4.1.9: - version "4.1.15" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" - integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== - -graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.2: - version "4.2.3" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" - integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== - -graceful-fs@^4.2.0: - version "4.2.2" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.2.tgz#6f0952605d0140c1cfdb138ed005775b92d67b02" - integrity sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q== - -graceful-fs@^4.2.3, graceful-fs@^4.2.4: +graceful-fs@4.X, graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.4, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.2, graceful-fs@^4.2.3, graceful-fs@^4.2.4: version "4.2.4" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== @@ -14587,11 +14332,6 @@ graceful-fs@~1.1: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-1.1.14.tgz#07078db5f6377f6321fceaaedf497de124dc9465" integrity sha1-BweNtfY3f2Mh/Oqu30l94STclGU= -"graceful-readlink@>= 1.0.0": - version "1.0.1" - resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" - integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU= - graphql-anywhere@^4.1.0-alpha.0: version "4.1.16" resolved "https://registry.yarnpkg.com/graphql-anywhere/-/graphql-anywhere-4.1.16.tgz#82bb59643e30183cfb7b485ed4262a7b39d8a6c1" @@ -15082,7 +14822,7 @@ handle-thing@^2.0.0: resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.0.tgz#0e039695ff50c93fc288557d696f3c1dc6776754" integrity sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ== -handlebars@4.7.6, handlebars@^4.0.1: +handlebars@4.7.6: version "4.7.6" resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.6.tgz#d4c05c1baf90e9945f77aa68a7a219aa4a7df74e" integrity sha512-1f2BACcBfiwAfStCKZNrUCgqNZkGsAT7UM3kkYtXuLo0KnaVfjKOyf7PRzB6++aK9STyT1Pd2ZCPe3EGOXleXA== @@ -15418,7 +15158,7 @@ hoist-non-react-statics@^2.3.1, hoist-non-react-statics@^2.5.0, hoist-non-react- dependencies: react-is "^16.7.0" -homedir-polyfill@^1.0.0, homedir-polyfill@^1.0.1: +homedir-polyfill@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz#4c2bbc8a758998feebf5ed68580f76d46768b4bc" integrity sha1-TCu8inWJmP7r9e1oWA921GdotLw= @@ -15731,7 +15471,7 @@ icalendar@0.7.1: resolved "https://registry.yarnpkg.com/icalendar/-/icalendar-0.7.1.tgz#d0d3486795f8f1c5cf4f8cafac081b4b4e7a32ae" integrity sha1-0NNIZ5X48cXPT4yvrAgbS056Mq4= -iconv-lite@0.4, iconv-lite@0.4.24, iconv-lite@^0.4.17, iconv-lite@^0.4.22, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13: +iconv-lite@0.4, iconv-lite@0.4.24, iconv-lite@^0.4.17, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== @@ -16115,26 +15855,6 @@ inquirer@^1.0.2, inquirer@^1.2.2: strip-ansi "^3.0.0" through "^2.3.6" -inquirer@^3.2.3: - version "3.3.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9" - integrity sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ== - dependencies: - ansi-escapes "^3.0.0" - chalk "^2.0.0" - cli-cursor "^2.1.0" - cli-width "^2.0.0" - external-editor "^2.0.4" - figures "^2.0.0" - lodash "^4.3.0" - mute-stream "0.0.7" - run-async "^2.2.0" - rx-lite "^4.0.8" - rx-lite-aggregates "^4.0.8" - string-width "^2.1.0" - strip-ansi "^4.0.0" - through "^2.3.6" - inquirer@^5.0.0: version "5.2.0" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-5.2.0.tgz#db350c2b73daca77ff1243962e9f22f099685726" @@ -16155,47 +15875,28 @@ inquirer@^5.0.0: through "^2.3.6" inquirer@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.0.0.tgz#e8c20303ddc15bbfc2c12a6213710ccd9e1413d8" - integrity sha512-tISQWRwtcAgrz+SHPhTH7d3e73k31gsOy6i1csonLc0u1dVK/wYvuOnFeiWqC5OXFIYbmrIFInef31wbT8MEJg== + version "6.5.2" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.2.tgz#ad50942375d036d327ff528c08bd5fab089928ca" + integrity sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ== dependencies: - ansi-escapes "^3.0.0" - chalk "^2.0.0" + ansi-escapes "^3.2.0" + chalk "^2.4.2" cli-cursor "^2.1.0" cli-width "^2.0.0" - external-editor "^3.0.0" + external-editor "^3.0.3" figures "^2.0.0" - lodash "^4.3.0" + lodash "^4.17.12" mute-stream "0.0.7" run-async "^2.2.0" - rxjs "^6.1.0" - string-width "^2.1.0" - strip-ansi "^4.0.0" - through "^2.3.6" - -inquirer@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.0.0.tgz#9e2b032dde77da1db5db804758b8fea3a970519a" - integrity sha512-rSdC7zelHdRQFkWnhsMu2+2SO41mpv2oF2zy4tMhmiLWkcKbOAs87fWAJhVXttKVwhdZvymvnuM95EyEXg2/tQ== - dependencies: - ansi-escapes "^4.2.1" - chalk "^2.4.2" - cli-cursor "^3.1.0" - cli-width "^2.0.0" - external-editor "^3.0.3" - figures "^3.0.0" - lodash "^4.17.15" - mute-stream "0.0.8" - run-async "^2.2.0" rxjs "^6.4.0" - string-width "^4.1.0" + string-width "^2.1.0" strip-ansi "^5.1.0" through "^2.3.6" -inquirer@^7.3.1: - version "7.3.1" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.3.1.tgz#ac6aba1abdfdd5ad34e7069370411edba17f6439" - integrity sha512-/+vOpHQHhoh90Znev8BXiuw1TDQ7IDxWsQnFafUEoK5+4uN5Eoz1p+3GqOj/NtzEi9VzWKQcV9Bm+i8moxedsA== +inquirer@^7.0.0, inquirer@^7.3.1, inquirer@^7.3.3: + version "7.3.3" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.3.3.tgz#04d176b2af04afc157a83fd7c100e98ee0aad003" + integrity sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA== dependencies: ansi-escapes "^4.2.1" chalk "^4.1.0" @@ -16203,7 +15904,7 @@ inquirer@^7.3.1: cli-width "^3.0.0" external-editor "^3.0.3" figures "^3.0.0" - lodash "^4.17.16" + lodash "^4.17.19" mute-stream "0.0.8" run-async "^2.4.0" rxjs "^6.6.0" @@ -16430,13 +16131,6 @@ is-binary-path@^1.0.0: dependencies: binary-extensions "^1.0.0" -is-binary-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.0.0.tgz#0e61cea6974b24dda8bcc8366ce58a69265d1a36" - integrity sha1-DmHOppdLJN2ovMg2bOWKaSZdGjY= - dependencies: - binary-extensions "^1.0.0" - is-binary-path@~2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" @@ -16722,11 +16416,6 @@ is-native@^1.0.1: is-nil "^1.0.0" to-source-code "^1.0.0" -is-natural-number@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/is-natural-number/-/is-natural-number-4.0.1.tgz#ab9d76e1db4ced51e35de0c72ebecf09f734cde8" - integrity sha1-q5124dtM7VHjXeDHLr7PCfc0zeg= - is-negated-glob@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-negated-glob/-/is-negated-glob-1.0.0.tgz#6910bca5da8c95e784b5751b976cf5a10fee36d2" @@ -16865,7 +16554,7 @@ is-plain-object@3.0.0, is-plain-object@^3.0.0: dependencies: isobject "^4.0.0" -is-promise@^2.0.0, is-promise@^2.1, is-promise@^2.1.0: +is-promise@^2.1, is-promise@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= @@ -17316,6 +17005,16 @@ iterate-value@^1.0.0: es-get-iterator "^1.0.2" iterate-iterator "^1.0.1" +jake@^10.6.1: + version "10.8.2" + resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.2.tgz#ebc9de8558160a66d82d0eadc6a2e58fbc500a7b" + integrity sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A== + dependencies: + async "0.9.x" + chalk "^2.4.2" + filelist "^1.0.1" + minimatch "^3.0.4" + jest-canvas-mock@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/jest-canvas-mock/-/jest-canvas-mock-2.2.0.tgz#45fbc58589c6ce9df50dc90bd8adce747cbdada7" @@ -18233,28 +17932,6 @@ jssha@^2.1.0: resolved "https://registry.yarnpkg.com/jssha/-/jssha-2.3.1.tgz#147b2125369035ca4b2f7d210dc539f009b3de9a" integrity sha1-FHshJTaQNcpLL30hDcU58Amz3po= -jstransformer-ejs@^0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/jstransformer-ejs/-/jstransformer-ejs-0.0.3.tgz#04d9201469274fcf260f1e7efd732d487fa234b6" - integrity sha1-BNkgFGknT88mDx5+/XMtSH+iNLY= - dependencies: - ejs "^2.2.4" - -jstransformer-handlebars@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/jstransformer-handlebars/-/jstransformer-handlebars-1.1.0.tgz#91ba56e0a28aee31bb56d4adbcbce508d8230468" - integrity sha1-kbpW4KKK7jG7VtStvLzlCNgjBGg= - dependencies: - handlebars "^4.0.1" - -jstransformer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/jstransformer/-/jstransformer-1.0.0.tgz#ed8bf0921e2f3f1ed4d5c1a44f68709ed24722c3" - integrity sha1-7Yvwkh4vPx7U1cGkT2hwntJHIsM= - dependencies: - is-promise "^2.0.0" - promise "^7.0.1" - jsts@^1.6.2: version "1.6.2" resolved "https://registry.yarnpkg.com/jsts/-/jsts-1.6.2.tgz#c0efc885edae06ae84f78cbf2a0110ba929c5925" @@ -18446,20 +18123,6 @@ known-css-properties@^0.3.0: resolved "https://registry.yarnpkg.com/known-css-properties/-/known-css-properties-0.3.0.tgz#a3d135bbfc60ee8c6eacf2f7e7e6f2d4755e49a4" integrity sha512-QMQcnKAiQccfQTqtBh/qwquGZ2XK/DXND1jrcN9M8gMMy99Gwla7GQjndVUsEqIaRyP6bsFRuhwRj5poafBGJQ== -kopy@^8.2.0: - version "8.2.5" - resolved "https://registry.yarnpkg.com/kopy/-/kopy-8.2.5.tgz#6c95f312e981ab917680d7e5de3cdf29a1bf221f" - integrity sha512-+U+LMXZtpRjU5JSGNsXeUG3k/Xvf+7NBQTdP7PxzUNBzLNkyoWxbDkvRchNFh3ANcucJKX/s6+cGxmmPUBBtww== - dependencies: - inquirer "^3.2.3" - is-binary-path "^2.0.0" - jstransformer "^1.0.0" - jstransformer-ejs "^0.0.3" - majo "^0.4.1" - minimatch "^3.0.4" - multimatch "^2.1.0" - path-exists "^3.0.0" - kuler@1.0.x: version "1.0.1" resolved "https://registry.yarnpkg.com/kuler/-/kuler-1.0.1.tgz#ef7c784f36c9fb6e16dd3150d152677b2b0228a6" @@ -19178,7 +18841,7 @@ lodash.uniq@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= -lodash@4.17.11, lodash@4.17.15, lodash@4.17.19, lodash@>4.17.4, lodash@^4, lodash@^4.0.0, lodash@^4.0.1, lodash@^4.10.0, lodash@^4.11.1, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.16, lodash@^4.17.19, lodash@^4.17.2, lodash@^4.17.20, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@~4.17.10, lodash@~4.17.15, lodash@~4.17.5: +lodash@4.17.11, lodash@4.17.15, lodash@4.17.19, lodash@>4.17.4, lodash@^4, lodash@^4.0.0, lodash@^4.0.1, lodash@^4.10.0, lodash@^4.11.1, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.2, lodash@^4.17.20, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@~4.17.10, lodash@~4.17.15, lodash@~4.17.5: version "4.17.20" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== @@ -19437,15 +19100,6 @@ magic-string@0.25.1: dependencies: sourcemap-codec "^1.4.1" -majo@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/majo/-/majo-0.4.1.tgz#5e6eeb9b63bda77e59d396b9c9ce4189ce6100bc" - integrity sha512-+Ys9ffqdJP9IAE8V8J6xSpemt1i6aleHhpk9R+K0GBkUKd6PE/oOW7GR9FFB5jHodxmX0lWeOezBc5OSoywDhw== - dependencies: - fs-extra "^3.0.1" - globby "^6.1.0" - ware "^1.3.0" - make-dir@^1.0.0: version "1.3.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" @@ -20091,14 +19745,6 @@ minimist@1.2.5, minimist@^1.1.0, minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2 resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== -minimost@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/minimost/-/minimost-1.0.0.tgz#1d07954aa0268873408b95552fbffc5977dfc78b" - integrity sha1-HQeVSqAmiHNAi5VVL7/8WXffx4s= - dependencies: - camelcase-keys "^4.0.0" - minimist "^1.2.0" - minipass-collect@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" @@ -20432,7 +20078,7 @@ multicast-dns@^6.0.1: dns-packet "^1.3.1" thunky "^1.0.2" -multimatch@^2.0.0, multimatch@^2.1.0: +multimatch@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b" integrity sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis= @@ -21108,7 +20754,7 @@ npm-bundled@^1.0.1: dependencies: npm-normalize-package-bin "^1.0.1" -npm-conf@^1.1.0, npm-conf@^1.1.3: +npm-conf@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/npm-conf/-/npm-conf-1.1.3.tgz#256cc47bd0e218c259c4e9550bf413bc2192aff9" integrity sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw== @@ -21625,7 +21271,7 @@ ora@^0.2.3: cli-spinners "^0.1.2" object-assign "^4.0.1" -ora@^1.3.0, ora@^1.4.0: +ora@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/ora/-/ora-1.4.0.tgz#884458215b3a5d4097592285f93321bb7a79e2e5" integrity sha512-iMK1DOQxzzh2MBlVsU42G80mnrvUhqsMh74phHtDlrcTZPK0pH6o7l7DRshK+0YsxDyEuaOkziVdvM3T0QTzpw== @@ -22092,16 +21738,6 @@ parse-filepath@^1.0.1: map-cache "^0.2.0" path-root "^0.1.1" -parse-git-config@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/parse-git-config/-/parse-git-config-1.1.1.tgz#d3a9984317132f57398712bba438e129590ddf8c" - integrity sha1-06mYQxcTL1c5hxK7pDjhKVkN34w= - dependencies: - extend-shallow "^2.0.1" - fs-exists-sync "^0.1.0" - git-config-path "^1.0.1" - ini "^1.3.4" - parse-headers@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.1.tgz#6ae83a7aa25a9d9b700acc28698cd1f1ed7e9536" @@ -22966,7 +22602,7 @@ promise.prototype.finally@^3.1.0: es-abstract "^1.9.0" function-bind "^1.1.1" -promise@^7.0.1, promise@^7.1.1: +promise@^7.1.1: version "7.3.1" resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg== @@ -25483,18 +25119,6 @@ rw@~0.1.4: resolved "https://registry.yarnpkg.com/rw/-/rw-0.1.4.tgz#4903cbd80248ae0ede685bf58fd236a7a9b29a3e" integrity sha1-SQPL2AJIrg7eaFv1j9I2p6mymj4= -rx-lite-aggregates@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be" - integrity sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74= - dependencies: - rx-lite "*" - -rx-lite@*, rx-lite@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" - integrity sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ= - rx-lite@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102" @@ -25605,33 +25229,6 @@ sane@^4.0.3: minimist "^1.1.1" walker "~1.0.5" -sao@^0.22.12: - version "0.22.12" - resolved "https://registry.yarnpkg.com/sao/-/sao-0.22.12.tgz#fe13bb32bb0d32892c188024f77c5ac26c19eaf9" - integrity sha512-ybJxqUg2wvmnBZ6LBNV2L3ermzjP4RFpti0MSXX3VI+Weaw5wBhgB0umvgeWkyObKhsuP1TmZ22XGfi6v+o1LQ== - dependencies: - boxen "^1.2.2" - cac "^4.3.4" - chalk "^2.0.1" - co "^4.6.0" - conf "^1.1.2" - cross-spawn "^5.1.0" - download-git-repo "^1.0.1" - filenamify "^2.0.0" - fs-extra "^4.0.1" - git-config-path "^1.0.1" - globby "^6.1.0" - jstransformer-handlebars "^1.0.0" - kopy "^8.2.0" - ora "^1.3.0" - parse-git-config "^1.1.1" - semver "^5.4.1" - text-table "^0.2.0" - tildify "^1.2.0" - update-notifier "^2.2.0" - user-home "^2.0.0" - yarn-install "^0.5.1" - sass-graph@^2.2.4: version "2.2.4" resolved "https://registry.yarnpkg.com/sass-graph/-/sass-graph-2.2.4.tgz#13fbd63cd1caf0908b9fd93476ad43a51d1e0b49" @@ -25777,13 +25374,6 @@ seedrandom@^3.0.5: resolved "https://registry.yarnpkg.com/seedrandom/-/seedrandom-3.0.5.tgz#54edc85c95222525b0c7a6f6b3543d8e0b3aa0a7" integrity sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg== -seek-bzip@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/seek-bzip/-/seek-bzip-1.0.5.tgz#cfe917cb3d274bcffac792758af53173eb1fabdc" - integrity sha1-z+kXyz0nS8/6x5J1ivUxc+sfq9w= - dependencies: - commander "~2.8.1" - select-hose@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" @@ -27155,13 +26745,6 @@ strip-bom@^4.0.0: resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== -strip-dirs@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/strip-dirs/-/strip-dirs-2.1.0.tgz#4987736264fc344cf20f6c34aca9d13d1d4ed6c5" - integrity sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g== - dependencies: - is-natural-number "^4.0.1" - strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" @@ -27211,13 +26794,6 @@ strip-json-comments@~1.0.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-1.0.4.tgz#1e15fbcac97d3ee99bf2d73b4c656b082bbafb91" integrity sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E= -strip-outer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-outer/-/strip-outer-1.0.0.tgz#aac0ba60d2e90c5d4f275fd8869fd9a2d310ffb8" - integrity sha1-qsC6YNLpDF1PJ1/Yhp/ZotMQ/7g= - dependencies: - escape-string-regexp "^1.0.2" - strong-log-transformer@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/strong-log-transformer/-/strong-log-transformer-2.1.0.tgz#0f5ed78d325e0421ac6f90f7f10e691d6ae3ae10" @@ -27304,11 +26880,6 @@ sudo-block@^1.1.0: is-docker "^1.0.0" is-root "^1.0.0" -suffix@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/suffix/-/suffix-0.1.0.tgz#3e46966de56af17600385e58db8ec659dd797907" - integrity sha1-PkaWbeVq8XYAOF5Y247GWd15eQc= - superagent@3.8.2: version "3.8.2" resolved "https://registry.yarnpkg.com/superagent/-/superagent-3.8.2.tgz#e4a11b9d047f7d3efeb3bbe536d9ec0021d16403" @@ -27639,7 +27210,7 @@ tar-fs@^1.16.3: pump "^1.0.0" tar-stream "^1.1.2" -tar-stream@^1.1.2, tar-stream@^1.5.2: +tar-stream@^1.1.2: version "1.5.5" resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.5.5.tgz#5cad84779f45c83b1f2508d96b09d88c7218af55" integrity sha512-mQdgLPc/Vjfr3VWqWbfxW8yQNiJCbAZ+Gf6GDu1Cy0bdb33ofyiNGBtAY96jHFhDuivCwgW1H9DgTON+INiXgg== @@ -27922,13 +27493,6 @@ thunky@^1.0.2: resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.0.2.tgz#a862e018e3fb1ea2ec3fce5d55605cf57f247371" integrity sha1-qGLgGOP7HqLsP85dVWBc9X8kc3E= -tildify@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/tildify/-/tildify-1.2.0.tgz#dcec03f55dca9b7aa3e5b04f21817eb56e63588a" - integrity sha1-3OwD9V3Km3qj5bBPIYF+tW5jWIo= - dependencies: - os-homedir "^1.0.0" - time-stamp@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" @@ -28299,13 +27863,6 @@ trim-newlines@^3.0.0: resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.0.tgz#79726304a6a898aa8373427298d54c2ee8b1cb30" integrity sha512-C4+gOpvmxaSMKuEf9Qc134F1ZuOHVXKRbtEflf4NTtuuJDEIJ9p5PXsalL8SkeRw+qit1Mo+yuvMPAKwWg/1hA== -trim-repeated@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/trim-repeated/-/trim-repeated-1.0.0.tgz#e3646a2ea4e891312bf7eace6cfb05380bc01c21" - integrity sha1-42RqLqTokTEr9+rObPsFOAvAHCE= - dependencies: - escape-string-regexp "^1.0.2" - trim-right@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" @@ -28598,7 +28155,7 @@ typings-tester@^0.3.2: dependencies: commander "^2.12.2" -ua-parser-js@^0.7.18, ua-parser-js@^0.7.9: +ua-parser-js@^0.7.18: version "0.7.21" resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.21.tgz#853cf9ce93f642f67174273cc34565ae6f308777" integrity sha512-+O8/qh/Qj8CgC6eYBVBykMrNtp5Gebn4dlGD/kKXVkJNDwyrAwSIqwz8CDf+tsAIWVycKcku6gIXJ0qwx/ZXaQ== @@ -28648,14 +28205,6 @@ uid-safe@2.1.5: dependencies: random-bytes "~1.0.0" -unbzip2-stream@^1.0.9: - version "1.2.5" - resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.2.5.tgz#73a033a567bbbde59654b193c44d48a7e4f43c47" - integrity sha512-izD3jxT8xkzwtXRUZjtmRwKnZoeECrfZ8ra/ketwOcusbZEp4mjULMnJOCfTDZBgGQAAY1AJ/IgxcwkavcX9Og== - dependencies: - buffer "^3.0.1" - through "^2.3.6" - unc-path-regex@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa" @@ -29003,21 +28552,6 @@ update-notifier@^0.5.0: semver-diff "^2.0.0" string-length "^1.0.0" -update-notifier@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.3.0.tgz#4e8827a6bb915140ab093559d7014e3ebb837451" - integrity sha1-TognpruRUUCrCTVZ1wFOPruDdFE= - dependencies: - boxen "^1.2.1" - chalk "^2.0.1" - configstore "^3.0.0" - import-lazy "^2.1.0" - is-installed-globally "^0.1.0" - is-npm "^1.0.0" - latest-version "^3.0.0" - semver-diff "^2.0.0" - xdg-basedir "^3.0.0" - update-notifier@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.5.0.tgz#d0744593e13f161e406acb1d9408b72cad08aff6" @@ -29949,13 +29483,6 @@ walker@^1.0.7, walker@~1.0.5: dependencies: makeerror "1.0.x" -ware@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/ware/-/ware-1.3.0.tgz#d1b14f39d2e2cb4ab8c4098f756fe4b164e473d4" - integrity sha1-0bFPOdLiy0q4xAmPdW/ksWTkc9Q= - dependencies: - wrap-fn "^0.1.0" - warning@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/warning/-/warning-3.0.0.tgz#32e5377cb572de4ab04753bdf8821c01ed605b7c" @@ -30485,13 +30012,6 @@ wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-fn@^0.1.0: - version "0.1.5" - resolved "https://registry.yarnpkg.com/wrap-fn/-/wrap-fn-0.1.5.tgz#f21b6e41016ff4a7e31720dbc63a09016bdf9845" - integrity sha1-8htuQQFv9KfjFyDbxjoJAWvfmEU= - dependencies: - co "3.1.0" - wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" @@ -30974,15 +30494,6 @@ yargs@~3.10.0: decamelize "^1.0.0" window-size "0.1.0" -yarn-install@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/yarn-install/-/yarn-install-0.5.1.tgz#f3c55e8646b6ac8da360b2f8e31afe5c4a067340" - integrity sha512-v0E5rDOoRRGyrbwxIOqPfX/x5kiV4ba7bvzT0wVfOhyZZr7PKP57F3h1hLHa66jYpU7zd4GLTVvjVL/Y1aE/gg== - dependencies: - cac "^3.0.3" - chalk "^1.1.3" - cross-spawn "^4.0.2" - yauzl@2.10.0, yauzl@^2.10.0: version "2.10.0" resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" @@ -30991,14 +30502,6 @@ yauzl@2.10.0, yauzl@^2.10.0: buffer-crc32 "~0.2.3" fd-slicer "~1.1.0" -yauzl@^2.4.2: - version "2.9.1" - resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.9.1.tgz#a81981ea70a57946133883f029c5821a89359a7f" - integrity sha1-qBmB6nCleUYTOIPwKcWCGok1mn8= - dependencies: - buffer-crc32 "~0.2.3" - fd-slicer "~1.0.1" - yazl@^2.5.1: version "2.5.1" resolved "https://registry.yarnpkg.com/yazl/-/yazl-2.5.1.tgz#a3d65d3dd659a5b0937850e8609f22fffa2b5c35" From ec44ee0dc9f5c24bef7c7676466ff3ee5fae56b1 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Fri, 21 Aug 2020 10:33:07 +0300 Subject: [PATCH 12/45] [TSVB] Disable enableHistogramMode prop when user selects non-stacked bar (#74930) * Remove enableHistogramMode prop from TSVB as it causes bugs with non-stacked bars * Disable enableHistogramMode property to false only when thr user selects the nobn-stacked option * small change to be more human readbale Co-authored-by: Elastic Machine --- .../application/components/lib/charts.js | 22 ------------------- .../components/vis_types/timeseries/vis.js | 3 --- .../visualizations/views/timeseries/index.js | 7 +++--- 3 files changed, 3 insertions(+), 29 deletions(-) delete mode 100644 src/plugins/vis_type_timeseries/public/application/components/lib/charts.js diff --git a/src/plugins/vis_type_timeseries/public/application/components/lib/charts.js b/src/plugins/vis_type_timeseries/public/application/components/lib/charts.js deleted file mode 100644 index 2495026304be8..0000000000000 --- a/src/plugins/vis_type_timeseries/public/application/components/lib/charts.js +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { uniq, map, size, flow } from 'lodash'; - -export const areFieldsDifferent = (name) => (series) => flow(uniq, size)(map(series, name)) > 1; diff --git a/src/plugins/vis_type_timeseries/public/application/components/vis_types/timeseries/vis.js b/src/plugins/vis_type_timeseries/public/application/components/vis_types/timeseries/vis.js index 612a7a48bade1..c14148d4a020f 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/vis_types/timeseries/vis.js +++ b/src/plugins/vis_type_timeseries/public/application/components/vis_types/timeseries/vis.js @@ -31,7 +31,6 @@ import { MarkdownSimple } from '../../../../../../../plugins/kibana_react/public import { replaceVars } from '../../lib/replace_vars'; import { getAxisLabelString } from '../../lib/get_axis_label_string'; import { getInterval } from '../../lib/get_interval'; -import { areFieldsDifferent } from '../../lib/charts'; import { createXaxisFormatter } from '../../lib/create_xaxis_formatter'; import { STACKED_OPTIONS } from '../../../visualizations/constants'; import { getCoreStart } from '../../../../services'; @@ -164,7 +163,6 @@ export class TimeseriesVisualization extends Component { const mainAxisGroupId = yAxisIdGenerator('main_group'); const seriesModel = model.series.filter((s) => !s.hidden).map((s) => cloneDeep(s)); - const enableHistogramMode = areFieldsDifferent('chart_type')(seriesModel); const firstSeries = seriesModel.find((s) => s.formatter && !s.separate_axis); const mainAxisScaleType = TimeseriesVisualization.getAxisScaleType(model); @@ -243,7 +241,6 @@ export class TimeseriesVisualization extends Component { series={series} yAxis={yAxis} onBrush={onBrush} - enableHistogramMode={enableHistogramMode} backgroundColor={model.background_color} showGrid={Boolean(model.show_grid)} legend={Boolean(model.show_legend)} diff --git a/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/index.js b/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/index.js index 64ac5cc5f871f..6b5d84dc56981 100644 --- a/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/index.js +++ b/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/index.js @@ -67,7 +67,6 @@ export const TimeSeries = ({ onBrush, xAxisFormatter, annotations, - enableHistogramMode, }) => { const chartRef = useRef(); const updateCursor = (_, cursor) => { @@ -181,6 +180,7 @@ export const TimeSeries = ({ ) => { const stackAccessors = getStackAccessors(stack); const isPercentage = stack === STACKED_OPTIONS.PERCENT; + const isStacked = stack !== STACKED_OPTIONS.NONE; const key = `${id}-${label}`; // Only use color mapping if there is no color from the server const finalColor = color ?? colors.mappedColors.mapping[label]; @@ -201,7 +201,7 @@ export const TimeSeries = ({ xScaleType={xScaleType} yScaleType={yScaleType} timeZone={timeZone} - enableHistogramMode={enableHistogramMode} + enableHistogramMode={isStacked} useDefaultGroupDomain={useDefaultGroupDomain} sortIndex={sortIndex} y1AccessorFormat={y1AccessorFormat} @@ -227,7 +227,7 @@ export const TimeSeries = ({ xScaleType={xScaleType} yScaleType={yScaleType} timeZone={timeZone} - enableHistogramMode={enableHistogramMode} + enableHistogramMode={isStacked} useDefaultGroupDomain={useDefaultGroupDomain} sortIndex={sortIndex} y1AccessorFormat={y1AccessorFormat} @@ -283,5 +283,4 @@ TimeSeries.propTypes = { onBrush: PropTypes.func, xAxisFormatter: PropTypes.func, annotations: PropTypes.array, - enableHistogramMode: PropTypes.bool.isRequired, }; From 659890cc91072b5c1477580355cdd39c1526a0ab Mon Sep 17 00:00:00 2001 From: Pete Harverson Date: Fri, 21 Aug 2020 09:25:17 +0100 Subject: [PATCH 13/45] [ML] Transforms: Unset doc title when app unmounts (#75539) Co-authored-by: Elastic Machine --- .../transform/public/app/mount_management_section.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/transform/public/app/mount_management_section.ts b/x-pack/plugins/transform/public/app/mount_management_section.ts index 454738f7a313a..0392ecbafa832 100644 --- a/x-pack/plugins/transform/public/app/mount_management_section.ts +++ b/x-pack/plugins/transform/public/app/mount_management_section.ts @@ -49,5 +49,10 @@ export async function mountManagementSection( history, }; - return renderApp(element, appDependencies); + const unmountAppCallback = renderApp(element, appDependencies); + + return () => { + docTitle.reset(); + unmountAppCallback(); + }; } From 3ddc2acd66208599c260397ed34ee12b6f1b67fa Mon Sep 17 00:00:00 2001 From: Peter Pisljar Date: Fri, 21 Aug 2020 11:16:52 +0200 Subject: [PATCH 14/45] adding markdown vis renderer (#75532) --- src/plugins/vis_type_markdown/kibana.json | 2 +- .../__snapshots__/markdown_fn.test.ts.snap | 2 +- .../public/__snapshots__/to_ast.test.ts.snap | 67 +++++++++++++++++ .../vis_type_markdown/public/markdown_fn.ts | 8 +- .../public/markdown_renderer.tsx | 57 ++++++++++++++ .../vis_type_markdown/public/markdown_vis.ts | 4 +- .../public/markdown_vis_controller.test.tsx | 74 ++++++++++++------- .../public/markdown_vis_controller.tsx | 11 ++- .../vis_type_markdown/public/plugin.ts | 6 +- .../vis_type_markdown/public/to_ast.test.ts | 54 ++++++++++++++ .../vis_type_markdown/public/to_ast.ts | 39 ++++++++++ .../__snapshots__/build_pipeline.test.ts.snap | 4 - .../public/legacy/build_pipeline.test.ts | 17 ----- .../public/legacy/build_pipeline.ts | 11 --- 14 files changed, 288 insertions(+), 68 deletions(-) create mode 100644 src/plugins/vis_type_markdown/public/__snapshots__/to_ast.test.ts.snap create mode 100644 src/plugins/vis_type_markdown/public/markdown_renderer.tsx create mode 100644 src/plugins/vis_type_markdown/public/to_ast.test.ts create mode 100644 src/plugins/vis_type_markdown/public/to_ast.ts diff --git a/src/plugins/vis_type_markdown/kibana.json b/src/plugins/vis_type_markdown/kibana.json index 9241f5eeee837..4196bd7e85707 100644 --- a/src/plugins/vis_type_markdown/kibana.json +++ b/src/plugins/vis_type_markdown/kibana.json @@ -4,5 +4,5 @@ "ui": true, "server": true, "requiredPlugins": ["expressions", "visualizations"], - "requiredBundles": ["kibanaUtils", "kibanaReact", "data", "charts"] + "requiredBundles": ["kibanaUtils", "kibanaReact", "data", "charts", "visualizations", "expressions"] } diff --git a/src/plugins/vis_type_markdown/public/__snapshots__/markdown_fn.test.ts.snap b/src/plugins/vis_type_markdown/public/__snapshots__/markdown_fn.test.ts.snap index 5a107bdfed9e5..473e2cba742b7 100644 --- a/src/plugins/vis_type_markdown/public/__snapshots__/markdown_fn.test.ts.snap +++ b/src/plugins/vis_type_markdown/public/__snapshots__/markdown_fn.test.ts.snap @@ -2,7 +2,7 @@ exports[`interpreter/functions#markdown returns an object with the correct structure 1`] = ` Object { - "as": "visualization", + "as": "markdown_vis", "type": "render", "value": Object { "visConfig": Object { diff --git a/src/plugins/vis_type_markdown/public/__snapshots__/to_ast.test.ts.snap b/src/plugins/vis_type_markdown/public/__snapshots__/to_ast.test.ts.snap new file mode 100644 index 0000000000000..2b8ff47be3f23 --- /dev/null +++ b/src/plugins/vis_type_markdown/public/__snapshots__/to_ast.test.ts.snap @@ -0,0 +1,67 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`markdown vis toExpressionAst function with params 1`] = ` +Object { + "chain": Array [ + Object { + "arguments": Object { + "font": Array [ + Object { + "chain": Array [ + Object { + "arguments": Object { + "size": Array [ + 15, + ], + }, + "function": "font", + "type": "function", + }, + ], + "type": "expression", + }, + ], + "markdown": Array [ + "### my markdown", + ], + "openLinksInNewTab": Array [ + true, + ], + }, + "function": "markdownVis", + "type": "function", + }, + ], + "type": "expression", +} +`; + +exports[`markdown vis toExpressionAst function without params 1`] = ` +Object { + "chain": Array [ + Object { + "arguments": Object { + "font": Array [ + Object { + "chain": Array [ + Object { + "arguments": Object { + "size": Array [ + "undefined", + ], + }, + "function": "font", + "type": "function", + }, + ], + "type": "expression", + }, + ], + }, + "function": "markdownVis", + "type": "function", + }, + ], + "type": "expression", +} +`; diff --git a/src/plugins/vis_type_markdown/public/markdown_fn.ts b/src/plugins/vis_type_markdown/public/markdown_fn.ts index 9f0809109e465..4b3c9989431f9 100644 --- a/src/plugins/vis_type_markdown/public/markdown_fn.ts +++ b/src/plugins/vis_type_markdown/public/markdown_fn.ts @@ -26,12 +26,14 @@ interface RenderValue { visConfig: MarkdownVisParams; } -export const createMarkdownVisFn = (): ExpressionFunctionDefinition< +export type MarkdownVisExpressionFunctionDefinition = ExpressionFunctionDefinition< 'markdownVis', unknown, Arguments, Render -> => ({ +>; + +export const createMarkdownVisFn = (): MarkdownVisExpressionFunctionDefinition => ({ name: 'markdownVis', type: 'render', inputTypes: [], @@ -65,7 +67,7 @@ export const createMarkdownVisFn = (): ExpressionFunctionDefinition< fn(input, args) { return { type: 'render', - as: 'visualization', + as: 'markdown_vis', value: { visType: 'markdown', visConfig: { diff --git a/src/plugins/vis_type_markdown/public/markdown_renderer.tsx b/src/plugins/vis_type_markdown/public/markdown_renderer.tsx new file mode 100644 index 0000000000000..5950a762635b2 --- /dev/null +++ b/src/plugins/vis_type_markdown/public/markdown_renderer.tsx @@ -0,0 +1,57 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React from 'react'; +import { render, unmountComponentAtNode } from 'react-dom'; +import { VisualizationContainer } from '../../visualizations/public'; +import { ExpressionRenderDefinition } from '../../expressions/common/expression_renderers'; +import { MarkdownVisWrapper } from './markdown_vis_controller'; +import { StartServicesGetter } from '../../kibana_utils/public'; + +export const getMarkdownRenderer = (start: StartServicesGetter) => { + const markdownVisRenderer: () => ExpressionRenderDefinition = () => ({ + name: 'markdown_vis', + displayName: 'markdown visualization', + reuseDomNode: true, + render: async (domNode: HTMLElement, config: any, handlers: any) => { + const { visConfig } = config; + + const I18nContext = await start().core.i18n.Context; + + handlers.onDestroy(() => { + unmountComponentAtNode(domNode); + }); + + render( + + + + + , + domNode + ); + }, + }); + + return markdownVisRenderer; +}; diff --git a/src/plugins/vis_type_markdown/public/markdown_vis.ts b/src/plugins/vis_type_markdown/public/markdown_vis.ts index 089e00bb44937..27ac038aee6ff 100644 --- a/src/plugins/vis_type_markdown/public/markdown_vis.ts +++ b/src/plugins/vis_type_markdown/public/markdown_vis.ts @@ -19,10 +19,10 @@ import { i18n } from '@kbn/i18n'; -import { MarkdownVisWrapper } from './markdown_vis_controller'; import { MarkdownOptions } from './markdown_options'; import { SettingsOptions } from './settings_options_lazy'; import { DefaultEditorSize } from '../../vis_default_editor/public'; +import { toExpressionAst } from './to_ast'; export const markdownVisDefinition = { name: 'markdown', @@ -32,8 +32,8 @@ export const markdownVisDefinition = { description: i18n.translate('visTypeMarkdown.markdownDescription', { defaultMessage: 'Create a document using markdown syntax', }), + toExpressionAst, visConfig: { - component: MarkdownVisWrapper, defaults: { fontSize: 12, openLinksInNewTab: false, diff --git a/src/plugins/vis_type_markdown/public/markdown_vis_controller.test.tsx b/src/plugins/vis_type_markdown/public/markdown_vis_controller.test.tsx index 103879cb6e6df..ff0cc89a5d9c9 100644 --- a/src/plugins/vis_type_markdown/public/markdown_vis_controller.test.tsx +++ b/src/plugins/vis_type_markdown/public/markdown_vis_controller.test.tsx @@ -25,13 +25,15 @@ describe('markdown vis controller', () => { it('should set html from markdown params', () => { const vis = { params: { + openLinksInNewTab: false, + fontSize: 16, markdown: 'This is a test of the [markdown](http://daringfireball.net/projects/markdown) vis.', }, }; const wrapper = render( - + ); expect(wrapper.find('a').text()).toBe('markdown'); }); @@ -39,12 +41,14 @@ describe('markdown vis controller', () => { it('should not render the html', () => { const vis = { params: { + openLinksInNewTab: false, + fontSize: 16, markdown: 'Testing html', }, }; const wrapper = render( - + ); expect(wrapper.text()).toBe('Testing html\n'); }); @@ -52,12 +56,14 @@ describe('markdown vis controller', () => { it('should update the HTML when render again with changed params', () => { const vis = { params: { + openLinksInNewTab: false, + fontSize: 16, markdown: 'Initial', }, }; const wrapper = mount( - + ); expect(wrapper.text().trim()).toBe('Initial'); vis.params.markdown = 'Updated'; @@ -66,52 +72,68 @@ describe('markdown vis controller', () => { }); describe('renderComplete', () => { + const vis = { + params: { + openLinksInNewTab: false, + fontSize: 16, + markdown: 'test', + }, + }; + + const renderComplete = jest.fn(); + + beforeEach(() => { + renderComplete.mockClear(); + }); + it('should be called on initial rendering', () => { - const vis = { - params: { - markdown: 'test', - }, - }; - const renderComplete = jest.fn(); mount( - + ); expect(renderComplete.mock.calls.length).toBe(1); }); it('should be called on successive render when params change', () => { - const vis = { - params: { - markdown: 'test', - }, - }; - const renderComplete = jest.fn(); mount( - + ); expect(renderComplete.mock.calls.length).toBe(1); renderComplete.mockClear(); vis.params.markdown = 'changed'; mount( - + ); expect(renderComplete.mock.calls.length).toBe(1); }); it('should be called on successive render even without data change', () => { - const vis = { - params: { - markdown: 'test', - }, - }; - const renderComplete = jest.fn(); mount( - + ); expect(renderComplete.mock.calls.length).toBe(1); renderComplete.mockClear(); mount( - + ); expect(renderComplete.mock.calls.length).toBe(1); }); diff --git a/src/plugins/vis_type_markdown/public/markdown_vis_controller.tsx b/src/plugins/vis_type_markdown/public/markdown_vis_controller.tsx index 4e77bb196b713..e1155ca42df72 100644 --- a/src/plugins/vis_type_markdown/public/markdown_vis_controller.tsx +++ b/src/plugins/vis_type_markdown/public/markdown_vis_controller.tsx @@ -22,7 +22,7 @@ import { Markdown } from '../../kibana_react/public'; import { MarkdownVisParams } from './types'; interface MarkdownVisComponentProps extends MarkdownVisParams { - renderComplete: () => {}; + renderComplete: () => void; } /** @@ -80,7 +80,14 @@ class MarkdownVisComponent extends React.Component { * The way React works, this wrapper nearly brings no overhead, but allows us * to use proper lifecycle methods in the actual component. */ -export function MarkdownVisWrapper(props: any) { + +export interface MarkdownVisWrapperProps { + visParams: MarkdownVisParams; + fireEvent: (event: any) => void; + renderComplete: () => void; +} + +export function MarkdownVisWrapper(props: MarkdownVisWrapperProps) { return ( { } public setup(core: CoreSetup, { expressions, visualizations }: MarkdownPluginSetupDependencies) { - visualizations.createReactVisualization(markdownVisDefinition); + const start = createStartServicesGetter(core.getStartServices); + visualizations.createBaseVisualization(markdownVisDefinition); + expressions.registerRenderer(getMarkdownRenderer(start)); expressions.registerFunction(createMarkdownVisFn); } diff --git a/src/plugins/vis_type_markdown/public/to_ast.test.ts b/src/plugins/vis_type_markdown/public/to_ast.test.ts new file mode 100644 index 0000000000000..1ad1fa0ee2517 --- /dev/null +++ b/src/plugins/vis_type_markdown/public/to_ast.test.ts @@ -0,0 +1,54 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { toExpressionAst } from './to_ast'; +import { Vis } from '../../visualizations/public'; + +describe('markdown vis toExpressionAst function', () => { + let vis: Vis; + + beforeEach(() => { + vis = { + isHierarchical: () => false, + type: {}, + params: { + percentageMode: false, + }, + data: { + indexPattern: { id: '123' } as any, + aggs: { + getResponseAggs: () => [], + aggs: [], + } as any, + }, + } as any; + }); + + it('without params', () => { + vis.params = {}; + const actual = toExpressionAst(vis); + expect(actual).toMatchSnapshot(); + }); + + it('with params', () => { + vis.params = { markdown: '### my markdown', fontSize: 15, openLinksInNewTab: true }; + const actual = toExpressionAst(vis); + expect(actual).toMatchSnapshot(); + }); +}); diff --git a/src/plugins/vis_type_markdown/public/to_ast.ts b/src/plugins/vis_type_markdown/public/to_ast.ts new file mode 100644 index 0000000000000..9b481218b42ea --- /dev/null +++ b/src/plugins/vis_type_markdown/public/to_ast.ts @@ -0,0 +1,39 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { Vis } from '../../visualizations/public'; +import { buildExpression, buildExpressionFunction } from '../../expressions/public'; +import { MarkdownVisExpressionFunctionDefinition } from './markdown_fn'; + +export const toExpressionAst = (vis: Vis) => { + const { markdown, fontSize, openLinksInNewTab } = vis.params; + + const markdownVis = buildExpressionFunction( + 'markdownVis', + { + markdown, + font: buildExpression(`font size=${fontSize}`), + openLinksInNewTab, + } + ); + + const ast = buildExpression([markdownVis]); + + return ast.toAst(); +}; diff --git a/src/plugins/visualizations/public/legacy/__snapshots__/build_pipeline.test.ts.snap b/src/plugins/visualizations/public/legacy/__snapshots__/build_pipeline.test.ts.snap index df29c078d23e4..fae777b98ef63 100644 --- a/src/plugins/visualizations/public/legacy/__snapshots__/build_pipeline.test.ts.snap +++ b/src/plugins/visualizations/public/legacy/__snapshots__/build_pipeline.test.ts.snap @@ -4,8 +4,6 @@ exports[`visualize loader pipeline helpers: build pipeline buildPipeline calls t exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles input_control_vis function 1`] = `"input_control_vis visConfig='{\\"some\\":\\"nested\\",\\"data\\":{\\"here\\":true}}' "`; -exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles markdown function 1`] = `"markdownvis '## hello _markdown_' font={font size=12} openLinksInNewTab=true "`; - exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles metrics/tsvb function 1`] = `"tsvb params='{\\"foo\\":\\"bar\\"}' uiState='{}' "`; exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles pie function 1`] = `"kibana_pie visConfig='{\\"dimensions\\":{\\"metric\\":{\\"accessor\\":0,\\"label\\":\\"\\",\\"format\\":{},\\"params\\":{},\\"aggType\\":\\"\\"},\\"buckets\\":[1,2]}}' "`; @@ -34,6 +32,4 @@ exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunct exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles timelion function 1`] = `"timelion_vis expression='foo' interval='bar' "`; -exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles undefined markdown function 1`] = `"markdownvis '' font={font size=12} openLinksInNewTab=true "`; - exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles vega function 1`] = `"vega spec='this is a test' "`; diff --git a/src/plugins/visualizations/public/legacy/build_pipeline.test.ts b/src/plugins/visualizations/public/legacy/build_pipeline.test.ts index 50fa5ac64e2a1..2d92b386253b0 100644 --- a/src/plugins/visualizations/public/legacy/build_pipeline.test.ts +++ b/src/plugins/visualizations/public/legacy/build_pipeline.test.ts @@ -123,23 +123,6 @@ describe('visualize loader pipeline helpers: build pipeline', () => { expect(actual).toMatchSnapshot(); }); - it('handles markdown function', () => { - const params = { - markdown: '## hello _markdown_', - fontSize: 12, - openLinksInNewTab: true, - foo: 'bar', - }; - const actual = buildPipelineVisFunction.markdown(params, schemasDef, uiState); - expect(actual).toMatchSnapshot(); - }); - - it('handles undefined markdown function', () => { - const params = { fontSize: 12, openLinksInNewTab: true, foo: 'bar' }; - const actual = buildPipelineVisFunction.markdown(params, schemasDef, uiState); - expect(actual).toMatchSnapshot(); - }); - describe('handles table function', () => { it('without splits or buckets', () => { const params = { foo: 'bar' }; diff --git a/src/plugins/visualizations/public/legacy/build_pipeline.ts b/src/plugins/visualizations/public/legacy/build_pipeline.ts index ebd240c79287a..438a6d2337724 100644 --- a/src/plugins/visualizations/public/legacy/build_pipeline.ts +++ b/src/plugins/visualizations/public/legacy/build_pipeline.ts @@ -269,17 +269,6 @@ export const buildPipelineVisFunction: BuildPipelineVisFunction = { const interval = prepareString('interval', params.interval); return `timelion_vis ${expression}${interval}`; }, - markdown: (params) => { - const { markdown, fontSize, openLinksInNewTab } = params; - let escapedMarkdown = ''; - if (typeof markdown === 'string' || markdown instanceof String) { - escapedMarkdown = escapeString(markdown.toString()); - } - let expr = `markdownvis '${escapedMarkdown}' `; - expr += prepareValue('font', `{font size=${fontSize}}`, true); - expr += prepareValue('openLinksInNewTab', openLinksInNewTab); - return expr; - }, table: (params, schemas) => { const visConfig = { ...params, From 74ab9897b57daf746c0a41e739485032ddf6a15f Mon Sep 17 00:00:00 2001 From: Vadim Dalecky Date: Fri, 21 Aug 2020 11:28:37 +0200 Subject: [PATCH 15/45] Embeddable input (#73033) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: 💡 move timeRange, filters and query to base embeddabl * refactor: 💡 use new base embeddable input in explore data * feat: 🎸 import types as types --- .../public/lib/embeddables/i_embeddable.ts | 16 ++++++++++++++++ .../public/embeddable/visualize_embeddable.ts | 3 --- .../explore_data/abstract_explore_data_action.ts | 1 + .../explore_data/explore_data_chart_action.ts | 9 +++------ .../explore_data_context_menu_action.ts | 7 +++---- 5 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/plugins/embeddable/public/lib/embeddables/i_embeddable.ts b/src/plugins/embeddable/public/lib/embeddables/i_embeddable.ts index 7628b1d41b452..9c4a1b5602c49 100644 --- a/src/plugins/embeddable/public/lib/embeddables/i_embeddable.ts +++ b/src/plugins/embeddable/public/lib/embeddables/i_embeddable.ts @@ -22,6 +22,7 @@ import { Adapters } from '../types'; import { IContainer } from '../containers/i_container'; import { ViewMode } from '../types'; import { TriggerContextMapping } from '../../../../ui_actions/public'; +import type { TimeRange, Query, Filter } from '../../../../data/common'; export interface EmbeddableError { name: string; @@ -55,6 +56,21 @@ export interface EmbeddableInput { */ disableTriggers?: boolean; + /** + * Time range of the chart. + */ + timeRange?: TimeRange; + + /** + * Visualization query string used to narrow down results. + */ + query?: Query; + + /** + * Visualization filters used to narrow down results. + */ + filters?: Filter[]; + [key: string]: unknown; } diff --git a/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts b/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts index a434bf9756b64..4efdfd2911cbc 100644 --- a/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts +++ b/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts @@ -60,9 +60,6 @@ export interface VisualizeEmbeddableConfiguration { } export interface VisualizeInput extends EmbeddableInput { - timeRange?: TimeRange; - query?: Query; - filters?: Filter[]; vis?: { colors?: { [key: string]: string }; }; diff --git a/x-pack/plugins/discover_enhanced/public/actions/explore_data/abstract_explore_data_action.ts b/x-pack/plugins/discover_enhanced/public/actions/explore_data/abstract_explore_data_action.ts index 4ddcb3386f314..36a844752a1c3 100644 --- a/x-pack/plugins/discover_enhanced/public/actions/explore_data/abstract_explore_data_action.ts +++ b/x-pack/plugins/discover_enhanced/public/actions/explore_data/abstract_explore_data_action.ts @@ -59,6 +59,7 @@ export abstract class AbstractExploreDataAction Date: Fri, 21 Aug 2020 11:33:42 +0200 Subject: [PATCH 16/45] [Lens] Use index pattern service instead saved object client (#74654) --- .../datapanel.test.tsx | 45 +- .../indexpattern_datasource/datapanel.tsx | 5 +- .../bucket_nesting_editor.test.tsx | 16 + .../dimension_panel/bucket_nesting_editor.tsx | 8 +- .../dimension_panel/dimension_panel.test.tsx | 35 +- .../dimension_panel/field_select.tsx | 6 +- .../dimension_panel/popover_editor.tsx | 1 + .../indexpattern_datasource/document_field.ts | 6 +- .../field_item.test.tsx | 15 + .../indexpattern_datasource/field_item.tsx | 6 +- .../indexpattern.test.ts | 9 + .../indexpattern_datasource/indexpattern.tsx | 7 +- .../indexpattern_suggestions.test.tsx | 41 +- .../indexpattern_suggestions.ts | 16 +- .../layerpanel.test.tsx | 11 + .../indexpattern_datasource/loader.test.ts | 554 +++++++++--------- .../public/indexpattern_datasource/loader.ts | 153 +++-- .../public/indexpattern_datasource/mocks.ts | 20 + .../operations/definitions/cardinality.tsx | 4 +- .../operations/definitions/count.tsx | 2 +- .../definitions/date_histogram.test.tsx | 7 + .../operations/definitions/date_histogram.tsx | 4 +- .../operations/definitions/metrics.tsx | 4 +- .../operations/definitions/terms.test.tsx | 8 + .../operations/definitions/terms.tsx | 4 +- .../operations/operations.test.ts | 10 + .../state_helpers.test.ts | 5 + .../public/indexpattern_datasource/types.ts | 1 + 28 files changed, 586 insertions(+), 417 deletions(-) diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.test.tsx index 4a79f30a17a05..8291b673cd17a 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.test.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.test.tsx @@ -87,36 +87,42 @@ const initialState: IndexPatternPrivateState = { fields: [ { name: 'timestamp', + displayName: 'timestampLabel', type: 'date', aggregatable: true, searchable: true, }, { name: 'bytes', + displayName: 'bytes', type: 'number', aggregatable: true, searchable: true, }, { name: 'memory', + displayName: 'amemory', type: 'number', aggregatable: true, searchable: true, }, { name: 'unsupported', + displayName: 'unsupported', type: 'geo', aggregatable: true, searchable: true, }, { name: 'source', + displayName: 'source', type: 'string', aggregatable: true, searchable: true, }, { name: 'client', + displayName: 'client', type: 'ip', aggregatable: true, searchable: true, @@ -131,6 +137,7 @@ const initialState: IndexPatternPrivateState = { fields: [ { name: 'timestamp', + displayName: 'timestampLabel', type: 'date', aggregatable: true, searchable: true, @@ -145,6 +152,7 @@ const initialState: IndexPatternPrivateState = { }, { name: 'bytes', + displayName: 'bytes', type: 'number', aggregatable: true, searchable: true, @@ -166,6 +174,7 @@ const initialState: IndexPatternPrivateState = { }, { name: 'source', + displayName: 'source', type: 'string', aggregatable: true, searchable: true, @@ -185,18 +194,21 @@ const initialState: IndexPatternPrivateState = { fields: [ { name: 'timestamp', + displayName: 'timestampLabel', type: 'date', aggregatable: true, searchable: true, }, { name: 'bytes', + displayName: 'bytes', type: 'number', aggregatable: true, searchable: true, }, { name: 'source', + displayName: 'source', type: 'string', aggregatable: true, searchable: true, @@ -581,18 +593,19 @@ describe('IndexPattern Data Panel', () => { .find('[data-test-subj="lnsIndexPatternAvailableFields"]') .find(FieldItem) .map((fieldItem) => fieldItem.prop('field').name) - ).toEqual(['bytes', 'memory']); + ).toEqual(['memory', 'bytes']); wrapper .find('[data-test-subj="lnsIndexPatternEmptyFields"]') .find('button') .first() .simulate('click'); + const emptyAccordion = wrapper.find('[data-test-subj="lnsIndexPatternEmptyFields"]'); expect( - wrapper - .find('[data-test-subj="lnsIndexPatternEmptyFields"]') - .find(FieldItem) - .map((fieldItem) => fieldItem.prop('field').name) + emptyAccordion.find(FieldItem).map((fieldItem) => fieldItem.prop('field').name) ).toEqual(['client', 'source', 'timestamp']); + expect( + emptyAccordion.find(FieldItem).map((fieldItem) => fieldItem.prop('field').displayName) + ).toEqual(['client', 'source', 'timestampLabel']); }); it('should display NoFieldsCallout when all fields are empty', async () => { @@ -615,8 +628,8 @@ describe('IndexPattern Data Panel', () => { wrapper .find('[data-test-subj="lnsIndexPatternEmptyFields"]') .find(FieldItem) - .map((fieldItem) => fieldItem.prop('field').name) - ).toEqual(['bytes', 'client', 'memory', 'source', 'timestamp']); + .map((fieldItem) => fieldItem.prop('field').displayName) + ).toEqual(['amemory', 'bytes', 'client', 'source', 'timestampLabel']); }); it('should display spinner for available fields accordion if existing fields are not loaded yet', async () => { @@ -656,10 +669,9 @@ describe('IndexPattern Data Panel', () => { wrapper.find('[data-test-subj="typeFilter-number"]').first().simulate('click'); - expect(wrapper.find(FieldItem).map((fieldItem) => fieldItem.prop('field').name)).toEqual([ - 'bytes', - 'memory', - ]); + expect( + wrapper.find(FieldItem).map((fieldItem) => fieldItem.prop('field').displayName) + ).toEqual(['amemory', 'bytes']); }); it('should display no fields in groups when filtered by type Record', () => { @@ -686,14 +698,9 @@ describe('IndexPattern Data Panel', () => { .find('button') .first() .simulate('click'); - expect(wrapper.find(FieldItem).map((fieldItem) => fieldItem.prop('field').name)).toEqual([ - 'Records', - 'bytes', - 'memory', - 'client', - 'source', - 'timestamp', - ]); + expect( + wrapper.find(FieldItem).map((fieldItem) => fieldItem.prop('field').displayName) + ).toEqual(['Records', 'amemory', 'bytes', 'client', 'source', 'timestampLabel']); }); it('should filter down by type and by name', () => { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.tsx index bdcce52314634..0777b9b9d8e57 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.tsx @@ -59,7 +59,7 @@ const FixedEuiContextMenuPanel = (EuiContextMenuPanel as unknown) as React.Funct >; function sortFields(fieldA: IndexPatternField, fieldB: IndexPatternField) { - return fieldA.name.localeCompare(fieldB.name, undefined, { sensitivity: 'base' }); + return fieldA.displayName.localeCompare(fieldB.displayName, undefined, { sensitivity: 'base' }); } const supportedFieldTypes = new Set(['string', 'number', 'boolean', 'date', 'ip', 'document']); @@ -323,7 +323,8 @@ export const InnerIndexPatternDataPanel = function InnerIndexPatternDataPanel({ fieldGroup.filter((field) => { if ( localState.nameFilter.length && - !field.name.toLowerCase().includes(localState.nameFilter.toLowerCase()) + !field.name.toLowerCase().includes(localState.nameFilter.toLowerCase()) && + !field.displayName.toLowerCase().includes(localState.nameFilter.toLowerCase()) ) { return false; } diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/bucket_nesting_editor.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/bucket_nesting_editor.test.tsx index c6dbb6f617acf..3d6c9f6047c81 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/bucket_nesting_editor.test.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/bucket_nesting_editor.test.tsx @@ -8,6 +8,13 @@ import { mount } from 'enzyme'; import React from 'react'; import { BucketNestingEditor } from './bucket_nesting_editor'; import { IndexPatternColumn } from '../indexpattern'; +import { IndexPatternField } from '../types'; + +const fieldMap = { + a: { displayName: 'a' } as IndexPatternField, + b: { displayName: 'b' } as IndexPatternField, + c: { displayName: 'c' } as IndexPatternField, +}; describe('BucketNestingEditor', () => { function mockCol(col: Partial = {}): IndexPatternColumn { @@ -32,6 +39,7 @@ describe('BucketNestingEditor', () => { it('should display the top level grouping when at the root', () => { const component = mount( { const component = mount( { const component = mount( { const component = mount( { const component = mount( { const component = mount( { const component = mount( { const component = mount( { const setColumns = jest.fn(); const component = mount( void; + fieldMap: Record; }) { const column = layer.columns[columnId]; const columns = Object.entries(layer.columns); @@ -37,14 +39,14 @@ export function BucketNestingEditor({ .map(([value, c]) => ({ value, text: c.label, - fieldName: hasField(c) ? c.sourceField : '', + fieldName: hasField(c) ? fieldMap[c.sourceField].displayName : '', })); if (!column || !column.isBucketed || !aggColumns.length) { return null; } - const fieldName = hasField(column) ? column.sourceField : ''; + const fieldName = hasField(column) ? fieldMap[column.sourceField].displayName : ''; const prevColumn = layer.columnOrder[layer.columnOrder.indexOf(columnId) - 1]; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_panel.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_panel.test.tsx index 1f48f95ee45e0..bca179b437521 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_panel.test.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_panel.test.tsx @@ -45,6 +45,7 @@ const expectedIndexPatterns = { fields: [ { name: 'timestamp', + displayName: 'timestampLabel', type: 'date', aggregatable: true, searchable: true, @@ -52,6 +53,7 @@ const expectedIndexPatterns = { }, { name: 'bytes', + displayName: 'bytes', type: 'number', aggregatable: true, searchable: true, @@ -59,6 +61,7 @@ const expectedIndexPatterns = { }, { name: 'memory', + displayName: 'memory', type: 'number', aggregatable: true, searchable: true, @@ -66,6 +69,7 @@ const expectedIndexPatterns = { }, { name: 'source', + displayName: 'source', type: 'string', aggregatable: true, searchable: true, @@ -210,9 +214,8 @@ describe('IndexPatternDimensionEditorPanel', () => { expect(options).toHaveLength(2); expect(options![0].label).toEqual('Records'); - expect(options![1].options!.map(({ label }) => label)).toEqual([ - 'timestamp', + 'timestampLabel', 'bytes', 'memory', 'source', @@ -239,7 +242,7 @@ describe('IndexPatternDimensionEditorPanel', () => { .filter('[data-test-subj="indexPattern-dimension-field"]') .prop('options'); - expect(options![1].options!.map(({ label }) => label)).toEqual(['timestamp', 'source']); + expect(options![1].options!.map(({ label }) => label)).toEqual(['timestampLabel', 'source']); }); it('should indicate fields which are incompatible for the operation of the current column', () => { @@ -277,7 +280,7 @@ describe('IndexPatternDimensionEditorPanel', () => { expect(options![0]['data-test-subj']).toEqual('lns-fieldOptionIncompatible-Records'); expect( - options![1].options!.filter(({ label }) => label === 'timestamp')[0]['data-test-subj'] + options![1].options!.filter(({ label }) => label === 'timestampLabel')[0]['data-test-subj'] ).toContain('Incompatible'); expect( options![1].options!.filter(({ label }) => label === 'memory')[0]['data-test-subj'] @@ -651,7 +654,9 @@ describe('IndexPatternDimensionEditorPanel', () => { expect(options![0]['data-test-subj']).toContain('Incompatible'); expect( - options![1].options!.filter(({ label }) => label === 'timestamp')[0]['data-test-subj'] + options![1].options!.filter(({ label }) => label === 'timestampLabel')[0][ + 'data-test-subj' + ] ).toContain('Incompatible'); expect( options![1].options!.filter(({ label }) => label === 'source')[0]['data-test-subj'] @@ -769,7 +774,9 @@ describe('IndexPatternDimensionEditorPanel', () => { expect(options![0]['data-test-subj']).toContain('Incompatible'); expect( - options![1].options!.filter(({ label }) => label === 'timestamp')[0]['data-test-subj'] + options![1].options!.filter(({ label }) => label === 'timestampLabel')[0][ + 'data-test-subj' + ] ).toContain('Incompatible'); expect( options![1].options!.filter(({ label }) => label === 'source')[0]['data-test-subj'] @@ -923,7 +930,7 @@ describe('IndexPatternDimensionEditorPanel', () => { expect(options![0]['data-test-subj']).toContain('Incompatible'); expect( - options![1].options!.filter(({ label }) => label === 'timestamp')[0]['data-test-subj'] + options![1].options!.filter(({ label }) => label === 'timestampLabel')[0]['data-test-subj'] ).toContain('Incompatible'); expect( options![1].options!.filter(({ label }) => label === 'bytes')[0]['data-test-subj'] @@ -1095,12 +1102,12 @@ describe('IndexPatternDimensionEditorPanel', () => { columnOrder: ['col1'], columns: { col1: { - label: 'Average of bar', + label: 'Average of memory', dataType: 'number', isBucketed: false, // Private operationType: 'avg', - sourceField: 'bar', + sourceField: 'memory', }, }, }, @@ -1145,12 +1152,12 @@ describe('IndexPatternDimensionEditorPanel', () => { columnOrder: ['col1'], columns: { col1: { - label: 'Average of bar', + label: 'Average of memory', dataType: 'number', isBucketed: false, // Private operationType: 'avg', - sourceField: 'bar', + sourceField: 'memory', params: { format: { id: 'bytes', params: { decimals: 0 } }, }, @@ -1195,12 +1202,12 @@ describe('IndexPatternDimensionEditorPanel', () => { columnOrder: ['col1'], columns: { col1: { - label: 'Average of bar', + label: 'Average of memory', dataType: 'number', isBucketed: false, // Private operationType: 'avg', - sourceField: 'bar', + sourceField: 'memory', params: { format: { id: 'bytes', params: { decimals: 2 } }, }, @@ -1253,12 +1260,14 @@ describe('IndexPatternDimensionEditorPanel', () => { { aggregatable: true, name: 'bar', + displayName: 'bar', searchable: true, type: 'number', }, { aggregatable: true, name: 'mystring', + displayName: 'mystring', searchable: true, type: 'string', }, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/field_select.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/field_select.tsx index 4c85a55ad6011..b2a59788b50f9 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/field_select.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/field_select.tsx @@ -74,7 +74,7 @@ export function FieldSelect({ function fieldNamesToOptions(items: string[]) { return items .map((field) => ({ - label: field, + label: fieldMap[field].displayName, value: { type: 'field', field, @@ -105,7 +105,7 @@ export function FieldSelect({ // eslint-disable-next-line @typescript-eslint/naming-convention 'lnFieldSelect__option--nonExistant': !exists, }), - 'data-test-subj': `lns-fieldOption${compatible ? '' : 'Incompatible'}-${label}`, + 'data-test-subj': `lns-fieldOption${compatible ? '' : 'Incompatible'}-${value.field}`, })); } @@ -161,7 +161,7 @@ export function FieldSelect({ ? selectedColumnSourceField ? [ { - label: selectedColumnSourceField, + label: fieldMap[selectedColumnSourceField].displayName, value: { type: 'field', field: selectedColumnSourceField }, }, ] diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/popover_editor.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/popover_editor.tsx index a5108b30cea1d..038b51b922286 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/popover_editor.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/popover_editor.tsx @@ -378,6 +378,7 @@ export function PopoverEditor(props: PopoverEditorProps) { {!hideGrouping && ( { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/document_field.ts b/x-pack/plugins/lens/public/indexpattern_datasource/document_field.ts index e0a7f27835e42..b0c5540a6b94f 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/document_field.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/document_field.ts @@ -5,12 +5,16 @@ */ import { i18n } from '@kbn/i18n'; +import { IndexPatternField } from './types'; /** * This is a special-case field which allows us to perform * document-level operations such as count. */ -export const documentField = { +export const documentField: IndexPatternField = { + displayName: i18n.translate('xpack.lens.indexPattern.records', { + defaultMessage: 'Records', + }), name: i18n.translate('xpack.lens.indexPattern.records', { defaultMessage: 'Records', }), diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/field_item.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/field_item.test.tsx index 08a2f85ec7053..781222888b6dc 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/field_item.test.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/field_item.test.tsx @@ -36,30 +36,35 @@ describe('IndexPattern Field Item', () => { fields: [ { name: 'timestamp', + displayName: 'timestampLabel', type: 'date', aggregatable: true, searchable: true, }, { name: 'bytes', + displayName: 'bytesLabel', type: 'number', aggregatable: true, searchable: true, }, { name: 'memory', + displayName: 'memory', type: 'number', aggregatable: true, searchable: true, }, { name: 'unsupported', + displayName: 'unsupported', type: 'geo', aggregatable: true, searchable: true, }, { name: 'source', + displayName: 'source', type: 'string', aggregatable: true, searchable: true, @@ -83,6 +88,7 @@ describe('IndexPattern Field Item', () => { filters: [], field: { name: 'bytes', + displayName: 'bytesLabel', type: 'number', aggregatable: true, searchable: true, @@ -98,6 +104,13 @@ describe('IndexPattern Field Item', () => { } as unknown) as DataPublicPluginStart['fieldFormats']; }); + it('should display displayName of a field', () => { + const wrapper = mountWithIntl(); + expect(wrapper.find('[data-test-subj="lnsFieldListPanelField"]').first().text()).toEqual( + 'bytesLabel' + ); + }); + it('should request field stats without a time field, if the index pattern has none', async () => { indexPattern.timeFieldName = undefined; core.http.post.mockImplementationOnce(() => { @@ -149,6 +162,7 @@ describe('IndexPattern Field Item', () => { timeFieldName: 'timestamp', field: { name: 'bytes', + displayName: 'bytesLabel', type: 'number', aggregatable: true, searchable: true, @@ -235,6 +249,7 @@ describe('IndexPattern Field Item', () => { timeFieldName: 'timestamp', field: { name: 'bytes', + displayName: 'bytesLabel', type: 'number', aggregatable: true, searchable: true, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx index 5dc6673bc29ec..5bcfbc64ec706 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx @@ -100,7 +100,7 @@ export const InnerFieldItem = function InnerFieldItem(props: FieldItemProps) { isLoading: false, }); - const wrappableName = wrapOnDot(field.name)!; + const wrappableName = wrapOnDot(field.displayName)!; const wrappableHighlight = wrapOnDot(highlight); const highlightIndex = wrappableHighlight ? wrappableName.toLowerCase().indexOf(wrappableHighlight.toLowerCase()) @@ -204,7 +204,7 @@ export const InnerFieldItem = function InnerFieldItem(props: FieldItemProps) { container={document.querySelector('.application') || undefined} button={ = { id: 'indexpattern', @@ -129,6 +131,7 @@ export function getIndexPatternDatasource({ savedObjectsClient: await savedObjectsClient, defaultIndexPatternId: core.uiSettings.get('defaultIndex'), storage, + indexPatternsService, }); }, @@ -209,9 +212,9 @@ export function getIndexPatternDatasource({ id, state, setState, - savedObjectsClient, onError: onIndexPatternLoadError, storage, + indexPatternsService, }); }} data={data} @@ -289,7 +292,6 @@ export function getIndexPatternDatasource({ { changeLayerIndexPattern({ - savedObjectsClient, indexPatternId, setState: props.setState, state: props.state, @@ -297,6 +299,7 @@ export function getIndexPatternDatasource({ onError: onIndexPatternLoadError, replaceIfPossible: true, storage, + indexPatternsService, }); }} {...props} diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.test.tsx index b6246c6e91e7e..5489dcffc52c4 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.test.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.test.tsx @@ -23,36 +23,42 @@ const expectedIndexPatterns = { fields: [ { name: 'timestamp', + displayName: 'timestampLabel', type: 'date', aggregatable: true, searchable: true, }, { name: 'start_date', + displayName: 'start_date', type: 'date', aggregatable: true, searchable: true, }, { name: 'bytes', + displayName: 'bytes', type: 'number', aggregatable: true, searchable: true, }, { name: 'memory', + displayName: 'memory', type: 'number', aggregatable: true, searchable: true, }, { name: 'source', + displayName: 'source', type: 'string', aggregatable: true, searchable: true, }, { name: 'dest', + displayName: 'dest', type: 'string', aggregatable: true, searchable: true, @@ -66,6 +72,7 @@ const expectedIndexPatterns = { fields: [ { name: 'timestamp', + displayName: 'timestampLabel', type: 'date', aggregatable: true, searchable: true, @@ -80,6 +87,7 @@ const expectedIndexPatterns = { }, { name: 'bytes', + displayName: 'bytes', type: 'number', aggregatable: true, searchable: true, @@ -105,6 +113,7 @@ const expectedIndexPatterns = { }, { name: 'source', + displayName: 'source', type: 'string', aggregatable: true, searchable: true, @@ -169,6 +178,7 @@ describe('IndexPattern Data Source suggestions', () => { it('should apply a bucketed aggregation for a string field', () => { const suggestions = getDatasourceSuggestionsForField(stateWithoutLayer(), '1', { name: 'source', + displayName: 'source', type: 'string', aggregatable: true, searchable: true, @@ -214,6 +224,7 @@ describe('IndexPattern Data Source suggestions', () => { it('should apply a bucketed aggregation for a date field', () => { const suggestions = getDatasourceSuggestionsForField(stateWithoutLayer(), '1', { name: 'timestamp', + displayName: 'timestampLabel', type: 'date', aggregatable: true, searchable: true, @@ -258,6 +269,7 @@ describe('IndexPattern Data Source suggestions', () => { it('should select a metric for a number field', () => { const suggestions = getDatasourceSuggestionsForField(stateWithoutLayer(), '1', { name: 'bytes', + displayName: 'bytes', type: 'number', aggregatable: true, searchable: true, @@ -313,6 +325,7 @@ describe('IndexPattern Data Source suggestions', () => { fields: [ { name: 'bytes', + displayName: 'bytes', type: 'number', aggregatable: true, searchable: true, @@ -331,6 +344,7 @@ describe('IndexPattern Data Source suggestions', () => { const suggestions = getDatasourceSuggestionsForField(state, '1', { name: 'bytes', + displayName: 'bytes', type: 'number', aggregatable: true, searchable: true, @@ -374,6 +388,7 @@ describe('IndexPattern Data Source suggestions', () => { it('should apply a bucketed aggregation for a string field', () => { const suggestions = getDatasourceSuggestionsForField(stateWithEmptyLayer(), '1', { name: 'source', + displayName: 'source', type: 'string', aggregatable: true, searchable: true, @@ -419,6 +434,7 @@ describe('IndexPattern Data Source suggestions', () => { it('should apply a bucketed aggregation for a date field', () => { const suggestions = getDatasourceSuggestionsForField(stateWithEmptyLayer(), '1', { name: 'timestamp', + displayName: 'timestampLabel', type: 'date', aggregatable: true, searchable: true, @@ -463,6 +479,7 @@ describe('IndexPattern Data Source suggestions', () => { it('should select a metric for a number field', () => { const suggestions = getDatasourceSuggestionsForField(stateWithEmptyLayer(), '1', { name: 'bytes', + displayName: 'bytes', type: 'number', aggregatable: true, searchable: true, @@ -518,6 +535,7 @@ describe('IndexPattern Data Source suggestions', () => { fields: [ { name: 'bytes', + displayName: 'bytes', type: 'number', aggregatable: true, searchable: true, @@ -536,6 +554,7 @@ describe('IndexPattern Data Source suggestions', () => { const suggestions = getDatasourceSuggestionsForField(state, '1', { name: 'bytes', + displayName: 'bytes', type: 'number', aggregatable: true, searchable: true, @@ -563,6 +582,7 @@ describe('IndexPattern Data Source suggestions', () => { it('creates a new layer and replaces layer if no match is found', () => { const suggestions = getDatasourceSuggestionsForField(stateWithEmptyLayer(), '2', { name: 'source', + displayName: 'source', type: 'string', aggregatable: true, searchable: true, @@ -693,6 +713,7 @@ describe('IndexPattern Data Source suggestions', () => { '1', { name: 'start_date', + displayName: 'start_date', type: 'date', aggregatable: true, searchable: true, @@ -724,6 +745,7 @@ describe('IndexPattern Data Source suggestions', () => { const initialState = stateWithNonEmptyTables(); const suggestions = getDatasourceSuggestionsForField(initialState, '1', { name: 'timestamp', + displayName: 'timestampLabel', type: 'date', aggregatable: true, searchable: true, @@ -770,6 +792,7 @@ describe('IndexPattern Data Source suggestions', () => { it('does not use the same field for bucketing multiple times', () => { const suggestions = getDatasourceSuggestionsForField(stateWithNonEmptyTables(), '1', { name: 'source', + displayName: 'source', type: 'string', aggregatable: true, searchable: true, @@ -785,6 +808,7 @@ describe('IndexPattern Data Source suggestions', () => { const initialState = stateWithNonEmptyTables(); const suggestions = getDatasourceSuggestionsForField(initialState, '1', { name: 'dest', + displayName: 'dest', type: 'string', aggregatable: true, searchable: true, @@ -816,6 +840,7 @@ describe('IndexPattern Data Source suggestions', () => { const initialState = stateWithNonEmptyTables(); const suggestions = getDatasourceSuggestionsForField(initialState, '1', { name: 'memory', + displayName: 'memory', type: 'number', aggregatable: true, searchable: true, @@ -858,6 +883,7 @@ describe('IndexPattern Data Source suggestions', () => { }; const suggestions = getDatasourceSuggestionsForField(modifiedState, '1', { name: 'memory', + displayName: 'memory', type: 'number', aggregatable: true, searchable: true, @@ -908,6 +934,7 @@ describe('IndexPattern Data Source suggestions', () => { }; const suggestions = getDatasourceSuggestionsForField(modifiedState, '1', { name: 'memory', + displayName: 'memory', type: 'number', aggregatable: true, searchable: true, @@ -961,6 +988,7 @@ describe('IndexPattern Data Source suggestions', () => { const initialState = stateWithCurrentIndexPattern(); const suggestions = getDatasourceSuggestionsForField(initialState, '2', { name: 'timestamp', + displayName: 'timestampLabel', type: 'date', aggregatable: true, searchable: true, @@ -1015,6 +1043,7 @@ describe('IndexPattern Data Source suggestions', () => { const initialState = stateWithCurrentIndexPattern(); const suggestions = getDatasourceSuggestionsForField(initialState, '1', { name: 'timestamp', + displayName: 'timestampLabel', type: 'date', aggregatable: true, searchable: true, @@ -1185,7 +1214,7 @@ describe('IndexPattern Data Source suggestions', () => { { columnId: 'id1', operation: { - label: 'timestamp', + label: 'timestampLabel', dataType: 'date', isBucketed: true, scale: 'interval', @@ -1261,7 +1290,7 @@ describe('IndexPattern Data Source suggestions', () => { { columnId: 'id1', operation: { - label: 'timestamp', + label: 'timestampLabel', dataType: 'date', isBucketed: true, scale: 'interval', @@ -1324,30 +1353,35 @@ describe('IndexPattern Data Source suggestions', () => { fields: [ { name: 'field1', + displayName: 'field1', type: 'string', aggregatable: true, searchable: true, }, { name: 'field2', + displayName: 'field2', type: 'string', aggregatable: true, searchable: true, }, { name: 'field3', + displayName: 'field3Label', type: 'string', aggregatable: true, searchable: true, }, { name: 'field4', + displayName: 'field4', type: 'number', aggregatable: true, searchable: true, }, { name: 'field5', + displayName: 'field5', type: 'number', aggregatable: true, searchable: true, @@ -1462,12 +1496,14 @@ describe('IndexPattern Data Source suggestions', () => { fields: [ { name: 'field1', + displayName: 'field1', type: 'number', aggregatable: true, searchable: true, }, { name: 'field2', + displayName: 'field2', type: 'date', aggregatable: true, searchable: true, @@ -1522,6 +1558,7 @@ describe('IndexPattern Data Source suggestions', () => { fields: [ { name: 'field1', + displayName: 'field1', type: 'number', aggregatable: true, searchable: true, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts index 111a113a16be7..f3aa9c4f51c82 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts @@ -481,11 +481,19 @@ function createChangedNestingSuggestion(state: IndexPatternPrivateState, layerId const layer = state.layers[layerId]; const [firstBucket, secondBucket, ...rest] = layer.columnOrder; const updatedLayer = { ...layer, columnOrder: [secondBucket, firstBucket, ...rest] }; + const currentFields = state.indexPatterns[state.currentIndexPatternId].fields; + const firstBucketLabel = + currentFields.find((field) => field.name === layer.columns[firstBucket].sourceField) + ?.displayName || ''; + const secondBucketLabel = + currentFields.find((field) => field.name === layer.columns[secondBucket].sourceField) + ?.displayName || ''; + return buildSuggestion({ state, layerId, updatedLayer, - label: getNestedTitle([layer.columns[secondBucket], layer.columns[firstBucket]]), + label: getNestedTitle([secondBucketLabel, firstBucketLabel]), changeType: 'reorder', }); } @@ -544,12 +552,12 @@ function createMetricSuggestion( }); } -function getNestedTitle([outerBucket, innerBucket]: IndexPatternColumn[]) { +function getNestedTitle([outerBucketLabel, innerBucketLabel]: string[]) { return i18n.translate('xpack.lens.indexpattern.suggestions.nestingChangeLabel', { defaultMessage: '{innerOperation} for each {outerOperation}', values: { - innerOperation: innerBucket.sourceField, - outerOperation: outerBucket.sourceField, + innerOperation: innerBucketLabel, + outerOperation: outerBucketLabel, }, }); } diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/layerpanel.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/layerpanel.test.tsx index 560c48b2155ee..738cdd611a7ba 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/layerpanel.test.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/layerpanel.test.tsx @@ -65,30 +65,35 @@ const initialState: IndexPatternPrivateState = { fields: [ { name: 'timestamp', + displayName: 'timestampLabel', type: 'date', aggregatable: true, searchable: true, }, { name: 'bytes', + displayName: 'bytes', type: 'number', aggregatable: true, searchable: true, }, { name: 'memory', + displayName: 'memory', type: 'number', aggregatable: true, searchable: true, }, { name: 'unsupported', + displayName: 'unsupported', type: 'geo', aggregatable: true, searchable: true, }, { name: 'source', + displayName: 'source', type: 'string', aggregatable: true, searchable: true, @@ -102,6 +107,7 @@ const initialState: IndexPatternPrivateState = { fields: [ { name: 'timestamp', + displayName: 'timestampLabel', type: 'date', aggregatable: true, searchable: true, @@ -116,6 +122,7 @@ const initialState: IndexPatternPrivateState = { }, { name: 'bytes', + displayName: 'bytes', type: 'number', aggregatable: true, searchable: true, @@ -137,6 +144,7 @@ const initialState: IndexPatternPrivateState = { }, { name: 'source', + displayName: 'source', type: 'string', aggregatable: true, searchable: true, @@ -155,18 +163,21 @@ const initialState: IndexPatternPrivateState = { fields: [ { name: 'timestamp', + displayName: 'timestampLabel', type: 'date', aggregatable: true, searchable: true, }, { name: 'memory', + displayName: 'memory', type: 'number', aggregatable: true, searchable: true, }, { name: 'source', + displayName: 'source', type: 'string', aggregatable: true, searchable: true, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/loader.test.ts b/x-pack/plugins/lens/public/indexpattern_datasource/loader.test.ts index 27904a0f23f16..cfabcb4edcef7 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/loader.test.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/loader.test.ts @@ -13,7 +13,14 @@ import { changeLayerIndexPattern, syncExistingFields, } from './loader'; -import { IndexPatternPersistedState, IndexPatternPrivateState, IndexPatternField } from './types'; +import { IndexPatternsContract } from '../../../../../src/plugins/data/public'; +import { + IndexPatternPersistedState, + IndexPatternPrivateState, + IndexPatternField, + IndexPattern, +} from './types'; +import { createMockedRestrictedIndexPattern, createMockedIndexPattern } from './mocks'; import { documentField } from './document_field'; jest.mock('./operations'); @@ -27,154 +34,157 @@ const createMockStorage = (lastData?: Record) => { }; }; -const sampleIndexPatterns = { - a: { - id: 'a', - title: 'my-fake-index-pattern', - timeFieldName: 'timestamp', - fields: [ - { - name: 'timestamp', - type: 'date', - aggregatable: true, - searchable: true, - }, - { - name: 'start_date', - type: 'date', - aggregatable: true, - searchable: true, - }, - { - name: 'bytes', - type: 'number', - aggregatable: true, - searchable: true, - }, - { - name: 'memory', - type: 'number', - aggregatable: true, - searchable: true, - }, - { - name: 'source', - type: 'string', - aggregatable: true, - searchable: true, - esTypes: ['keyword'], - }, - { - name: 'dest', - type: 'string', - aggregatable: true, - searchable: true, - esTypes: ['keyword'], - }, - documentField, - ], - }, - b: { - id: 'b', - title: 'my-fake-restricted-pattern', - timeFieldName: 'timestamp', - fields: [ - { - name: 'timestamp', - type: 'date', - aggregatable: true, - searchable: true, - aggregationRestrictions: { - date_histogram: { - agg: 'date_histogram', - fixed_interval: '1d', - delay: '7d', - time_zone: 'UTC', - }, +const indexPattern1 = ({ + id: '1', + title: 'my-fake-index-pattern', + timeFieldName: 'timestamp', + fields: [ + { + name: 'timestamp', + displayName: 'timestampLabel', + type: 'date', + aggregatable: true, + searchable: true, + }, + { + name: 'start_date', + displayName: 'start_date', + type: 'date', + aggregatable: true, + searchable: true, + }, + { + name: 'bytes', + displayName: 'bytes', + type: 'number', + aggregatable: true, + searchable: true, + }, + { + name: 'memory', + displayName: 'memory', + type: 'number', + aggregatable: true, + searchable: true, + }, + { + name: 'source', + displayName: 'source', + type: 'string', + aggregatable: true, + searchable: true, + esTypes: ['keyword'], + }, + { + name: 'unsupported', + displayName: 'unsupported', + type: 'geo', + aggregatable: true, + searchable: true, + }, + { + name: 'dest', + displayName: 'dest', + type: 'string', + aggregatable: true, + searchable: true, + esTypes: ['keyword'], + }, + documentField, + ], +} as unknown) as IndexPattern; + +const sampleIndexPatternsFromService = { + '1': createMockedIndexPattern(), + '2': createMockedRestrictedIndexPattern(), +}; + +const indexPattern2 = ({ + id: '2', + title: 'my-fake-restricted-pattern', + timeFieldName: 'timestamp', + fields: [ + { + name: 'timestamp', + displayName: 'timestampLabel', + type: 'date', + aggregatable: true, + searchable: true, + aggregationRestrictions: { + date_histogram: { + agg: 'date_histogram', + fixed_interval: '1d', + delay: '7d', + time_zone: 'UTC', }, }, - { - name: 'bytes', - type: 'number', - aggregatable: true, - searchable: true, - aggregationRestrictions: { - // Ignored in the UI - histogram: { - agg: 'histogram', - interval: 1000, - }, - avg: { - agg: 'avg', - }, - max: { - agg: 'max', - }, - min: { - agg: 'min', - }, - sum: { - agg: 'sum', - }, + }, + { + name: 'bytes', + displayName: 'bytes', + type: 'number', + aggregatable: true, + searchable: true, + aggregationRestrictions: { + // Ignored in the UI + histogram: { + agg: 'histogram', + interval: 1000, }, - }, - { - name: 'source', - type: 'string', - aggregatable: false, - searchable: false, - scripted: true, - aggregationRestrictions: { - terms: { - agg: 'terms', - }, + avg: { + agg: 'avg', + }, + max: { + agg: 'max', + }, + min: { + agg: 'min', + }, + sum: { + agg: 'sum', }, - esTypes: ['keyword'], }, - documentField, - ], - }, -}; - -function indexPatternSavedObject({ id }: { id: keyof typeof sampleIndexPatterns }) { - const pattern = { - ...sampleIndexPatterns[id], - fields: [ - ...sampleIndexPatterns[id].fields, - { - name: 'description', - type: 'string', - aggregatable: false, - searchable: true, - esTypes: ['text'], + }, + { + name: 'source', + displayName: 'source', + type: 'string', + aggregatable: true, + searchable: true, + scripted: true, + aggregationRestrictions: { + terms: { + agg: 'terms', + }, }, - ], - }; - return { - id, - type: 'index-pattern', - attributes: { - title: pattern.title, - timeFieldName: pattern.timeFieldName, - fields: JSON.stringify(pattern.fields.filter((f) => f.type !== 'document')), + esTypes: ['keyword'], }, - }; -} + documentField, + ], +} as unknown) as IndexPattern; + +const sampleIndexPatterns = { + '1': indexPattern1, + '2': indexPattern2, +}; function mockClient() { return ({ find: jest.fn(async () => ({ savedObjects: [ - { id: 'a', attributes: { title: sampleIndexPatterns.a.title } }, - { id: 'b', attributes: { title: sampleIndexPatterns.b.title } }, + { id: '1', attributes: { title: sampleIndexPatterns[1].title } }, + { id: '2', attributes: { title: sampleIndexPatterns[2].title } }, ], })), - async bulkGet(indexPatterns: Array<{ id: keyof typeof sampleIndexPatterns }>) { - return { - savedObjects: indexPatterns.map(({ id }) => indexPatternSavedObject({ id })), - }; - }, - } as unknown) as Pick; + } as unknown) as Pick; +} + +function mockIndexPatternsService() { + return ({ + get: jest.fn(async (id: '1' | '2') => { + return sampleIndexPatternsFromService[id]; + }), + } as unknown) as Pick; } describe('loader', () => { @@ -182,11 +192,12 @@ describe('loader', () => { it('should not load index patterns that are already loaded', async () => { const cache = await loadIndexPatterns({ cache: sampleIndexPatterns, - patterns: ['a', 'b'], - savedObjectsClient: { - bulkGet: jest.fn(() => Promise.reject('bulkGet should not have been called')), - find: jest.fn(() => Promise.reject('find should not have been called')), - }, + patterns: ['1', '2'], + indexPatternsService: ({ + get: jest.fn(() => + Promise.reject('mockIndexPatternService.get should not have been called') + ), + } as unknown) as Pick, }); expect(cache).toEqual(sampleIndexPatterns); @@ -195,10 +206,10 @@ describe('loader', () => { it('should load index patterns that are not loaded', async () => { const cache = await loadIndexPatterns({ cache: { - b: sampleIndexPatterns.b, + '2': sampleIndexPatterns['2'], }, - patterns: ['a', 'b'], - savedObjectsClient: mockClient(), + patterns: ['1', '2'], + indexPatternsService: mockIndexPatternsService(), }); expect(cache).toMatchObject(sampleIndexPatterns); @@ -207,8 +218,8 @@ describe('loader', () => { it('should allow scripted, but not full text fields', async () => { const cache = await loadIndexPatterns({ cache: {}, - patterns: ['a', 'b'], - savedObjectsClient: mockClient(), + patterns: ['1', '2'], + indexPatternsService: mockIndexPatternsService(), }); expect(cache).toMatchObject(sampleIndexPatterns); @@ -218,61 +229,56 @@ describe('loader', () => { const cache = await loadIndexPatterns({ cache: {}, patterns: ['foo'], - savedObjectsClient: ({ - ...mockClient(), - async bulkGet() { - return { - savedObjects: [ - { - id: 'foo', - type: 'index-pattern', - attributes: { - title: 'Foo index', - typeMeta: JSON.stringify({ - aggs: { - date_histogram: { - timestamp: { - agg: 'date_histogram', - fixed_interval: 'm', - }, - }, - sum: { - bytes: { - agg: 'sum', - }, - }, - }, - }), - fields: JSON.stringify([ - { - name: 'timestamp', - type: 'date', - aggregatable: true, - searchable: true, - }, - { - name: 'bytes', - type: 'number', - aggregatable: true, - searchable: true, - }, - ]), + indexPatternsService: ({ + get: jest.fn(async () => ({ + id: 'foo', + title: 'Foo index', + typeMeta: { + aggs: { + date_histogram: { + timestamp: { + agg: 'date_histogram', + fixed_interval: 'm', }, }, - ], - }; - }, - } as unknown) as Pick, + sum: { + bytes: { + agg: 'sum', + }, + }, + }, + }, + fields: [ + { + name: 'timestamp', + displayName: 'timestampLabel', + type: 'date', + aggregatable: true, + searchable: true, + }, + { + name: 'bytes', + displayName: 'bytes', + type: 'number', + aggregatable: true, + searchable: true, + }, + ], + })), + } as unknown) as Pick, }); - expect(cache.foo.fields.find((f) => f.name === 'bytes')!.aggregationRestrictions).toEqual({ + expect( + cache.foo.fields.find((f: IndexPatternField) => f.name === 'bytes')!.aggregationRestrictions + ).toEqual({ sum: { agg: 'sum' }, }); - expect(cache.foo.fields.find((f) => f.name === 'timestamp')!.aggregationRestrictions).toEqual( - { - date_histogram: { agg: 'date_histogram', fixed_interval: 'm' }, - } - ); + expect( + cache.foo.fields.find((f: IndexPatternField) => f.name === 'timestamp')! + .aggregationRestrictions + ).toEqual({ + date_histogram: { agg: 'date_histogram', fixed_interval: 'm' }, + }); }); }); @@ -281,22 +287,23 @@ describe('loader', () => { const storage = createMockStorage(); const state = await loadInitialState({ savedObjectsClient: mockClient(), + indexPatternsService: mockIndexPatternsService(), storage, }); expect(state).toMatchObject({ - currentIndexPatternId: 'a', + currentIndexPatternId: '1', indexPatternRefs: [ - { id: 'a', title: sampleIndexPatterns.a.title }, - { id: 'b', title: sampleIndexPatterns.b.title }, + { id: '1', title: sampleIndexPatterns['1'].title }, + { id: '2', title: sampleIndexPatterns['2'].title }, ], indexPatterns: { - a: sampleIndexPatterns.a, + '1': sampleIndexPatterns['1'], }, layers: {}, }); expect(storage.set).toHaveBeenCalledWith('lens-settings', { - indexPatternId: 'a', + indexPatternId: '1', }); }); @@ -304,39 +311,41 @@ describe('loader', () => { const storage = createMockStorage({ indexPatternId: 'c' }); const state = await loadInitialState({ savedObjectsClient: mockClient(), + indexPatternsService: mockIndexPatternsService(), storage, }); expect(state).toMatchObject({ - currentIndexPatternId: 'a', + currentIndexPatternId: '1', indexPatternRefs: [ - { id: 'a', title: sampleIndexPatterns.a.title }, - { id: 'b', title: sampleIndexPatterns.b.title }, + { id: '1', title: sampleIndexPatterns['1'].title }, + { id: '2', title: sampleIndexPatterns['2'].title }, ], indexPatterns: { - a: sampleIndexPatterns.a, + '1': sampleIndexPatterns['1'], }, layers: {}, }); expect(storage.set).toHaveBeenCalledWith('lens-settings', { - indexPatternId: 'a', + indexPatternId: '1', }); }); it('should load lastUsedIndexPatternId if in localStorage', async () => { const state = await loadInitialState({ savedObjectsClient: mockClient(), - storage: createMockStorage({ indexPatternId: 'b' }), + indexPatternsService: mockIndexPatternsService(), + storage: createMockStorage({ indexPatternId: '2' }), }); expect(state).toMatchObject({ - currentIndexPatternId: 'b', + currentIndexPatternId: '2', indexPatternRefs: [ - { id: 'a', title: sampleIndexPatterns.a.title }, - { id: 'b', title: sampleIndexPatterns.b.title }, + { id: '1', title: sampleIndexPatterns['1'].title }, + { id: '2', title: sampleIndexPatterns['2'].title }, ], indexPatterns: { - b: sampleIndexPatterns.b, + '2': sampleIndexPatterns['2'], }, layers: {}, }); @@ -345,33 +354,34 @@ describe('loader', () => { it('should use the default index pattern id, if provided', async () => { const storage = createMockStorage(); const state = await loadInitialState({ - defaultIndexPatternId: 'b', + defaultIndexPatternId: '2', savedObjectsClient: mockClient(), + indexPatternsService: mockIndexPatternsService(), storage, }); expect(state).toMatchObject({ - currentIndexPatternId: 'b', + currentIndexPatternId: '2', indexPatternRefs: [ - { id: 'a', title: sampleIndexPatterns.a.title }, - { id: 'b', title: sampleIndexPatterns.b.title }, + { id: '1', title: sampleIndexPatterns['1'].title }, + { id: '2', title: sampleIndexPatterns['2'].title }, ], indexPatterns: { - b: sampleIndexPatterns.b, + '2': sampleIndexPatterns['2'], }, layers: {}, }); expect(storage.set).toHaveBeenCalledWith('lens-settings', { - indexPatternId: 'b', + indexPatternId: '2', }); }); it('should initialize from saved state', async () => { const savedState: IndexPatternPersistedState = { - currentIndexPatternId: 'b', + currentIndexPatternId: '2', layers: { layerb: { - indexPatternId: 'b', + indexPatternId: '2', columnOrder: ['col1', 'col2'], columns: { col1: { @@ -395,27 +405,28 @@ describe('loader', () => { }, }, }; - const storage = createMockStorage({ indexPatternId: 'a' }); + const storage = createMockStorage({ indexPatternId: '1' }); const state = await loadInitialState({ state: savedState, savedObjectsClient: mockClient(), + indexPatternsService: mockIndexPatternsService(), storage, }); expect(state).toMatchObject({ - currentIndexPatternId: 'b', + currentIndexPatternId: '2', indexPatternRefs: [ - { id: 'a', title: sampleIndexPatterns.a.title }, - { id: 'b', title: sampleIndexPatterns.b.title }, + { id: '1', title: sampleIndexPatterns['1'].title }, + { id: '2', title: sampleIndexPatterns['2'].title }, ], indexPatterns: { - b: sampleIndexPatterns.b, + '2': sampleIndexPatterns['2'], }, layers: savedState.layers, }); expect(storage.set).toHaveBeenCalledWith('lens-settings', { - indexPatternId: 'b', + indexPatternId: '2', }); }); }); @@ -424,33 +435,36 @@ describe('loader', () => { it('loads the index pattern and then sets it as current', async () => { const setState = jest.fn(); const state: IndexPatternPrivateState = { - currentIndexPatternId: 'b', + currentIndexPatternId: '2', indexPatternRefs: [], indexPatterns: {}, existingFields: {}, layers: {}, isFirstExistenceFetch: false, }; - const storage = createMockStorage({ indexPatternId: 'b' }); + const storage = createMockStorage({ indexPatternId: '2' }); await changeIndexPattern({ state, setState, - id: 'a', - savedObjectsClient: mockClient(), + id: '1', + indexPatternsService: mockIndexPatternsService(), onError: jest.fn(), storage, }); expect(setState).toHaveBeenCalledTimes(1); expect(setState.mock.calls[0][0](state)).toMatchObject({ - currentIndexPatternId: 'a', + currentIndexPatternId: '1', indexPatterns: { - a: sampleIndexPatterns.a, + '1': { + ...sampleIndexPatterns['1'], + fields: [...sampleIndexPatterns['1'].fields], + }, }, }); expect(storage.set).toHaveBeenCalledWith('lens-settings', { - indexPatternId: 'a', + indexPatternId: '1', }); }); @@ -459,7 +473,7 @@ describe('loader', () => { const onError = jest.fn(); const err = new Error('NOPE!'); const state: IndexPatternPrivateState = { - currentIndexPatternId: 'b', + currentIndexPatternId: '2', indexPatternRefs: [], existingFields: {}, indexPatterns: {}, @@ -467,15 +481,14 @@ describe('loader', () => { isFirstExistenceFetch: false, }; - const storage = createMockStorage({ indexPatternId: 'b' }); + const storage = createMockStorage({ indexPatternId: '2' }); await changeIndexPattern({ state, setState, - id: 'a', - savedObjectsClient: { - ...mockClient(), - bulkGet: jest.fn(async () => { + id: '1', + indexPatternsService: { + get: jest.fn(async () => { throw err; }), }, @@ -493,17 +506,17 @@ describe('loader', () => { it('loads the index pattern and then changes the specified layer', async () => { const setState = jest.fn(); const state: IndexPatternPrivateState = { - currentIndexPatternId: 'b', + currentIndexPatternId: '2', indexPatternRefs: [], existingFields: {}, indexPatterns: { - a: sampleIndexPatterns.a, + '1': sampleIndexPatterns['1'], }, layers: { l0: { columnOrder: ['col1'], columns: {}, - indexPatternId: 'a', + indexPatternId: '1', }, l1: { columnOrder: ['col2'], @@ -519,36 +532,36 @@ describe('loader', () => { sourceField: 'timestamp', }, }, - indexPatternId: 'a', + indexPatternId: '1', }, }, isFirstExistenceFetch: false, }; - const storage = createMockStorage({ indexPatternId: 'a' }); + const storage = createMockStorage({ indexPatternId: '1' }); await changeLayerIndexPattern({ state, setState, - indexPatternId: 'b', + indexPatternId: '2', layerId: 'l1', - savedObjectsClient: mockClient(), + indexPatternsService: mockIndexPatternsService(), onError: jest.fn(), storage, }); expect(setState).toHaveBeenCalledTimes(1); expect(setState.mock.calls[0][0](state)).toMatchObject({ - currentIndexPatternId: 'b', + currentIndexPatternId: '2', indexPatterns: { - a: sampleIndexPatterns.a, - b: sampleIndexPatterns.b, + 1: sampleIndexPatterns['1'], + 2: sampleIndexPatterns['2'], }, layers: { l0: { columnOrder: ['col1'], columns: {}, - indexPatternId: 'a', + indexPatternId: '1', }, l1: { columnOrder: ['col2'], @@ -564,12 +577,12 @@ describe('loader', () => { sourceField: 'timestamp', }, }, - indexPatternId: 'b', + indexPatternId: '2', }, }, }); expect(storage.set).toHaveBeenCalledWith('lens-settings', { - indexPatternId: 'b', + indexPatternId: '2', }); }); @@ -578,32 +591,31 @@ describe('loader', () => { const onError = jest.fn(); const err = new Error('NOPE!'); const state: IndexPatternPrivateState = { - currentIndexPatternId: 'b', + currentIndexPatternId: '2', indexPatternRefs: [], existingFields: {}, indexPatterns: { - a: sampleIndexPatterns.a, + '1': sampleIndexPatterns['1'], }, layers: { l0: { columnOrder: ['col1'], columns: {}, - indexPatternId: 'a', + indexPatternId: '1', }, }, isFirstExistenceFetch: false, }; - const storage = createMockStorage({ indexPatternId: 'b' }); + const storage = createMockStorage({ indexPatternId: '2' }); await changeLayerIndexPattern({ state, setState, - indexPatternId: 'b', + indexPatternId: '2', layerId: 'l0', - savedObjectsClient: { - ...mockClient(), - bulkGet: jest.fn(async () => { + indexPatternsService: { + get: jest.fn(async () => { throw err; }), }, @@ -634,7 +646,7 @@ describe('loader', () => { return { indexPatternTitle, existingFieldNames: ['field_1', 'field_2'].map( - (fieldName) => `${indexPatternTitle}_${fieldName}` + (fieldName) => `ip${indexPatternTitle}_${fieldName}` ), }; }) as unknown) as HttpHandler; @@ -643,9 +655,9 @@ describe('loader', () => { dateRange: { fromDate: '1900-01-01', toDate: '2000-01-01' }, fetchJson, indexPatterns: [ - { id: 'a', title: 'a', fields: [] }, - { id: 'b', title: 'a', fields: [] }, - { id: 'c', title: 'a', fields: [] }, + { id: '1', title: '1', fields: [] }, + { id: '2', title: '1', fields: [] }, + { id: '3', title: '1', fields: [] }, ], setState, dslQuery, @@ -668,9 +680,9 @@ describe('loader', () => { isFirstExistenceFetch: false, existenceFetchFailed: false, existingFields: { - a: { a_field_1: true, a_field_2: true }, - b: { b_field_1: true, b_field_2: true }, - c: { c_field_1: true, c_field_2: true }, + '1': { ip1_field_1: true, ip1_field_2: true }, + '2': { ip2_field_1: true, ip2_field_2: true }, + '3': { ip3_field_1: true, ip3_field_2: true }, }, }); }); @@ -683,7 +695,7 @@ describe('loader', () => { return { indexPatternTitle, existingFieldNames: - indexPatternTitle === 'a' + indexPatternTitle === '1' ? ['field_1', 'field_2'].map((fieldName) => `${indexPatternTitle}_${fieldName}`) : [], }; @@ -693,9 +705,9 @@ describe('loader', () => { dateRange: { fromDate: '1900-01-01', toDate: '2000-01-01' }, fetchJson, indexPatterns: [ - { id: 'a', title: 'a', fields: [] }, - { id: 'b', title: 'a', fields: [] }, - { id: 'c', title: 'a', fields: [] }, + { id: '1', title: '1', fields: [] }, + { id: '2', title: '1', fields: [] }, + { id: 'c', title: '1', fields: [] }, ], setState, dslQuery, @@ -725,8 +737,8 @@ describe('loader', () => { fetchJson, indexPatterns: [ { - id: 'a', - title: 'a', + id: '1', + title: '1', fields: [{ name: 'field1' }, { name: 'field2' }] as IndexPatternField[], }, ], @@ -746,7 +758,7 @@ describe('loader', () => { }) as IndexPatternPrivateState; expect(newState.existenceFetchFailed).toEqual(true); - expect(newState.existingFields.a).toEqual({ + expect(newState.existingFields['1']).toEqual({ field1: true, field2: true, }); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/loader.ts b/x-pack/plugins/lens/public/indexpattern_datasource/loader.ts index 20e7bec6db131..9c4a19e58a052 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/loader.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/loader.ts @@ -6,8 +6,7 @@ import _ from 'lodash'; import { IStorageWrapper } from 'src/plugins/kibana_utils/public'; -import { SavedObjectsClientContract, SavedObjectAttributes, HttpSetup } from 'kibana/public'; -import { SimpleSavedObject } from 'kibana/public'; +import { SavedObjectsClientContract, HttpSetup } from 'kibana/public'; import { StateSetter } from '../types'; import { IndexPattern, @@ -19,33 +18,25 @@ import { import { updateLayerIndexPattern } from './state_helpers'; import { DateRange, ExistingFields } from '../../common/types'; import { BASE_API_URL } from '../../common'; -import { documentField } from './document_field'; import { + IndexPatternsContract, indexPatterns as indexPatternsUtils, - IFieldType, - IndexPatternTypeMeta, } from '../../../../../src/plugins/data/public'; +import { documentField } from './document_field'; import { readFromStorage, writeToStorage } from '../settings_storage'; -interface SavedIndexPatternAttributes extends SavedObjectAttributes { - title: string; - timeFieldName: string | null; - fields: string; - fieldFormatMap: string; - typeMeta: string; -} - type SetState = StateSetter; -type SavedObjectsClient = Pick; +type SavedObjectsClient = Pick; +type IndexPatternsService = Pick; type ErrorHandler = (err: Error) => void; export async function loadIndexPatterns({ + indexPatternsService, patterns, - savedObjectsClient, cache, }: { + indexPatternsService: IndexPatternsService; patterns: string[]; - savedObjectsClient: SavedObjectsClient; cache: Record; }) { const missingIds = patterns.filter((id) => !cache[id]); @@ -54,20 +45,62 @@ export async function loadIndexPatterns({ return cache; } - const resp = await savedObjectsClient.bulkGet( - missingIds.map((id) => ({ id, type: 'index-pattern' })) - ); + const indexPatterns = await Promise.all(missingIds.map((id) => indexPatternsService.get(id))); + const indexPatternsObject = indexPatterns.reduce( + (acc, indexPattern) => { + const newFields = indexPattern.fields + .filter( + (field) => + !indexPatternsUtils.isNestedField(field) && (!!field.aggregatable || !!field.scripted) + ) + .map( + (field): IndexPatternField => ({ + name: field.name, + displayName: field.displayName, + type: field.type, + aggregatable: field.aggregatable, + searchable: field.searchable, + scripted: field.scripted, + esTypes: field.esTypes, + }) + ) + .concat(documentField); + + const { typeMeta, title, timeFieldName, fieldFormatMap } = indexPattern; + if (typeMeta?.aggs) { + const aggs = Object.keys(typeMeta.aggs); + newFields.forEach((field, index) => { + const restrictionsObj: IndexPatternField['aggregationRestrictions'] = {}; + aggs.forEach((agg) => { + const restriction = + typeMeta.aggs && typeMeta.aggs[agg] && typeMeta.aggs[agg][field.name]; + if (restriction) { + restrictionsObj[agg] = restriction; + } + }); + if (Object.keys(restrictionsObj).length) { + newFields[index] = { ...field, aggregationRestrictions: restrictionsObj }; + } + }); + } - return resp.savedObjects.reduce( - (acc, savedObject) => { - const indexPattern = fromSavedObject( - savedObject as SimpleSavedObject - ); - acc[indexPattern.id] = indexPattern; - return acc; + const currentIndexPattern: IndexPattern = { + id: indexPattern.id!, // id exists for sure because we got index patterns by id + title, + timeFieldName, + fieldFormatMap, + fields: newFields, + }; + + return { + [currentIndexPattern.id]: currentIndexPattern, + ...acc, + }; }, { ...cache } ); + + return indexPatternsObject; } const getLastUsedIndexPatternId = ( @@ -87,11 +120,13 @@ export async function loadInitialState({ savedObjectsClient, defaultIndexPatternId, storage, + indexPatternsService, }: { state?: IndexPatternPersistedState; savedObjectsClient: SavedObjectsClient; defaultIndexPatternId?: string; storage: IStorageWrapper; + indexPatternsService: IndexPatternsService; }): Promise { const indexPatternRefs = await loadIndexPatternRefs(savedObjectsClient); const lastUsedIndexPatternId = getLastUsedIndexPatternId(storage, indexPatternRefs); @@ -108,7 +143,7 @@ export async function loadInitialState({ setLastUsedIndexPatternId(storage, currentIndexPatternId); const indexPatterns = await loadIndexPatterns({ - savedObjectsClient, + indexPatternsService, cache: {}, patterns: requiredPatterns, }); @@ -135,22 +170,22 @@ export async function loadInitialState({ export async function changeIndexPattern({ id, - savedObjectsClient, state, setState, onError, storage, + indexPatternsService, }: { id: string; - savedObjectsClient: SavedObjectsClient; state: IndexPatternPrivateState; setState: SetState; onError: ErrorHandler; storage: IStorageWrapper; + indexPatternsService: IndexPatternsService; }) { try { const indexPatterns = await loadIndexPatterns({ - savedObjectsClient, + indexPatternsService, cache: state.indexPatterns, patterns: [id], }); @@ -175,25 +210,25 @@ export async function changeIndexPattern({ export async function changeLayerIndexPattern({ indexPatternId, layerId, - savedObjectsClient, state, setState, onError, replaceIfPossible, storage, + indexPatternsService, }: { indexPatternId: string; layerId: string; - savedObjectsClient: SavedObjectsClient; state: IndexPatternPrivateState; setState: SetState; onError: ErrorHandler; replaceIfPossible?: boolean; storage: IStorageWrapper; + indexPatternsService: IndexPatternsService; }) { try { const indexPatterns = await loadIndexPatterns({ - savedObjectsClient, + indexPatternsService, cache: state.indexPatterns, patterns: [indexPatternId], }); @@ -319,55 +354,3 @@ function isSingleEmptyLayer(layerMap: IndexPatternPrivateState['layers']) { const layers = Object.values(layerMap); return layers.length === 1 && layers[0].columnOrder.length === 0; } - -function fromSavedObject( - savedObject: SimpleSavedObject -): IndexPattern { - const { id, attributes, type } = savedObject; - const indexPattern = { - ...attributes, - id, - type, - title: attributes.title, - fields: (JSON.parse(attributes.fields) as IFieldType[]) - .filter( - (field) => - !indexPatternsUtils.isNestedField(field) && (!!field.aggregatable || !!field.scripted) - ) - .concat(documentField) as IndexPatternField[], - typeMeta: attributes.typeMeta - ? (JSON.parse(attributes.typeMeta) as IndexPatternTypeMeta) - : undefined, - fieldFormatMap: attributes.fieldFormatMap ? JSON.parse(attributes.fieldFormatMap) : undefined, - }; - - const { typeMeta } = indexPattern; - if (!typeMeta) { - return indexPattern; - } - - const newFields = [...(indexPattern.fields as IndexPatternField[])]; - - if (typeMeta.aggs) { - const aggs = Object.keys(typeMeta.aggs); - newFields.forEach((field, index) => { - const restrictionsObj: IndexPatternField['aggregationRestrictions'] = {}; - aggs.forEach((agg) => { - const restriction = typeMeta.aggs && typeMeta.aggs[agg] && typeMeta.aggs[agg][field.name]; - if (restriction) { - restrictionsObj[agg] = restriction; - } - }); - if (Object.keys(restrictionsObj).length) { - newFields[index] = { ...field, aggregationRestrictions: restrictionsObj }; - } - }); - } - - return { - id: indexPattern.id, - title: indexPattern.title, - timeFieldName: indexPattern.timeFieldName || undefined, - fields: newFields, - }; -} diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/mocks.ts b/x-pack/plugins/lens/public/indexpattern_datasource/mocks.ts index dff3e61342a6a..869eee67d381d 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/mocks.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/mocks.ts @@ -14,39 +14,54 @@ export const createMockedIndexPattern = (): IndexPattern => ({ fields: [ { name: 'timestamp', + displayName: 'timestampLabel', type: 'date', aggregatable: true, searchable: true, }, { name: 'start_date', + displayName: 'start_date', type: 'date', aggregatable: true, searchable: true, }, { name: 'bytes', + displayName: 'bytes', type: 'number', aggregatable: true, searchable: true, }, { name: 'memory', + displayName: 'memory', type: 'number', aggregatable: true, searchable: true, }, { name: 'source', + displayName: 'source', type: 'string', aggregatable: true, searchable: true, + esTypes: ['keyword'], + }, + { + name: 'unsupported', + displayName: 'unsupported', + type: 'geo', + aggregatable: true, + searchable: true, }, { name: 'dest', + displayName: 'dest', type: 'string', aggregatable: true, searchable: true, + esTypes: ['keyword'], }, ], }); @@ -58,21 +73,26 @@ export const createMockedRestrictedIndexPattern = () => ({ fields: [ { name: 'timestamp', + displayName: 'timestampLabel', type: 'date', aggregatable: true, searchable: true, }, { name: 'bytes', + displayName: 'bytes', type: 'number', aggregatable: true, searchable: true, }, { name: 'source', + displayName: 'source', type: 'string', aggregatable: true, searchable: true, + scripted: true, + esTypes: ['keyword'], }, ], typeMeta: { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/cardinality.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/cardinality.tsx index 09faa4bb70447..ad04891b637d4 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/cardinality.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/cardinality.tsx @@ -51,7 +51,7 @@ export const cardinalityOperation: OperationDefinition { return { ...oldColumn, - label: ofName(field.name), + label: ofName(field.displayName), sourceField: field.name, }; }, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.tsx index 1dcaf78b58a6c..4e081da2c6dc9 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.tsx @@ -26,7 +26,7 @@ export const countOperation: OperationDefinition = { onFieldChange: (oldColumn, indexPattern, field) => { return { ...oldColumn, - label: field.name, + label: field.displayName, sourceField: field.name, }; }, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.test.tsx index ebf8e09e86396..48a6079c58ac0 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.test.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.test.tsx @@ -58,6 +58,7 @@ describe('date_histogram', () => { fields: [ { name: 'timestamp', + displayName: 'timestampLabel', type: 'date', esTypes: ['date'], aggregatable: true, @@ -71,6 +72,7 @@ describe('date_histogram', () => { fields: [ { name: 'other_timestamp', + displayName: 'other_timestamp', type: 'date', esTypes: ['date'], aggregatable: true, @@ -168,6 +170,7 @@ describe('date_histogram', () => { indexPattern: createMockedIndexPattern(), field: { name: 'timestamp', + displayName: 'timestampLabel', type: 'date', esTypes: ['date'], aggregatable: true, @@ -185,6 +188,7 @@ describe('date_histogram', () => { indexPattern: createMockedIndexPattern(), field: { name: 'start_date', + displayName: 'start_date', type: 'date', esTypes: ['date'], aggregatable: true, @@ -202,6 +206,7 @@ describe('date_histogram', () => { indexPattern: createMockedIndexPattern(), field: { name: 'timestamp', + displayName: 'timestampLabel', type: 'date', esTypes: ['date'], aggregatable: true, @@ -298,6 +303,7 @@ describe('date_histogram', () => { fields: [ { name: 'dateField', + displayName: 'dateField', type: 'date', aggregatable: true, searchable: true, @@ -340,6 +346,7 @@ describe('date_histogram', () => { fields: [ { name: 'dateField', + displayName: 'dateField', type: 'date', aggregatable: true, searchable: true, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.tsx index 6e007c12acf42..2236bc576e2b6 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.tsx @@ -64,7 +64,7 @@ export const dateHistogramOperation: OperationDefinition { return { ...oldColumn, - label: field.name, + label: field.displayName, sourceField: field.name, }; }, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/metrics.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/metrics.tsx index 3ede847a5e257..e6c8a5f6ac852 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/metrics.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/metrics.tsx @@ -51,7 +51,7 @@ function buildMetricOperation>({ ); }, buildColumn: ({ suggestedPriority, field, previousColumn }) => ({ - label: ofName(field.name), + label: ofName(field.displayName), dataType: 'number', operationType: type, suggestedPriority, @@ -64,7 +64,7 @@ function buildMetricOperation>({ onFieldChange: (oldColumn, indexPattern, field) => { return { ...oldColumn, - label: ofName(field.name), + label: ofName(field.displayName), sourceField: field.name, }; }, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms.test.tsx index d7f00e185a5bb..05bb2ef673888 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms.test.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms.test.tsx @@ -118,6 +118,7 @@ describe('terms', () => { aggregatable: true, searchable: true, name: 'test', + displayName: 'test', type: 'string', aggregationRestrictions: { terms: { @@ -136,6 +137,7 @@ describe('terms', () => { aggregatable: true, searchable: true, name: 'test', + displayName: 'test', type: 'number', aggregationRestrictions: { terms: { @@ -154,6 +156,7 @@ describe('terms', () => { aggregatable: true, searchable: true, name: 'test', + displayName: 'test', type: 'boolean', }) ).toEqual({ @@ -167,6 +170,7 @@ describe('terms', () => { aggregatable: true, searchable: true, name: 'test', + displayName: 'test', type: 'ip', }) ).toEqual({ @@ -182,6 +186,7 @@ describe('terms', () => { aggregatable: false, searchable: true, name: 'test', + displayName: 'test', type: 'string', }) ).toEqual(undefined); @@ -192,6 +197,7 @@ describe('terms', () => { aggregationRestrictions: {}, searchable: true, name: 'test', + displayName: 'test', type: 'string', }) ).toEqual(undefined); @@ -209,6 +215,7 @@ describe('terms', () => { searchable: true, type: 'boolean', name: 'test', + displayName: 'test', }, columns: {}, }); @@ -234,6 +241,7 @@ describe('terms', () => { searchable: true, type: 'boolean', name: 'test', + displayName: 'test', }, }); expect(termsColumn.params).toEqual( diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms.tsx index 1ab58cb11c598..ac1ff9da2fea0 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms.tsx @@ -79,7 +79,7 @@ export const termsOperation: OperationDefinition = { .map(([id]) => id)[0]; return { - label: ofName(field.name), + label: ofName(field.displayName), dataType: field.type as DataType, operationType: 'terms', scale: 'ordinal', @@ -115,7 +115,7 @@ export const termsOperation: OperationDefinition = { onFieldChange: (oldColumn, indexPattern, field) => { return { ...oldColumn, - label: ofName(field.name), + label: ofName(field.displayName), sourceField: field.name, }; }, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/operations.test.ts b/x-pack/plugins/lens/public/indexpattern_datasource/operations/operations.test.ts index 1a37e5e4cf6a4..3fce2562f528e 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/operations.test.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/operations.test.ts @@ -19,18 +19,21 @@ const expectedIndexPatterns = { fields: [ { name: 'timestamp', + displayName: 'timestamp', type: 'date', aggregatable: true, searchable: true, }, { name: 'bytes', + displayName: 'bytes', type: 'number', aggregatable: true, searchable: true, }, { name: 'source', + displayName: 'source', type: 'string', aggregatable: true, searchable: true, @@ -46,6 +49,7 @@ describe('getOperationTypesForField', () => { getOperationTypesForField({ type: 'string', name: 'a', + displayName: 'aLabel', aggregatable: true, searchable: true, }) @@ -57,6 +61,7 @@ describe('getOperationTypesForField', () => { getOperationTypesForField({ type: 'number', name: 'a', + displayName: 'aLabel', aggregatable: true, searchable: true, }) @@ -68,6 +73,7 @@ describe('getOperationTypesForField', () => { getOperationTypesForField({ type: 'date', name: 'a', + displayName: 'aLabel', aggregatable: true, searchable: true, }) @@ -79,6 +85,7 @@ describe('getOperationTypesForField', () => { getOperationTypesForField({ type: '_source', name: 'a', + displayName: 'aLabel', aggregatable: true, searchable: true, }) @@ -92,6 +99,7 @@ describe('getOperationTypesForField', () => { getOperationTypesForField({ type: 'string', name: 'a', + displayName: 'aLabel', aggregatable: true, searchable: true, aggregationRestrictions: { @@ -108,6 +116,7 @@ describe('getOperationTypesForField', () => { getOperationTypesForField({ type: 'number', name: 'a', + displayName: 'aLabel', aggregatable: true, searchable: true, aggregationRestrictions: { @@ -127,6 +136,7 @@ describe('getOperationTypesForField', () => { getOperationTypesForField({ type: 'date', name: 'a', + displayName: 'aLabel', aggregatable: true, searchable: true, aggregationRestrictions: { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/state_helpers.test.ts b/x-pack/plugins/lens/public/indexpattern_datasource/state_helpers.test.ts index d778749ef3940..d7fd0d3661c86 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/state_helpers.test.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/state_helpers.test.ts @@ -573,12 +573,14 @@ describe('state_helpers', () => { fields: [ { name: 'fieldA', + displayName: 'fieldA', aggregatable: true, searchable: true, type: 'string', }, { name: 'fieldB', + displayName: 'fieldB', aggregatable: true, searchable: true, type: 'number', @@ -590,12 +592,14 @@ describe('state_helpers', () => { }, { name: 'fieldC', + displayName: 'fieldC', aggregatable: false, searchable: true, type: 'date', }, { name: 'fieldD', + displayName: 'fieldD', aggregatable: true, searchable: true, type: 'date', @@ -609,6 +613,7 @@ describe('state_helpers', () => { }, { name: 'fieldE', + displayName: 'fieldE', aggregatable: true, searchable: true, type: 'date', diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/types.ts b/x-pack/plugins/lens/public/indexpattern_datasource/types.ts index 2a9b3f452d991..8d0e82b176aa9 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/types.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/types.ts @@ -23,6 +23,7 @@ export interface IndexPattern { export interface IndexPatternField { name: string; + displayName: string; type: string; esTypes?: string[]; aggregatable: boolean; From 506bf6c76455eb2264e5c67c0cfa9ce2c64253f7 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Fri, 21 Aug 2020 12:10:50 +0200 Subject: [PATCH 17/45] [Uptime] Add delay in telemetry test (#75162) Co-authored-by: Elastic Machine --- .../apis/uptime/rest/telemetry_collectors.ts | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/x-pack/test/api_integration/apis/uptime/rest/telemetry_collectors.ts b/x-pack/test/api_integration/apis/uptime/rest/telemetry_collectors.ts index f07ddf68152d3..cf1e7ff9f0716 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/telemetry_collectors.ts +++ b/x-pack/test/api_integration/apis/uptime/rest/telemetry_collectors.ts @@ -118,9 +118,9 @@ export default function ({ getService }: FtrProviderContext) { }); }); - it('should receive expected results after calling overview logging', async () => { + it('should receive 200 status after overview logging', async () => { // call overview page - const { body: result } = await supertest + await supertest .post(API_URLS.LOG_PAGE_VIEW) .set('kbn-xsrf', 'true') .send({ @@ -131,21 +131,6 @@ export default function ({ getService }: FtrProviderContext) { autoRefreshEnabled: true, }) .expect(200); - - expect(result).to.eql({ - overview_page: 1, - monitor_page: 1, - no_of_unique_monitors: 4, - settings_page: 0, - monitor_frequency: [120, 0.001, 60, 60], - monitor_name_stats: { min_length: 7, max_length: 22, avg_length: 12 }, - no_of_unique_observer_locations: 3, - observer_location_name_stats: { min_length: 2, max_length: 7, avg_length: 4.8 }, - dateRangeStart: ['now/d', 'now/d'], - dateRangeEnd: ['now/d', 'now-30'], - autoRefreshEnabled: true, - autorefreshInterval: [100, 60], - }); }); }); } From 7376e4ca3dcd0e40b132c55dcd379b1356522599 Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Fri, 21 Aug 2020 12:20:46 +0200 Subject: [PATCH 18/45] [Console] Get ES Config from core (#75406) * Server side changes - removed console_legacy plugin! - added new es_config endpoint that returns server side es config at the moment this is just the first value in hosts - Slight refactor to how routes are registered to bring them more in line with other ES UI plugins * Client side update - Updated the client to not get es host from injected metadata. Instead use the new endpoint created server side that returns this value - Added a small README.md regarding the hooks lib and need to refactor use of jQuery in console - Write code to init the es host value on the client once at start up in a non-blocking way. If this fails we just use the default value of http://localhost:9200 as this powers non-essential console functionality (i.e., copy as cURL). * fix type issue and jest tests * fix another type issue * simplify proxy assignment in proxy handler mock Co-authored-by: Elastic Machine --- .../core_plugins/console_legacy/index.ts | 49 -------------- .../core_plugins/console_legacy/package.json | 4 -- .../console/common/types/api_responses.ts | 29 +++++++++ .../editor/legacy/console_editor/editor.tsx | 5 +- .../contexts/services_context.mock.ts | 8 ++- .../application/contexts/services_context.tsx | 30 +++++---- .../public/application/hooks/README.md | 5 ++ .../console/public/application/index.tsx | 11 ++-- .../console/public/application/lib/api.ts | 39 +++++++++++ .../public/application/lib/es_host_service.ts | 54 ++++++++++++++++ .../console/public/application/lib/index.ts | 21 ++++++ src/plugins/console/public/plugin.ts | 10 +-- src/plugins/console/public/shared_imports.ts | 22 +++++++ .../server/__tests__/proxy_route/mocks.ts | 46 +++++++++---- .../__tests__/proxy_route/params.test.ts | 8 ++- .../proxy_route/proxy_fallback.test.ts | 14 ++-- src/plugins/console/server/plugin.ts | 54 +++++++++------- .../routes/api/console/es_config/index.ts | 33 ++++++++++ .../api/console/proxy/create_handler.ts | 25 ++------ .../server/routes/api/console/proxy/index.ts | 16 ++--- .../api/console/spec_definitions/index.ts | 14 ++-- src/plugins/console/server/routes/index.ts | 50 +++++++++++++++ .../services/es_legacy_config_service.ts | 64 +++++++++++++++++++ src/plugins/console/server/services/index.ts | 2 + src/plugins/console/server/types.ts | 2 +- 25 files changed, 451 insertions(+), 164 deletions(-) delete mode 100644 src/legacy/core_plugins/console_legacy/index.ts delete mode 100644 src/legacy/core_plugins/console_legacy/package.json create mode 100644 src/plugins/console/common/types/api_responses.ts create mode 100644 src/plugins/console/public/application/hooks/README.md create mode 100644 src/plugins/console/public/application/lib/api.ts create mode 100644 src/plugins/console/public/application/lib/es_host_service.ts create mode 100644 src/plugins/console/public/application/lib/index.ts create mode 100644 src/plugins/console/public/shared_imports.ts create mode 100644 src/plugins/console/server/routes/api/console/es_config/index.ts create mode 100644 src/plugins/console/server/routes/index.ts create mode 100644 src/plugins/console/server/services/es_legacy_config_service.ts diff --git a/src/legacy/core_plugins/console_legacy/index.ts b/src/legacy/core_plugins/console_legacy/index.ts deleted file mode 100644 index 82e00a99c6cfd..0000000000000 --- a/src/legacy/core_plugins/console_legacy/index.ts +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { first } from 'rxjs/operators'; -import { head } from 'lodash'; -import url from 'url'; - -// TODO: Remove this hack once we can get the ES config we need for Console proxy a better way. -let _legacyEsConfig: any; -export const readLegacyEsConfig = () => { - return _legacyEsConfig; -}; - -// eslint-disable-next-line import/no-default-export -export default function (kibana: any) { - return new kibana.Plugin({ - id: 'console_legacy', - - async init(server: any) { - _legacyEsConfig = await server.newPlatform.__internals.elasticsearch.legacy.config$ - .pipe(first()) - .toPromise(); - }, - - uiExports: { - injectDefaultVars: () => ({ - elasticsearchUrl: url.format( - Object.assign(url.parse(head(_legacyEsConfig.hosts) as any), { auth: false }) - ), - }), - }, - } as any); -} diff --git a/src/legacy/core_plugins/console_legacy/package.json b/src/legacy/core_plugins/console_legacy/package.json deleted file mode 100644 index b78807daed959..0000000000000 --- a/src/legacy/core_plugins/console_legacy/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "console_legacy", - "version": "kibana" -} diff --git a/src/plugins/console/common/types/api_responses.ts b/src/plugins/console/common/types/api_responses.ts new file mode 100644 index 0000000000000..1c8166bbe27f2 --- /dev/null +++ b/src/plugins/console/common/types/api_responses.ts @@ -0,0 +1,29 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export interface EsConfigApiResponse { + /** + * This is the first host in the hosts array that Kibana is configured to use + * to communicate with ES. + * + * At the moment this is used to power the copy as cURL functionality in Console + * to complete the host portion of the URL. + */ + host?: string; +} diff --git a/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.tsx b/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.tsx index 880069d8ebc7a..fc88b31711b23 100644 --- a/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.tsx +++ b/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.tsx @@ -67,9 +67,8 @@ const inputId = 'ConAppInputTextarea'; function EditorUI({ initialTextValue }: EditorProps) { const { - services: { history, notifications, settings: settingsService }, + services: { history, notifications, settings: settingsService, esHostService }, docLinkVersion, - elasticsearchUrl, } = useServicesContext(); const { settings } = useEditorReadContext(); @@ -232,7 +231,7 @@ function EditorUI({ initialTextValue }: EditorProps) { { - return editorInstanceRef.current!.getRequestsAsCURL(elasticsearchUrl); + return editorInstanceRef.current!.getRequestsAsCURL(esHostService.getHost()); }} getDocumentation={() => { return getDocumentation(editorInstanceRef.current!, docLinkVersion); diff --git a/src/plugins/console/public/application/contexts/services_context.mock.ts b/src/plugins/console/public/application/contexts/services_context.mock.ts index ae8d15a890782..ba982d3f50cfb 100644 --- a/src/plugins/console/public/application/contexts/services_context.mock.ts +++ b/src/plugins/console/public/application/contexts/services_context.mock.ts @@ -17,21 +17,27 @@ * under the License. */ import { notificationServiceMock } from '../../../../../core/public/mocks'; +import { httpServiceMock } from '../../../../../core/public/mocks'; + import { HistoryMock } from '../../services/history.mock'; import { SettingsMock } from '../../services/settings.mock'; import { StorageMock } from '../../services/storage.mock'; +import { createApi, createEsHostService } from '../lib'; import { ContextValue } from './services_context'; export const serviceContextMock = { create: (): ContextValue => { const storage = new StorageMock({} as any, 'test'); + const http = httpServiceMock.createSetupContract(); + const api = createApi({ http }); + const esHostService = createEsHostService({ api }); (storage.keys as jest.Mock).mockImplementation(() => []); return { - elasticsearchUrl: 'test', services: { trackUiMetric: { count: () => {}, load: () => {} }, storage, + esHostService, settings: new SettingsMock(storage), history: new HistoryMock(storage), notifications: notificationServiceMock.createSetupContract(), diff --git a/src/plugins/console/public/application/contexts/services_context.tsx b/src/plugins/console/public/application/contexts/services_context.tsx index 3d4ac3291c5ac..e2f01a152b27b 100644 --- a/src/plugins/console/public/application/contexts/services_context.tsx +++ b/src/plugins/console/public/application/contexts/services_context.tsx @@ -17,22 +17,25 @@ * under the License. */ -import React, { createContext, useContext } from 'react'; +import React, { createContext, useContext, useEffect } from 'react'; import { NotificationsSetup } from 'kibana/public'; -import { History, Storage, Settings } from '../../services'; +import { History, Settings, Storage } from '../../services'; import { ObjectStorageClient } from '../../../common/types'; import { MetricsTracker } from '../../types'; +import { EsHostService } from '../lib'; + +interface ContextServices { + history: History; + storage: Storage; + settings: Settings; + notifications: NotificationsSetup; + objectStorageClient: ObjectStorageClient; + trackUiMetric: MetricsTracker; + esHostService: EsHostService; +} export interface ContextValue { - services: { - history: History; - storage: Storage; - settings: Settings; - notifications: NotificationsSetup; - objectStorageClient: ObjectStorageClient; - trackUiMetric: MetricsTracker; - }; - elasticsearchUrl: string; + services: ContextServices; docLinkVersion: string; } @@ -44,6 +47,11 @@ interface ContextProps { const ServicesContext = createContext(null as any); export function ServicesContextProvider({ children, value }: ContextProps) { + useEffect(() => { + // Fire and forget, we attempt to init the host service once. + value.services.esHostService.init(); + }, [value.services.esHostService]); + return {children}; } diff --git a/src/plugins/console/public/application/hooks/README.md b/src/plugins/console/public/application/hooks/README.md new file mode 100644 index 0000000000000..10057193560e9 --- /dev/null +++ b/src/plugins/console/public/application/hooks/README.md @@ -0,0 +1,5 @@ +## Notes + +* Do not add any code directly to this directory. This code should be moved to the neighbouring `lib` directory to be in line with future ES UI plugin patterns. + +* The `es.send` method uses $.ajax under the hood and needs to be refactored to use the new platform-provided http client. \ No newline at end of file diff --git a/src/plugins/console/public/application/index.tsx b/src/plugins/console/public/application/index.tsx index 051eaea27a7de..0a5a502eb5062 100644 --- a/src/plugins/console/public/application/index.tsx +++ b/src/plugins/console/public/application/index.tsx @@ -19,19 +19,20 @@ import React from 'react'; import { render, unmountComponentAtNode } from 'react-dom'; -import { NotificationsSetup } from 'src/core/public'; +import { HttpSetup, NotificationsSetup } from 'src/core/public'; import { ServicesContextProvider, EditorContextProvider, RequestContextProvider } from './contexts'; import { Main } from './containers'; import { createStorage, createHistory, createSettings } from '../services'; import * as localStorageObjectClient from '../lib/local_storage_object_client'; import { createUsageTracker } from '../services/tracker'; import { UsageCollectionSetup } from '../../../usage_collection/public'; +import { createApi, createEsHostService } from './lib'; export interface BootDependencies { + http: HttpSetup; docLinkVersion: string; I18nContext: any; notifications: NotificationsSetup; - elasticsearchUrl: string; usageCollection?: UsageCollectionSetup; element: HTMLElement; } @@ -40,9 +41,9 @@ export function renderApp({ I18nContext, notifications, docLinkVersion, - elasticsearchUrl, usageCollection, element, + http, }: BootDependencies) { const trackUiMetric = createUsageTracker(usageCollection); trackUiMetric.load('opened_app'); @@ -54,14 +55,16 @@ export function renderApp({ const history = createHistory({ storage }); const settings = createSettings({ storage }); const objectStorageClient = localStorageObjectClient.create(storage); + const api = createApi({ http }); + const esHostService = createEsHostService({ api }); render( ; + +export const createApi = ({ http }: Dependencies) => { + return { + getEsConfig: () => { + return sendRequest(http, { + path: '/api/console/es_config', + method: 'get', + }); + }, + }; +}; diff --git a/src/plugins/console/public/application/lib/es_host_service.ts b/src/plugins/console/public/application/lib/es_host_service.ts new file mode 100644 index 0000000000000..887f270a24687 --- /dev/null +++ b/src/plugins/console/public/application/lib/es_host_service.ts @@ -0,0 +1,54 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { Api } from './api'; + +/** + * Very simple state for holding the current ES host. + * + * This is used to power the copy as cURL functionality. + */ +export class EsHostService { + private host = 'http://localhost:9200'; + + constructor(private readonly api: Api) {} + + private setHost(host: string): void { + this.host = host; + } + + /** + * Initialize the host value based on the value set on the server. + * + * This call is necessary because this value can only be retrieved at + * runtime. + */ + public async init() { + const { data } = await this.api.getEsConfig(); + if (data && data.host) { + this.setHost(data.host); + } + } + + public getHost(): string { + return this.host; + } +} + +export const createEsHostService = ({ api }: { api: Api }) => new EsHostService(api); diff --git a/src/plugins/console/public/application/lib/index.ts b/src/plugins/console/public/application/lib/index.ts new file mode 100644 index 0000000000000..1ba99cc607269 --- /dev/null +++ b/src/plugins/console/public/application/lib/index.ts @@ -0,0 +1,21 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export { createApi, Api } from './api'; +export { createEsHostService, EsHostService } from './es_host_service'; diff --git a/src/plugins/console/public/plugin.ts b/src/plugins/console/public/plugin.ts index 851dc7a063d7b..03b65a8bd145c 100644 --- a/src/plugins/console/public/plugin.ts +++ b/src/plugins/console/public/plugin.ts @@ -25,7 +25,7 @@ import { AppSetupUIPluginDependencies } from './types'; export class ConsoleUIPlugin implements Plugin { public setup( - { notifications, getStartServices }: CoreSetup, + { notifications, getStartServices, http }: CoreSetup, { devTools, home, usageCollection }: AppSetupUIPluginDependencies ) { home.featureCatalogue.register({ @@ -53,23 +53,17 @@ export class ConsoleUIPlugin implements Plugin ({ import { duration } from 'moment'; import { ProxyConfigCollection } from '../../lib'; -import { CreateHandlerDependencies } from '../../routes/api/console/proxy/create_handler'; -import { coreMock } from '../../../../../core/server/mocks'; +import { RouteDependencies, ProxyDependencies } from '../../routes'; +import { EsLegacyConfigService, SpecDefinitionsService } from '../../services'; +import { coreMock, httpServiceMock } from '../../../../../core/server/mocks'; -export const getProxyRouteHandlerDeps = ({ - proxyConfigCollection = new ProxyConfigCollection([]), - pathFilters = [/.*/], - readLegacyESConfig = () => ({ +const defaultProxyValue = Object.freeze({ + readLegacyESConfig: async () => ({ requestTimeout: duration(30000), customHeaders: {}, requestHeadersWhitelist: [], hosts: ['http://localhost:9200'], }), - log = coreMock.createPluginInitializerContext().logger.get(), -}: Partial): CreateHandlerDependencies => ({ - proxyConfigCollection, - pathFilters, - readLegacyESConfig, - log, + pathFilters: [/.*/], + proxyConfigCollection: new ProxyConfigCollection([]), }); + +interface MockDepsArgument extends Partial> { + proxy?: Partial; +} + +export const getProxyRouteHandlerDeps = ({ + proxy, + log = coreMock.createPluginInitializerContext().logger.get(), + router = httpServiceMock.createSetupContract().createRouter(), +}: MockDepsArgument): RouteDependencies => { + const services: RouteDependencies['services'] = { + esLegacyConfigService: new EsLegacyConfigService(), + specDefinitionService: new SpecDefinitionsService(), + }; + + return { + services, + router, + proxy: proxy + ? { + ...defaultProxyValue, + ...proxy, + } + : defaultProxyValue, + log, + }; +}; diff --git a/src/plugins/console/server/__tests__/proxy_route/params.test.ts b/src/plugins/console/server/__tests__/proxy_route/params.test.ts index 1ab9c3ae789cc..e1c5295f6d30f 100644 --- a/src/plugins/console/server/__tests__/proxy_route/params.test.ts +++ b/src/plugins/console/server/__tests__/proxy_route/params.test.ts @@ -36,7 +36,7 @@ describe('Console Proxy Route', () => { describe('no matches', () => { it('rejects with 403', async () => { handler = createHandler( - getProxyRouteHandlerDeps({ pathFilters: [/^\/foo\//, /^\/bar\//] }) + getProxyRouteHandlerDeps({ proxy: { pathFilters: [/^\/foo\//, /^\/bar\//] } }) ); const { status } = await handler( @@ -51,7 +51,7 @@ describe('Console Proxy Route', () => { describe('one match', () => { it('allows the request', async () => { handler = createHandler( - getProxyRouteHandlerDeps({ pathFilters: [/^\/foo\//, /^\/bar\//] }) + getProxyRouteHandlerDeps({ proxy: { pathFilters: [/^\/foo\//, /^\/bar\//] } }) ); (requestModule.proxyRequest as jest.Mock).mockResolvedValue(createResponseStub('foo')); @@ -68,7 +68,9 @@ describe('Console Proxy Route', () => { }); describe('all match', () => { it('allows the request', async () => { - handler = createHandler(getProxyRouteHandlerDeps({ pathFilters: [/^\/foo\//] })); + handler = createHandler( + getProxyRouteHandlerDeps({ proxy: { pathFilters: [/^\/foo\//] } }) + ); (requestModule.proxyRequest as jest.Mock).mockResolvedValue(createResponseStub('foo')); diff --git a/src/plugins/console/server/__tests__/proxy_route/proxy_fallback.test.ts b/src/plugins/console/server/__tests__/proxy_route/proxy_fallback.test.ts index b226bad11a01a..fc5233d0f833d 100644 --- a/src/plugins/console/server/__tests__/proxy_route/proxy_fallback.test.ts +++ b/src/plugins/console/server/__tests__/proxy_route/proxy_fallback.test.ts @@ -38,12 +38,14 @@ describe('Console Proxy Route', () => { const handler = createHandler( getProxyRouteHandlerDeps({ - readLegacyESConfig: () => ({ - requestTimeout: duration(30000), - customHeaders: {}, - requestHeadersWhitelist: [], - hosts: ['http://localhost:9201', 'http://localhost:9202', 'http://localhost:9203'], - }), + proxy: { + readLegacyESConfig: async () => ({ + requestTimeout: duration(30000), + customHeaders: {}, + requestHeadersWhitelist: [], + hosts: ['http://localhost:9201', 'http://localhost:9202', 'http://localhost:9203'], + }), + }, }) ); diff --git a/src/plugins/console/server/plugin.ts b/src/plugins/console/server/plugin.ts index eedd1541e8898..a76a35f8146c9 100644 --- a/src/plugins/console/server/plugin.ts +++ b/src/plugins/console/server/plugin.ts @@ -19,13 +19,12 @@ import { first } from 'rxjs/operators'; import { CoreSetup, Logger, Plugin, PluginInitializerContext } from 'kibana/server'; -import { readLegacyEsConfig } from '../../../legacy/core_plugins/console_legacy'; - import { ProxyConfigCollection } from './lib'; -import { SpecDefinitionsService } from './services'; +import { SpecDefinitionsService, EsLegacyConfigService } from './services'; import { ConfigType } from './config'; -import { registerProxyRoute } from './routes/api/console/proxy'; -import { registerSpecDefinitionsRoute } from './routes/api/console/spec_definitions'; + +import { registerRoutes } from './routes'; + import { ESConfigForProxy, ConsoleSetup, ConsoleStart } from './types'; export class ConsoleServerPlugin implements Plugin { @@ -33,11 +32,13 @@ export class ConsoleServerPlugin implements Plugin { specDefinitionsService = new SpecDefinitionsService(); + esLegacyConfigService = new EsLegacyConfigService(); + constructor(private readonly ctx: PluginInitializerContext) { this.log = this.ctx.logger.get(); } - async setup({ http, capabilities, getStartServices }: CoreSetup) { + async setup({ http, capabilities, getStartServices, elasticsearch }: CoreSetup) { capabilities.registerProvider(() => ({ dev_tools: { show: true, @@ -46,30 +47,31 @@ export class ConsoleServerPlugin implements Plugin { })); const config = await this.ctx.config.create().pipe(first()).toPromise(); - - const { elasticsearch } = await this.ctx.config.legacy.globalConfig$.pipe(first()).toPromise(); - + const globalConfig = await this.ctx.config.legacy.globalConfig$.pipe(first()).toPromise(); const proxyPathFilters = config.proxyFilter.map((str: string) => new RegExp(str)); + this.esLegacyConfigService.setup(elasticsearch.legacy.config$); + const router = http.createRouter(); - registerProxyRoute({ + registerRoutes({ + router, log: this.log, - proxyConfigCollection: new ProxyConfigCollection(config.proxyConfig), - readLegacyESConfig: (): ESConfigForProxy => { - const legacyConfig = readLegacyEsConfig(); - return { - ...elasticsearch, - ...legacyConfig, - }; + services: { + esLegacyConfigService: this.esLegacyConfigService, + specDefinitionService: this.specDefinitionsService, + }, + proxy: { + proxyConfigCollection: new ProxyConfigCollection(config.proxyConfig), + readLegacyESConfig: async (): Promise => { + const legacyConfig = await this.esLegacyConfigService.readConfig(); + return { + ...globalConfig.elasticsearch, + ...legacyConfig, + }; + }, + pathFilters: proxyPathFilters, }, - pathFilters: proxyPathFilters, - router, - }); - - registerSpecDefinitionsRoute({ - router, - services: { specDefinitions: this.specDefinitionsService }, }); return { @@ -82,4 +84,8 @@ export class ConsoleServerPlugin implements Plugin { ...this.specDefinitionsService.start(), }; } + + stop() { + this.esLegacyConfigService.stop(); + } } diff --git a/src/plugins/console/server/routes/api/console/es_config/index.ts b/src/plugins/console/server/routes/api/console/es_config/index.ts new file mode 100644 index 0000000000000..a115a6b32ad01 --- /dev/null +++ b/src/plugins/console/server/routes/api/console/es_config/index.ts @@ -0,0 +1,33 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { EsConfigApiResponse } from '../../../../../common/types/api_responses'; +import { RouteDependencies } from '../../../'; + +export const registerEsConfigRoute = ({ router, services }: RouteDependencies): void => { + router.get({ path: '/api/console/es_config', validate: false }, async (ctx, req, res) => { + const { + hosts: [host], + } = await services.esLegacyConfigService.readConfig(); + + const body: EsConfigApiResponse = { host }; + + return res.ok({ body }); + }); +}; diff --git a/src/plugins/console/server/routes/api/console/proxy/create_handler.ts b/src/plugins/console/server/routes/api/console/proxy/create_handler.ts index a16fb1dadfbcf..f6d9bcb77ddda 100644 --- a/src/plugins/console/server/routes/api/console/proxy/create_handler.ts +++ b/src/plugins/console/server/routes/api/console/proxy/create_handler.ts @@ -21,7 +21,7 @@ import { Agent, IncomingMessage } from 'http'; import * as url from 'url'; import { pick, trimStart, trimEnd } from 'lodash'; -import { KibanaRequest, Logger, RequestHandler } from 'kibana/server'; +import { KibanaRequest, RequestHandler } from 'kibana/server'; import { ESConfigForProxy } from '../../../../types'; import { @@ -31,19 +31,14 @@ import { setHeaders, } from '../../../../lib'; -import { Body, Query } from './validation_config'; - // TODO: find a better way to get information from the request like remoteAddress and remotePort // for forwarding. // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { ensureRawRequest } from '../../../../../../../core/server/http/router'; -export interface CreateHandlerDependencies { - log: Logger; - readLegacyESConfig: () => ESConfigForProxy; - pathFilters: RegExp[]; - proxyConfigCollection: ProxyConfigCollection; -} +import { RouteDependencies } from '../../../'; + +import { Body, Query } from './validation_config'; function toURL(base: string, path: string) { const urlResult = new url.URL(`${trimEnd(base, '/')}/${trimStart(path, '/')}`); @@ -120,14 +115,8 @@ function getProxyHeaders(req: KibanaRequest) { export const createHandler = ({ log, - readLegacyESConfig, - pathFilters, - proxyConfigCollection, -}: CreateHandlerDependencies): RequestHandler => async ( - ctx, - request, - response -) => { + proxy: { readLegacyESConfig, pathFilters, proxyConfigCollection }, +}: RouteDependencies): RequestHandler => async (ctx, request, response) => { const { body, query } = request; const { path, method } = query; @@ -140,7 +129,7 @@ export const createHandler = ({ }); } - const legacyConfig = readLegacyESConfig(); + const legacyConfig = await readLegacyESConfig(); const { hosts } = legacyConfig; let esIncomingMessage: IncomingMessage; diff --git a/src/plugins/console/server/routes/api/console/proxy/index.ts b/src/plugins/console/server/routes/api/console/proxy/index.ts index 5f7df1d7cf66b..5841671c340bd 100644 --- a/src/plugins/console/server/routes/api/console/proxy/index.ts +++ b/src/plugins/console/server/routes/api/console/proxy/index.ts @@ -17,17 +17,13 @@ * under the License. */ -import { IRouter } from 'kibana/server'; import { routeValidationConfig } from './validation_config'; -import { createHandler, CreateHandlerDependencies } from './create_handler'; +import { createHandler } from './create_handler'; -export const registerProxyRoute = ( - deps: { - router: IRouter; - } & CreateHandlerDependencies -) => { - const { router, ...handlerDeps } = deps; - router.post( +import { RouteDependencies } from '../../../'; + +export const registerProxyRoute = (deps: RouteDependencies) => { + deps.router.post( { path: '/api/console/proxy', options: { @@ -39,6 +35,6 @@ export const registerProxyRoute = ( }, validate: routeValidationConfig, }, - createHandler(handlerDeps) + createHandler(deps) ); }; diff --git a/src/plugins/console/server/routes/api/console/spec_definitions/index.ts b/src/plugins/console/server/routes/api/console/spec_definitions/index.ts index 5c7e679cd0d35..a179c36364e26 100644 --- a/src/plugins/console/server/routes/api/console/spec_definitions/index.ts +++ b/src/plugins/console/server/routes/api/console/spec_definitions/index.ts @@ -16,8 +16,8 @@ * specific language governing permissions and limitations * under the License. */ -import { IRouter, RequestHandler } from 'kibana/server'; -import { SpecDefinitionsService } from '../../../../services'; +import { RequestHandler } from 'kibana/server'; +import { RouteDependencies } from '../../../'; interface SpecDefinitionsRouteResponse { es: { @@ -27,16 +27,10 @@ interface SpecDefinitionsRouteResponse { }; } -export const registerSpecDefinitionsRoute = ({ - router, - services, -}: { - router: IRouter; - services: { specDefinitions: SpecDefinitionsService }; -}) => { +export const registerSpecDefinitionsRoute = ({ router, services }: RouteDependencies) => { const handler: RequestHandler = async (ctx, request, response) => { const specResponse: SpecDefinitionsRouteResponse = { - es: services.specDefinitions.asJson(), + es: services.specDefinitionService.asJson(), }; return response.ok({ diff --git a/src/plugins/console/server/routes/index.ts b/src/plugins/console/server/routes/index.ts new file mode 100644 index 0000000000000..cbd1cef7b36e3 --- /dev/null +++ b/src/plugins/console/server/routes/index.ts @@ -0,0 +1,50 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { IRouter, Logger } from 'kibana/server'; + +import { EsLegacyConfigService, SpecDefinitionsService } from '../services'; +import { ESConfigForProxy } from '../types'; +import { ProxyConfigCollection } from '../lib'; + +import { registerEsConfigRoute } from './api/console/es_config'; +import { registerProxyRoute } from './api/console/proxy'; +import { registerSpecDefinitionsRoute } from './api/console/spec_definitions'; + +export interface ProxyDependencies { + readLegacyESConfig: () => Promise; + pathFilters: RegExp[]; + proxyConfigCollection: ProxyConfigCollection; +} + +export interface RouteDependencies { + router: IRouter; + log: Logger; + proxy: ProxyDependencies; + services: { + esLegacyConfigService: EsLegacyConfigService; + specDefinitionService: SpecDefinitionsService; + }; +} + +export const registerRoutes = (dependencies: RouteDependencies) => { + registerEsConfigRoute(dependencies); + registerProxyRoute(dependencies); + registerSpecDefinitionsRoute(dependencies); +}; diff --git a/src/plugins/console/server/services/es_legacy_config_service.ts b/src/plugins/console/server/services/es_legacy_config_service.ts new file mode 100644 index 0000000000000..37928839b1846 --- /dev/null +++ b/src/plugins/console/server/services/es_legacy_config_service.ts @@ -0,0 +1,64 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { Observable, Subscription } from 'rxjs'; +import { first } from 'rxjs/operators'; +import { ElasticsearchConfig } from 'kibana/server'; + +export class EsLegacyConfigService { + /** + * The elasticsearch config value at a given point in time. + */ + private config?: ElasticsearchConfig; + + /** + * An observable that emits elasticsearch config. + */ + private config$?: Observable; + + /** + * A reference to the subscription to the elasticsearch observable + */ + private configSub?: Subscription; + + setup(config$: Observable) { + this.config$ = config$; + this.configSub = this.config$.subscribe((config) => { + this.config = config; + }); + } + + stop() { + if (this.configSub) { + this.configSub.unsubscribe(); + } + } + + async readConfig(): Promise { + if (!this.config$) { + throw new Error('Could not read elasticsearch config, this service has not been setup!'); + } + + if (!this.config) { + return this.config$.pipe(first()).toPromise(); + } + + return this.config; + } +} diff --git a/src/plugins/console/server/services/index.ts b/src/plugins/console/server/services/index.ts index c8dfeccd23070..c9d0b8b858150 100644 --- a/src/plugins/console/server/services/index.ts +++ b/src/plugins/console/server/services/index.ts @@ -17,4 +17,6 @@ * under the License. */ +export { EsLegacyConfigService } from './es_legacy_config_service'; + export { SpecDefinitionsService } from './spec_definitions_service'; diff --git a/src/plugins/console/server/types.ts b/src/plugins/console/server/types.ts index 4f026555ada7b..5dc8322c23ea9 100644 --- a/src/plugins/console/server/types.ts +++ b/src/plugins/console/server/types.ts @@ -38,8 +38,8 @@ export interface ESConfigForProxy { requestTimeout: Duration; ssl?: { verificationMode: 'none' | 'certificate' | 'full'; - certificateAuthorities: string[] | string; alwaysPresentCertificate: boolean; + certificateAuthorities?: string[]; certificate?: string; key?: string; keyPassphrase?: string; From fd459dea5d884e883be6fe26747121e768a7844b Mon Sep 17 00:00:00 2001 From: Pierre Gayvallet Date: Fri, 21 Aug 2020 14:35:31 +0200 Subject: [PATCH 19/45] Migrate CSP usage collector to `kibana_usage_collection` plugin (#75536) * move csp usage collector from legacy kibana plugin to kibana_usage_collection * make scripts/telemetry_check happy. * remove assertion on legacy kibana plugin * remove test on legacy kibana plugin * update README --- src/legacy/core_plugins/kibana/index.js | 6 ---- src/plugins/kibana_usage_collection/README.md | 1 + .../server/__snapshots__/index.test.ts.snap | 2 ++ .../collectors/csp}/csp_collector.test.ts | 29 ++++++------------- .../server/collectors/csp}/csp_collector.ts | 21 +++++++------- .../server/collectors/csp}/index.ts | 0 .../server/collectors/index.ts | 1 + .../kibana_usage_collection/server/plugin.ts | 12 ++++---- test/api_integration/apis/status/status.js | 4 --- test/functional/apps/status_page/index.ts | 8 ----- 10 files changed, 29 insertions(+), 55 deletions(-) rename src/{legacy/core_plugins/kibana/server/lib/csp_usage_collector => plugins/kibana_usage_collection/server/collectors/csp}/csp_collector.test.ts (79%) rename src/{legacy/core_plugins/kibana/server/lib/csp_usage_collector => plugins/kibana_usage_collection/server/collectors/csp}/csp_collector.ts (75%) rename src/{legacy/core_plugins/kibana/server/lib/csp_usage_collector => plugins/kibana_usage_collection/server/collectors/csp}/index.ts (100%) diff --git a/src/legacy/core_plugins/kibana/index.js b/src/legacy/core_plugins/kibana/index.js index 2e30bc5ce05ee..176c5386961a5 100644 --- a/src/legacy/core_plugins/kibana/index.js +++ b/src/legacy/core_plugins/kibana/index.js @@ -21,7 +21,6 @@ import Fs from 'fs'; import { promisify } from 'util'; import { getUiSettingDefaults } from './server/ui_setting_defaults'; -import { registerCspCollector } from './server/lib/csp_usage_collector'; const mkdirAsync = promisify(Fs.mkdir); @@ -53,10 +52,5 @@ export default function (kibana) { throw err; } }, - - init: async function (server) { - const { usageCollection } = server.newPlatform.setup.plugins; - registerCspCollector(usageCollection, server); - }, }); } diff --git a/src/plugins/kibana_usage_collection/README.md b/src/plugins/kibana_usage_collection/README.md index 6ef4f19c1570f..73a4d53f305f2 100644 --- a/src/plugins/kibana_usage_collection/README.md +++ b/src/plugins/kibana_usage_collection/README.md @@ -7,3 +7,4 @@ This plugin registers the basic usage collectors from Kibana: - Ops stats - Number of Saved Objects per type - Non-default UI Settings +- CSP configuration diff --git a/src/plugins/kibana_usage_collection/server/__snapshots__/index.test.ts.snap b/src/plugins/kibana_usage_collection/server/__snapshots__/index.test.ts.snap index f07912eff02b7..47a4c458a8398 100644 --- a/src/plugins/kibana_usage_collection/server/__snapshots__/index.test.ts.snap +++ b/src/plugins/kibana_usage_collection/server/__snapshots__/index.test.ts.snap @@ -9,3 +9,5 @@ exports[`kibana_usage_collection Runs the setup method without issues 3`] = `fal exports[`kibana_usage_collection Runs the setup method without issues 4`] = `false`; exports[`kibana_usage_collection Runs the setup method without issues 5`] = `false`; + +exports[`kibana_usage_collection Runs the setup method without issues 6`] = `true`; diff --git a/src/legacy/core_plugins/kibana/server/lib/csp_usage_collector/csp_collector.test.ts b/src/plugins/kibana_usage_collection/server/collectors/csp/csp_collector.test.ts similarity index 79% rename from src/legacy/core_plugins/kibana/server/lib/csp_usage_collector/csp_collector.test.ts rename to src/plugins/kibana_usage_collection/server/collectors/csp/csp_collector.test.ts index 63c2cbec21b57..465b21e3578ba 100644 --- a/src/legacy/core_plugins/kibana/server/lib/csp_usage_collector/csp_collector.test.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/csp/csp_collector.test.ts @@ -17,35 +17,24 @@ * under the License. */ -import { CspConfig, ICspConfig } from '../../../../../../core/server'; +import { CspConfig, ICspConfig } from '../../../../../core/server'; import { createCspCollector } from './csp_collector'; - -const createMockKbnServer = () => ({ - newPlatform: { - setup: { - core: { - http: { - csp: new CspConfig(), - }, - }, - }, - }, -}); +import { httpServiceMock } from '../../../../../core/server/mocks'; describe('csp collector', () => { - let kbnServer: ReturnType; + let httpMock: ReturnType; const mockCallCluster = null as any; function updateCsp(config: Partial) { - kbnServer.newPlatform.setup.core.http.csp = new CspConfig(config); + httpMock.csp = new CspConfig(config); } beforeEach(() => { - kbnServer = createMockKbnServer(); + httpMock = httpServiceMock.createSetupContract(); }); test('fetches whether strict mode is enabled', async () => { - const collector = createCspCollector(kbnServer as any); + const collector = createCspCollector(httpMock); expect((await collector.fetch(mockCallCluster)).strict).toEqual(true); @@ -54,7 +43,7 @@ describe('csp collector', () => { }); test('fetches whether the legacy browser warning is enabled', async () => { - const collector = createCspCollector(kbnServer as any); + const collector = createCspCollector(httpMock); expect((await collector.fetch(mockCallCluster)).warnLegacyBrowsers).toEqual(true); @@ -63,7 +52,7 @@ describe('csp collector', () => { }); test('fetches whether the csp rules have been changed or not', async () => { - const collector = createCspCollector(kbnServer as any); + const collector = createCspCollector(httpMock); expect((await collector.fetch(mockCallCluster)).rulesChangedFromDefault).toEqual(false); @@ -72,7 +61,7 @@ describe('csp collector', () => { }); test('does not include raw csp rules under any property names', async () => { - const collector = createCspCollector(kbnServer as any); + const collector = createCspCollector(httpMock); // It's important that we do not send the value of csp.rules here as it // can be customized with values that can be identifiable to given diff --git a/src/legacy/core_plugins/kibana/server/lib/csp_usage_collector/csp_collector.ts b/src/plugins/kibana_usage_collection/server/collectors/csp/csp_collector.ts similarity index 75% rename from src/legacy/core_plugins/kibana/server/lib/csp_usage_collector/csp_collector.ts rename to src/plugins/kibana_usage_collection/server/collectors/csp/csp_collector.ts index 9c124a90e66eb..c45a83588ee44 100644 --- a/src/legacy/core_plugins/kibana/server/lib/csp_usage_collector/csp_collector.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/csp/csp_collector.ts @@ -17,12 +17,8 @@ * under the License. */ -import { Server } from 'hapi'; -import { CspConfig } from '../../../../../../core/server'; -import { - UsageCollectionSetup, - CollectorOptions, -} from '../../../../../../plugins/usage_collection/server'; +import { UsageCollectionSetup, CollectorOptions } from 'src/plugins/usage_collection/server'; +import { HttpServiceSetup, CspConfig } from '../../../../../core/server'; interface Usage { strict: boolean; @@ -30,12 +26,12 @@ interface Usage { rulesChangedFromDefault: boolean; } -export function createCspCollector(server: Server): CollectorOptions { +export function createCspCollector(http: HttpServiceSetup): CollectorOptions { return { type: 'csp', isReady: () => true, async fetch() { - const { strict, warnLegacyBrowsers, header } = server.newPlatform.setup.core.http.csp; + const { strict, warnLegacyBrowsers, header } = http.csp; return { strict, @@ -60,8 +56,11 @@ export function createCspCollector(server: Server): CollectorOptions { }; } -export function registerCspCollector(usageCollection: UsageCollectionSetup, server: Server): void { - const collectorConfig = createCspCollector(server); - const collector = usageCollection.makeUsageCollector(collectorConfig); +export function registerCspCollector( + usageCollection: UsageCollectionSetup, + http: HttpServiceSetup +): void { + const collectorOptions = createCspCollector(http); + const collector = usageCollection.makeUsageCollector(collectorOptions); usageCollection.registerCollector(collector); } diff --git a/src/legacy/core_plugins/kibana/server/lib/csp_usage_collector/index.ts b/src/plugins/kibana_usage_collection/server/collectors/csp/index.ts similarity index 100% rename from src/legacy/core_plugins/kibana/server/lib/csp_usage_collector/index.ts rename to src/plugins/kibana_usage_collection/server/collectors/csp/index.ts diff --git a/src/plugins/kibana_usage_collection/server/collectors/index.ts b/src/plugins/kibana_usage_collection/server/collectors/index.ts index 1ca237528b41f..1f9fe130fa45d 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/index.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/index.ts @@ -22,3 +22,4 @@ export { registerManagementUsageCollector } from './management'; export { registerApplicationUsageCollector } from './application_usage'; export { registerKibanaUsageCollector } from './kibana'; export { registerOpsStatsCollector } from './ops_stats'; +export { registerCspCollector } from './csp'; diff --git a/src/plugins/kibana_usage_collection/server/plugin.ts b/src/plugins/kibana_usage_collection/server/plugin.ts index 803a9146bd08f..d4295c770803e 100644 --- a/src/plugins/kibana_usage_collection/server/plugin.ts +++ b/src/plugins/kibana_usage_collection/server/plugin.ts @@ -37,6 +37,7 @@ import { registerManagementUsageCollector, registerOpsStatsCollector, registerUiMetricUsageCollector, + registerCspCollector, } from './collectors'; interface KibanaUsageCollectionPluginsDepsSetup { @@ -56,12 +57,9 @@ export class KibanaUsageCollectionPlugin implements Plugin { this.metric$ = new Subject(); } - public setup( - { savedObjects }: CoreSetup, - { usageCollection }: KibanaUsageCollectionPluginsDepsSetup - ) { - this.registerUsageCollectors(usageCollection, this.metric$, (opts) => - savedObjects.registerType(opts) + public setup(coreSetup: CoreSetup, { usageCollection }: KibanaUsageCollectionPluginsDepsSetup) { + this.registerUsageCollectors(usageCollection, coreSetup, this.metric$, (opts) => + coreSetup.savedObjects.registerType(opts) ); } @@ -79,6 +77,7 @@ export class KibanaUsageCollectionPlugin implements Plugin { private registerUsageCollectors( usageCollection: UsageCollectionSetup, + coreSetup: CoreSetup, metric$: Subject, registerType: SavedObjectsRegisterType ) { @@ -90,5 +89,6 @@ export class KibanaUsageCollectionPlugin implements Plugin { registerManagementUsageCollector(usageCollection, getUiSettingsClient); registerUiMetricUsageCollector(usageCollection, registerType, getSavedObjectsClient); registerApplicationUsageCollector(usageCollection, registerType, getSavedObjectsClient); + registerCspCollector(usageCollection, coreSetup.http); } } diff --git a/test/api_integration/apis/status/status.js b/test/api_integration/apis/status/status.js index c60d354090cc2..edfd4ca08b34d 100644 --- a/test/api_integration/apis/status/status.js +++ b/test/api_integration/apis/status/status.js @@ -39,10 +39,6 @@ export default function ({ getService }) { expect(body.status.overall.state).to.be('green'); expect(body.status.statuses).to.be.an('array'); - const kibanaPlugin = body.status.statuses.find((s) => { - return s.id.indexOf('plugin:kibana') === 0; - }); - expect(kibanaPlugin.state).to.be('green'); expect(body.metrics.collection_interval_in_millis).to.be.a('number'); diff --git a/test/functional/apps/status_page/index.ts b/test/functional/apps/status_page/index.ts index 65349aba93b9b..234e61a142a81 100644 --- a/test/functional/apps/status_page/index.ts +++ b/test/functional/apps/status_page/index.ts @@ -21,7 +21,6 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../ftr_provider_context'; export default function ({ getService, getPageObjects }: FtrProviderContext) { - const retry = getService('retry'); const testSubjects = getService('testSubjects'); const PageObjects = getPageObjects(['common']); @@ -32,13 +31,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.common.navigateToApp('status_page'); }); - it('should show the kibana plugin as ready', async () => { - await retry.tryForTime(6000, async () => { - const text = await testSubjects.getVisibleText('statusBreakdown'); - expect(text.indexOf('plugin:kibana')).to.be.above(-1); - }); - }); - it('should show the build hash and number', async () => { const buildNumberText = await testSubjects.getVisibleText('statusBuildNumber'); expect(buildNumberText).to.contain('BUILD '); From ee75e571ad6842d25eab5572f42e7ec0482b5a16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Fern=C3=A1ndez=20Haro?= Date: Fri, 21 Aug 2020 13:47:01 +0100 Subject: [PATCH 20/45] [Data Telemetry] Add index pattern to identify "meow" attacks (#75163) Co-authored-by: Elastic Machine --- .../telemetry_collection/get_data_telemetry/constants.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/constants.ts b/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/constants.ts index 2d0864b1cb75f..7e4176281db41 100644 --- a/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/constants.ts +++ b/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/constants.ts @@ -128,6 +128,9 @@ export const DATA_DATASETS_INDEX_PATTERNS = [ { pattern: '*suricata*', patternName: 'suricata' }, // { pattern: '*fsf*', patternName: 'fsf' }, // Disabled because it's too vague { pattern: '*wazuh*', patternName: 'wazuh' }, + + // meow attacks + { pattern: '*meow*', patternName: 'meow' }, ] as const; // Get the unique list of index patterns (some are duplicated for documentation purposes) From da0da4ca752f01428e126964039b0ac867580c21 Mon Sep 17 00:00:00 2001 From: Robert Austin Date: Fri, 21 Aug 2020 09:43:42 -0400 Subject: [PATCH 21/45] [Security Solution] modify circular deps checker to output images of circular deps graphs (#75579) --- .../run_check_circular_deps_cli.js | 45 ++++++++++++++++--- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/security_solution/scripts/check_circular_deps/run_check_circular_deps_cli.js b/x-pack/plugins/security_solution/scripts/check_circular_deps/run_check_circular_deps_cli.js index 9b4a57f09066d..ac4102184091d 100644 --- a/x-pack/plugins/security_solution/scripts/check_circular_deps/run_check_circular_deps_cli.js +++ b/x-pack/plugins/security_solution/scripts/check_circular_deps/run_check_circular_deps_cli.js @@ -4,17 +4,17 @@ * you may not use this file except in compliance with the Elastic License. */ -import { resolve } from 'path'; - /* eslint-disable-next-line import/no-extraneous-dependencies */ import madge from 'madge'; /* eslint-disable-next-line import/no-extraneous-dependencies */ import { run, createFailError } from '@kbn/dev-utils'; +import * as os from 'os'; +import * as path from 'path'; run( - async ({ log }) => { + async ({ log, flags }) => { const result = await madge( - [resolve(__dirname, '../../public'), resolve(__dirname, '../../common')], + [path.resolve(__dirname, '../../public'), path.resolve(__dirname, '../../common')], { fileExtensions: ['ts', 'js', 'tsx'], excludeRegExp: [ @@ -34,6 +34,13 @@ run( const circularFound = result.circular(); if (circularFound.length !== 0) { + if (flags.svg) { + await outputSVGs(circularFound); + } else { + console.log( + 'Run this program with the --svg flag to save an SVG showing the dependency graph.' + ); + } throw createFailError( `SIEM circular dependencies of imports has been found:\n - ${circularFound.join('\n - ')}` ); @@ -42,6 +49,34 @@ run( } }, { - description: 'Check the SIEM plugin for circular deps', + description: + 'Check the Security Solution plugin for circular deps. If any are found, this will throw an Error.', + flags: { + help: ' --svg, Output SVGs of circular dependency graphs', + boolean: ['svg'], + default: { + svg: false, + }, + }, } ); + +async function outputSVGs(circularFound) { + let count = 0; + for (const found of circularFound) { + // Calculate the path using the os tmpdir and an increasing 'count' + const expectedImagePath = path.join(os.tmpdir(), `security_solution-circular-dep-${count}.svg`); + console.log(`Attempting to save SVG for circular dependency: ${found}`); + count++; + + // Graph just the files in the found circular dependency. + const specificGraph = await madge(found, { + fileExtensions: ['ts', 'js', 'tsx'], + }); + + // Output an SVG in the tmp directory + const imagePath = await specificGraph.image(expectedImagePath); + + console.log(`Saved SVG: ${imagePath}`); + } +} From c68363995b5fc0ce6820c5cdd92ab0d8d6d29d58 Mon Sep 17 00:00:00 2001 From: Aleh Zasypkin Date: Fri, 21 Aug 2020 16:15:12 +0200 Subject: [PATCH 22/45] Improve login UI error message. (#75642) --- .../components/login_form/login_form.test.tsx | 49 +++++++++++++++++++ .../components/login_form/login_form.tsx | 14 ++++-- 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/security/public/authentication/login/components/login_form/login_form.test.tsx b/x-pack/plugins/security/public/authentication/login/components/login_form/login_form.test.tsx index 552d523fa4a84..b6dd06595ae7f 100644 --- a/x-pack/plugins/security/public/authentication/login/components/login_form/login_form.test.tsx +++ b/x-pack/plugins/security/public/authentication/login/components/login_form/login_form.test.tsx @@ -421,9 +421,58 @@ describe('LoginForm', () => { expect(window.location.href).toBe(currentURL); expect(coreStartMock.notifications.toasts.addError).toHaveBeenCalledWith(failureReason, { title: 'Could not perform login.', + toastMessage: 'Oh no!', }); }); + it('shows error with message in the `body`', async () => { + const currentURL = `https://some-host/login?next=${encodeURIComponent( + '/some-base-path/app/kibana#/home?_g=()' + )}`; + + const coreStartMock = coreMock.createStart({ basePath: '/some-base-path' }); + coreStartMock.http.post.mockRejectedValue({ + body: { message: 'Oh no! But with much more details!' }, + message: 'Oh no!', + }); + + window.location.href = currentURL; + const wrapper = mountWithIntl( + + ); + + expectPageMode(wrapper, PageMode.Selector); + + wrapper.findWhere((node) => node.key() === 'saml1').simulate('click'); + + await act(async () => { + await nextTick(); + wrapper.update(); + }); + + expect(coreStartMock.http.post).toHaveBeenCalledTimes(1); + expect(coreStartMock.http.post).toHaveBeenCalledWith('/internal/security/login', { + body: JSON.stringify({ providerType: 'saml', providerName: 'saml1', currentURL }), + }); + + expect(window.location.href).toBe(currentURL); + expect(coreStartMock.notifications.toasts.addError).toHaveBeenCalledWith( + new Error('Oh no! But with much more details!'), + { title: 'Could not perform login.', toastMessage: 'Oh no!' } + ); + }); + it('properly switches to login form', async () => { const currentURL = `https://some-host/login?next=${encodeURIComponent( '/some-base-path/app/kibana#/home?_g=()' diff --git a/x-pack/plugins/security/public/authentication/login/components/login_form/login_form.tsx b/x-pack/plugins/security/public/authentication/login/components/login_form/login_form.tsx index 9ea553af75e00..a929b50fa1ffa 100644 --- a/x-pack/plugins/security/public/authentication/login/components/login_form/login_form.tsx +++ b/x-pack/plugins/security/public/authentication/login/components/login_form/login_form.tsx @@ -451,11 +451,15 @@ export class LoginForm extends Component { window.location.href = location; } catch (err) { - this.props.notifications.toasts.addError(err, { - title: i18n.translate('xpack.security.loginPage.loginSelectorErrorMessage', { - defaultMessage: 'Could not perform login.', - }), - }); + this.props.notifications.toasts.addError( + err?.body?.message ? new Error(err?.body?.message) : err, + { + title: i18n.translate('xpack.security.loginPage.loginSelectorErrorMessage', { + defaultMessage: 'Could not perform login.', + }), + toastMessage: err?.message, + } + ); this.setState({ loadingState: { type: LoadingStateType.None } }); } From 6b3ce3f91ee53c9050401af1edb80bd8793cf1c4 Mon Sep 17 00:00:00 2001 From: Devon Thomson Date: Fri, 21 Aug 2020 10:18:14 -0400 Subject: [PATCH 23/45] [Dashboard First] Lens Originating App Breadcrumb (#75470) Changed lens breadcrumbs to reflect the Originating App --- .../lens/public/app_plugin/app.test.tsx | 34 +++++++++++++++++++ x-pack/plugins/lens/public/app_plugin/app.tsx | 21 +++++++++++- 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/lens/public/app_plugin/app.test.tsx b/x-pack/plugins/lens/public/app_plugin/app.test.tsx index f92343183a700..70136a486e8c1 100644 --- a/x-pack/plugins/lens/public/app_plugin/app.test.tsx +++ b/x-pack/plugins/lens/public/app_plugin/app.test.tsx @@ -136,6 +136,7 @@ describe('Lens App', () => { originatingApp: string | undefined; onAppLeave: AppMountParameters['onAppLeave']; history: History; + getAppNameFromId?: (appId: string) => string | undefined; }> { return ({ navigation: navigationStartMock, @@ -187,6 +188,7 @@ describe('Lens App', () => { originatingApp: string | undefined; onAppLeave: AppMountParameters['onAppLeave']; history: History; + getAppNameFromId?: (appId: string) => string | undefined; }>; } @@ -298,6 +300,38 @@ describe('Lens App', () => { ]); }); + it('sets originatingApp breadcrumb when the document title changes', async () => { + const defaultArgs = makeDefaultArgs(); + defaultArgs.originatingApp = 'ultraCoolDashboard'; + defaultArgs.getAppNameFromId = () => 'The Coolest Container Ever Made'; + instance = mount(); + + expect(core.chrome.setBreadcrumbs).toHaveBeenCalledWith([ + { text: 'The Coolest Container Ever Made', onClick: expect.anything() }, + { text: 'Visualize', href: '/testbasepath/app/visualize#/', onClick: expect.anything() }, + { text: 'Create' }, + ]); + + (defaultArgs.docStorage.load as jest.Mock).mockResolvedValue({ + id: '1234', + title: 'Daaaaaaadaumching!', + expression: 'valid expression', + state: { + query: 'fake query', + datasourceMetaData: { filterableIndexPatterns: [{ id: '1', title: 'saved' }] }, + }, + }); + await act(async () => { + instance.setProps({ docId: '1234' }); + }); + + expect(defaultArgs.core.chrome.setBreadcrumbs).toHaveBeenCalledWith([ + { text: 'The Coolest Container Ever Made', onClick: expect.anything() }, + { text: 'Visualize', href: '/testbasepath/app/visualize#/', onClick: expect.anything() }, + { text: 'Daaaaaaadaumching!' }, + ]); + }); + describe('persistence', () => { it('does not load a document if there is no document id', () => { const args = makeDefaultArgs(); diff --git a/x-pack/plugins/lens/public/app_plugin/app.tsx b/x-pack/plugins/lens/public/app_plugin/app.tsx index b20fe2f804683..5ca6f27a0c578 100644 --- a/x-pack/plugins/lens/public/app_plugin/app.tsx +++ b/x-pack/plugins/lens/public/app_plugin/app.tsx @@ -11,6 +11,7 @@ import { i18n } from '@kbn/i18n'; import { NavigationPublicPluginStart } from 'src/plugins/navigation/public'; import { AppMountContext, AppMountParameters, NotificationsStart } from 'kibana/public'; import { History } from 'history'; +import { EuiBreadcrumb } from '@elastic/eui'; import { Query, DataPublicPluginStart, @@ -203,6 +204,16 @@ export function App({ // Sync Kibana breadcrumbs any time the saved document's title changes useEffect(() => { core.chrome.setBreadcrumbs([ + ...(originatingApp && getAppNameFromId + ? [ + { + onClick: (e) => { + core.application.navigateToApp(originatingApp); + }, + text: getAppNameFromId(originatingApp), + } as EuiBreadcrumb, + ] + : []), { href: core.http.basePath.prepend(`/app/visualize#/`), onClick: (e) => { @@ -219,7 +230,15 @@ export function App({ : i18n.translate('xpack.lens.breadcrumbsCreate', { defaultMessage: 'Create' }), }, ]); - }, [core.application, core.chrome, core.http.basePath, state.persistedDoc]); + }, [ + core.application, + core.chrome, + core.http.basePath, + state.persistedDoc, + originatingApp, + redirectTo, + getAppNameFromId, + ]); useEffect( () => { From 338b61ce6c1643af23b42e9a130085b0a55e8e80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Fern=C3=A1ndez=20Haro?= Date: Fri, 21 Aug 2020 15:23:39 +0100 Subject: [PATCH 24/45] [Usage Collection Schemas] Remove Legacy entries (#75652) --- .telemetryrc.json | 9 --------- .../telemetry/schema/legacy_oss_plugins.json | 17 ----------------- 2 files changed, 26 deletions(-) delete mode 100644 src/plugins/telemetry/schema/legacy_oss_plugins.json diff --git a/.telemetryrc.json b/.telemetryrc.json index 30643a104c1cd..2f57566159a70 100644 --- a/.telemetryrc.json +++ b/.telemetryrc.json @@ -1,13 +1,4 @@ [ - { - "output": "src/plugins/telemetry/schema/legacy_oss_plugins.json", - "root": "src/legacy/core_plugins/", - "exclude": [ - "src/legacy/core_plugins/testbed", - "src/legacy/core_plugins/elasticsearch", - "src/legacy/core_plugins/tests_bundle" - ] - }, { "output": "src/plugins/telemetry/schema/oss_plugins.json", "root": "src/plugins/", diff --git a/src/plugins/telemetry/schema/legacy_oss_plugins.json b/src/plugins/telemetry/schema/legacy_oss_plugins.json deleted file mode 100644 index e660ccac9dc36..0000000000000 --- a/src/plugins/telemetry/schema/legacy_oss_plugins.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "properties": { - "csp": { - "properties": { - "strict": { - "type": "boolean" - }, - "warnLegacyBrowsers": { - "type": "boolean" - }, - "rulesChangedFromDefault": { - "type": "boolean" - } - } - } - } -} From 172c464b147bb207b71530fe9c82170ba5d3893f Mon Sep 17 00:00:00 2001 From: Constance Date: Fri, 21 Aug 2020 09:02:15 -0700 Subject: [PATCH 25/45] [Enterprise Search] Convert our `public_url` route to `config_data` and collect initialAppData (#75616) * [Setup] DRY out stripTrailingSlash helper - DRYs out repeated code - This will be used by an upcoming server/ endpoint change, hence why it's in common * [Setup] DRY out initial app data types to common/types - In preparation for upcoming server logic that will need to reuse these types + DRY out and clean up workplace_search types - remove unused supportEligible - remove currentUser - unneeded in Kibana * Update callEnterpriseSearchConfigAPI to parse and fetch new expected data * Remove /public_url API for /config_data * Remove getPublicUrl in favor of directly calling the new /config_data API from public/plugin + set returned initialData in this.data * Set up product apps to be passed initial data as props * Fix for Kea/redux state not resetting between AS<->WS nav - resetContext at the top level only gets called once total on first plugin load and never after, causing navigating between WS and AS to crash when both have Kea - this fixes the issue - moves redux Provider to top level app as well * Add very basic Kea logic file to App Search * Finish AppSearchConfigured tests & set up kea+useEffect mocks * [Cleanup] DRY out repeated mock initialAppData to a reusable defaults constant --- .../common/__mocks__/index.ts | 7 ++ .../common/__mocks__/initial_app_data.ts | 45 +++++++++ .../common/strip_trailing_slash/index.test.ts | 17 ++++ .../common/strip_trailing_slash/index.ts | 13 +++ .../common/types/app_search.ts | 25 +++++ .../enterprise_search/common/types/index.ts | 24 +++++ .../common/types/workplace_search.ts | 19 ++++ .../public/applications/__mocks__/kea.mock.ts | 24 +++++ .../__mocks__/shallow_usecontext.mock.ts | 1 + .../applications/app_search/app_logic.test.ts | 35 +++++++ .../applications/app_search/app_logic.ts | 31 ++++++ .../applications/app_search/index.test.tsx | 53 ++++++++-- .../public/applications/app_search/index.tsx | 41 +++++--- .../public/applications/index.tsx | 27 ++++-- .../get_enterprise_search_url.test.ts | 30 ------ .../get_enterprise_search_url.ts | 27 ------ .../shared/enterprise_search_url/index.ts | 1 - .../applications/shared/layout/side_nav.tsx | 3 +- .../overview/__mocks__/overview_logic.mock.ts | 3 +- .../overview/onboarding_steps.test.tsx | 1 - .../overview/overview_logic.test.ts | 9 +- .../components/overview/overview_logic.ts | 9 +- .../applications/workplace_search/index.tsx | 48 ++++------ .../applications/workplace_search/types.ts | 20 +--- .../enterprise_search/public/plugin.ts | 21 ++-- .../lib/enterprise_search_config_api.test.ts | 96 ++++++++++++++++++- .../lib/enterprise_search_config_api.ts | 53 +++++++++- .../enterprise_search/server/plugin.ts | 4 +- ...public_url.test.ts => config_data.test.ts} | 39 +++++--- .../routes/enterprise_search/config_data.ts | 32 +++++++ .../routes/enterprise_search/public_url.ts | 26 ----- 31 files changed, 573 insertions(+), 211 deletions(-) create mode 100644 x-pack/plugins/enterprise_search/common/__mocks__/index.ts create mode 100644 x-pack/plugins/enterprise_search/common/__mocks__/initial_app_data.ts create mode 100644 x-pack/plugins/enterprise_search/common/strip_trailing_slash/index.test.ts create mode 100644 x-pack/plugins/enterprise_search/common/strip_trailing_slash/index.ts create mode 100644 x-pack/plugins/enterprise_search/common/types/app_search.ts create mode 100644 x-pack/plugins/enterprise_search/common/types/index.ts create mode 100644 x-pack/plugins/enterprise_search/common/types/workplace_search.ts create mode 100644 x-pack/plugins/enterprise_search/public/applications/__mocks__/kea.mock.ts create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/app_logic.test.ts create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/app_logic.ts delete mode 100644 x-pack/plugins/enterprise_search/public/applications/shared/enterprise_search_url/get_enterprise_search_url.test.ts delete mode 100644 x-pack/plugins/enterprise_search/public/applications/shared/enterprise_search_url/get_enterprise_search_url.ts rename x-pack/plugins/enterprise_search/server/routes/enterprise_search/{public_url.test.ts => config_data.test.ts} (50%) create mode 100644 x-pack/plugins/enterprise_search/server/routes/enterprise_search/config_data.ts delete mode 100644 x-pack/plugins/enterprise_search/server/routes/enterprise_search/public_url.ts diff --git a/x-pack/plugins/enterprise_search/common/__mocks__/index.ts b/x-pack/plugins/enterprise_search/common/__mocks__/index.ts new file mode 100644 index 0000000000000..57029913fe3a9 --- /dev/null +++ b/x-pack/plugins/enterprise_search/common/__mocks__/index.ts @@ -0,0 +1,7 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export * from './initial_app_data'; diff --git a/x-pack/plugins/enterprise_search/common/__mocks__/initial_app_data.ts b/x-pack/plugins/enterprise_search/common/__mocks__/initial_app_data.ts new file mode 100644 index 0000000000000..79e1efc425b4e --- /dev/null +++ b/x-pack/plugins/enterprise_search/common/__mocks__/initial_app_data.ts @@ -0,0 +1,45 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export const DEFAULT_INITIAL_APP_DATA = { + readOnlyMode: false, + ilmEnabled: true, + configuredLimits: { + maxDocumentByteSize: 102400, + maxEnginesPerMetaEngine: 15, + }, + appSearch: { + accountId: 'some-id-string', + onBoardingComplete: true, + role: { + id: 'account_id:somestring|user_oid:somestring', + roleType: 'owner', + ability: { + accessAllEngines: true, + destroy: ['session'], + manage: ['account_credentials', 'account_engines'], // etc + edit: ['LocoMoco::Account'], // etc + view: ['Engine'], // etc + credentialTypes: ['admin', 'private', 'search'], + availableRoleTypes: ['owner', 'admin'], + }, + }, + }, + workplaceSearch: { + organization: { + name: 'ACME Donuts', + defaultOrgName: 'My Organization', + }, + fpAccount: { + id: 'some-id-string', + groups: ['Default', 'Cats'], + isAdmin: true, + canCreatePersonalSources: true, + isCurated: false, + viewedOnboardingPage: true, + }, + }, +}; diff --git a/x-pack/plugins/enterprise_search/common/strip_trailing_slash/index.test.ts b/x-pack/plugins/enterprise_search/common/strip_trailing_slash/index.test.ts new file mode 100644 index 0000000000000..b5d64455b1a90 --- /dev/null +++ b/x-pack/plugins/enterprise_search/common/strip_trailing_slash/index.test.ts @@ -0,0 +1,17 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { stripTrailingSlash } from './'; + +describe('Strip Trailing Slash helper', () => { + it('strips trailing slashes', async () => { + expect(stripTrailingSlash('http://trailing.slash/')).toEqual('http://trailing.slash'); + }); + + it('does nothing is there is no trailing slash', async () => { + expect(stripTrailingSlash('http://ok.url')).toEqual('http://ok.url'); + }); +}); diff --git a/x-pack/plugins/enterprise_search/common/strip_trailing_slash/index.ts b/x-pack/plugins/enterprise_search/common/strip_trailing_slash/index.ts new file mode 100644 index 0000000000000..ade9bd8742c97 --- /dev/null +++ b/x-pack/plugins/enterprise_search/common/strip_trailing_slash/index.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +/** + * Small helper for stripping trailing slashes from URLs or paths + * (usually ones that come in from React Router or API endpoints) + */ +export const stripTrailingSlash = (url: string): string => { + return url && url.endsWith('/') ? url.slice(0, -1) : url; +}; diff --git a/x-pack/plugins/enterprise_search/common/types/app_search.ts b/x-pack/plugins/enterprise_search/common/types/app_search.ts new file mode 100644 index 0000000000000..5d6ec079e66e0 --- /dev/null +++ b/x-pack/plugins/enterprise_search/common/types/app_search.ts @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export interface IAccount { + accountId: string; + onBoardingComplete: boolean; + role: IRole; +} + +export interface IRole { + id: string; + roleType: string; + ability: { + accessAllEngines: boolean; + destroy: string[]; + manage: string[]; + edit: string[]; + view: string[]; + credentialTypes: string[]; + availableRoleTypes: string[]; + }; +} diff --git a/x-pack/plugins/enterprise_search/common/types/index.ts b/x-pack/plugins/enterprise_search/common/types/index.ts new file mode 100644 index 0000000000000..52e468b741a07 --- /dev/null +++ b/x-pack/plugins/enterprise_search/common/types/index.ts @@ -0,0 +1,24 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { IAccount as IAppSearchAccount } from './app_search'; +import { IAccount as IWorkplaceSearchAccount, IOrganization } from './workplace_search'; + +export interface IInitialAppData { + readOnlyMode?: boolean; + ilmEnabled?: boolean; + configuredLimits?: IConfiguredLimits; + appSearch?: IAppSearchAccount; + workplaceSearch?: { + organization: IOrganization; + fpAccount: IWorkplaceSearchAccount; + }; +} + +export interface IConfiguredLimits { + maxDocumentByteSize: number; + maxEnginesPerMetaEngine: number; +} diff --git a/x-pack/plugins/enterprise_search/common/types/workplace_search.ts b/x-pack/plugins/enterprise_search/common/types/workplace_search.ts new file mode 100644 index 0000000000000..fd8fa6daf81ac --- /dev/null +++ b/x-pack/plugins/enterprise_search/common/types/workplace_search.ts @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export interface IAccount { + id: string; + groups: string[]; + isAdmin: boolean; + isCurated: boolean; + canCreatePersonalSources: boolean; + viewedOnboardingPage: boolean; +} + +export interface IOrganization { + name: string; + defaultOrgName: string; +} diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/kea.mock.ts b/x-pack/plugins/enterprise_search/public/applications/__mocks__/kea.mock.ts new file mode 100644 index 0000000000000..5049e9da21ce9 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/__mocks__/kea.mock.ts @@ -0,0 +1,24 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +jest.mock('kea', () => ({ + ...(jest.requireActual('kea') as object), + useValues: jest.fn(() => ({})), + useActions: jest.fn(() => ({})), +})); + +/** + * Example usage within a component test: + * + * import '../../../__mocks__/kea'; // Must come before kea's import, adjust relative path as needed + * + * import { useActions, useValues } from 'kea'; + * + * it('some test', () => { + * (useValues as jest.Mock).mockImplementationOnce(() => ({ someValue: 'hello' })); + * (useActions as jest.Mock).mockImplementationOnce(() => ({ someAction: () => 'world' })); + * }); + */ diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/shallow_usecontext.mock.ts b/x-pack/plugins/enterprise_search/public/applications/__mocks__/shallow_usecontext.mock.ts index 792be49a49c48..3a2193db646de 100644 --- a/x-pack/plugins/enterprise_search/public/applications/__mocks__/shallow_usecontext.mock.ts +++ b/x-pack/plugins/enterprise_search/public/applications/__mocks__/shallow_usecontext.mock.ts @@ -14,6 +14,7 @@ import { mockLicenseContext } from './license_context.mock'; jest.mock('react', () => ({ ...(jest.requireActual('react') as object), useContext: jest.fn(() => ({ ...mockKibanaContext, ...mockLicenseContext })), + useEffect: jest.fn((fn) => fn()), // Calls on mount/every update - use mount for more complex behavior })); /** diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/app_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/app_logic.test.ts new file mode 100644 index 0000000000000..bc31b7df5d971 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/app_logic.test.ts @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { resetContext } from 'kea'; + +import { DEFAULT_INITIAL_APP_DATA } from '../../../common/__mocks__'; +import { AppLogic } from './app_logic'; + +describe('AppLogic', () => { + beforeEach(() => { + resetContext({}); + AppLogic.mount(); + }); + + const DEFAULT_VALUES = { + hasInitialized: false, + }; + + it('has expected default values', () => { + expect(AppLogic.values).toEqual(DEFAULT_VALUES); + }); + + describe('initializeAppData()', () => { + it('sets values based on passed props', () => { + AppLogic.actions.initializeAppData(DEFAULT_INITIAL_APP_DATA); + + expect(AppLogic.values).toEqual({ + hasInitialized: true, + }); + }); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/app_logic.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/app_logic.ts new file mode 100644 index 0000000000000..0fb3bb8080d82 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/app_logic.ts @@ -0,0 +1,31 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { kea } from 'kea'; + +import { IInitialAppData } from '../../../common/types'; +import { IKeaLogic } from '../shared/types'; + +export interface IAppLogicValues { + hasInitialized: boolean; +} +export interface IAppLogicActions { + initializeAppData(props: IInitialAppData): void; +} + +export const AppLogic = kea({ + actions: (): IAppLogicActions => ({ + initializeAppData: (props) => props, + }), + reducers: () => ({ + hasInitialized: [ + false, + { + initializeAppData: () => true, + }, + ], + }), +}) as IKeaLogic; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx index fa9a761a966e1..0f4072c591bc7 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx @@ -5,27 +5,68 @@ */ import '../__mocks__/shallow_usecontext.mock'; +import '../__mocks__/kea.mock'; import React, { useContext } from 'react'; import { Redirect } from 'react-router-dom'; import { shallow } from 'enzyme'; +import { useValues, useActions } from 'kea'; +import { SetupGuide } from './components/setup_guide'; import { Layout, SideNav, SideNavLink } from '../shared/layout'; -import { AppSearch, AppSearchNav } from './'; +import { AppSearch, AppSearchUnconfigured, AppSearchConfigured, AppSearchNav } from './'; describe('AppSearch', () => { - it('renders', () => { + it('renders AppSearchUnconfigured when config.host is not set', () => { + (useContext as jest.Mock).mockImplementationOnce(() => ({ config: { host: '' } })); const wrapper = shallow(); - expect(wrapper.find(Layout)).toHaveLength(1); + expect(wrapper.find(AppSearchUnconfigured)).toHaveLength(1); }); - it('redirects to Setup Guide when config.host is not set', () => { - (useContext as jest.Mock).mockImplementationOnce(() => ({ config: { host: '' } })); + it('renders AppSearchConfigured when config.host set', () => { + (useContext as jest.Mock).mockImplementationOnce(() => ({ config: { host: 'some.url' } })); const wrapper = shallow(); + expect(wrapper.find(AppSearchConfigured)).toHaveLength(1); + }); +}); + +describe('AppSearchUnconfigured', () => { + it('renders the Setup Guide and redirects to the Setup Guide', () => { + const wrapper = shallow(); + + expect(wrapper.find(SetupGuide)).toHaveLength(1); expect(wrapper.find(Redirect)).toHaveLength(1); - expect(wrapper.find(Layout)).toHaveLength(0); + }); +}); + +describe('AppSearchConfigured', () => { + it('renders with layout', () => { + (useActions as jest.Mock).mockImplementation(() => ({ initializeAppData: () => {} })); + + const wrapper = shallow(); + + expect(wrapper.find(Layout)).toHaveLength(1); + }); + + it('initializes app data with passed props', () => { + const initializeAppData = jest.fn(); + (useActions as jest.Mock).mockImplementation(() => ({ initializeAppData })); + + shallow(); + + expect(initializeAppData).toHaveBeenCalledWith({ readOnlyMode: true }); + }); + + it('does not re-initialize app data', () => { + const initializeAppData = jest.fn(); + (useActions as jest.Mock).mockImplementation(() => ({ initializeAppData })); + (useValues as jest.Mock).mockImplementationOnce(() => ({ hasInitialized: true })); + + shallow(); + + expect(initializeAppData).not.toHaveBeenCalled(); }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx index 5856a13bf75b7..5f4734630624c 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx @@ -4,13 +4,17 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { useContext } from 'react'; +import React, { useContext, useEffect } from 'react'; import { Route, Redirect, Switch } from 'react-router-dom'; +import { useActions, useValues } from 'kea'; import { i18n } from '@kbn/i18n'; -import { APP_SEARCH_PLUGIN } from '../../../common/constants'; import { KibanaContext, IKibanaContext } from '../index'; +import { AppLogic, IAppLogicActions, IAppLogicValues } from './app_logic'; +import { IInitialAppData } from '../../../common/types'; + +import { APP_SEARCH_PLUGIN } from '../../../common/constants'; import { Layout, SideNav, SideNavLink } from '../shared/layout'; import { @@ -25,20 +29,29 @@ import { import { SetupGuide } from './components/setup_guide'; import { EngineOverview } from './components/engine_overview'; -export const AppSearch: React.FC = () => { +export const AppSearch: React.FC = (props) => { const { config } = useContext(KibanaContext) as IKibanaContext; + return !config.host ? : ; +}; + +export const AppSearchUnconfigured: React.FC = () => ( + + + + + + + + +); + +export const AppSearchConfigured: React.FC = (props) => { + const { hasInitialized } = useValues(AppLogic) as IAppLogicValues; + const { initializeAppData } = useActions(AppLogic) as IAppLogicActions; - if (!config.host) - return ( - - - - - - - - - ); + useEffect(() => { + if (!hasInitialized) initializeAppData(props); + }, [hasInitialized]); return ( diff --git a/x-pack/plugins/enterprise_search/public/applications/index.tsx b/x-pack/plugins/enterprise_search/public/applications/index.tsx index 1b1f9ae43e7c1..d6cc6e81509b2 100644 --- a/x-pack/plugins/enterprise_search/public/applications/index.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/index.tsx @@ -8,6 +8,10 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { Router } from 'react-router-dom'; +import { Provider } from 'react-redux'; +import { Store } from 'redux'; +import { getContext, resetContext } from 'kea'; + import { I18nProvider } from '@kbn/i18n/react'; import { AppMountParameters, @@ -19,6 +23,7 @@ import { import { ClientConfigType, ClientData, PluginsSetup } from '../plugin'; import { LicenseProvider } from './shared/licensing'; import { IExternalUrl } from './shared/enterprise_search_url'; +import { IInitialAppData } from '../../common/types'; export interface IKibanaContext { config: { host?: string }; @@ -38,33 +43,41 @@ export const KibanaContext = React.createContext({}); */ export const renderApp = ( - App: React.FC, + App: React.FC, params: AppMountParameters, core: CoreStart, plugins: PluginsSetup, config: ClientConfigType, - data: ClientData + { externalUrl, ...initialData }: ClientData ) => { + resetContext({ createStore: true }); + const store = getContext().store as Store; + ReactDOM.render( - - - + + + + + , params.element ); - return () => ReactDOM.unmountComponentAtNode(params.element); + return () => { + resetContext({}); + ReactDOM.unmountComponentAtNode(params.element); + }; }; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/enterprise_search_url/get_enterprise_search_url.test.ts b/x-pack/plugins/enterprise_search/public/applications/shared/enterprise_search_url/get_enterprise_search_url.test.ts deleted file mode 100644 index 42f308c554268..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/shared/enterprise_search_url/get_enterprise_search_url.test.ts +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { getPublicUrl } from './'; - -describe('Enterprise Search URL helper', () => { - const httpMock = { get: jest.fn() } as any; - - it('calls and returns the public URL API endpoint', async () => { - httpMock.get.mockImplementationOnce(() => ({ publicUrl: 'http://some.vanity.url' })); - - expect(await getPublicUrl(httpMock)).toEqual('http://some.vanity.url'); - }); - - it('strips trailing slashes', async () => { - httpMock.get.mockImplementationOnce(() => ({ publicUrl: 'http://trailing.slash/' })); - - expect(await getPublicUrl(httpMock)).toEqual('http://trailing.slash'); - }); - - // For the most part, error logging/handling is done on the server side. - // On the front-end, we should simply gracefully fall back to config.host - // if we can't fetch a public URL - it('falls back to an empty string', async () => { - expect(await getPublicUrl(httpMock)).toEqual(''); - }); -}); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/enterprise_search_url/get_enterprise_search_url.ts b/x-pack/plugins/enterprise_search/public/applications/shared/enterprise_search_url/get_enterprise_search_url.ts deleted file mode 100644 index 419c187a0048a..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/shared/enterprise_search_url/get_enterprise_search_url.ts +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { HttpSetup } from 'src/core/public'; - -/** - * On Elastic Cloud, the host URL set in kibana.yml is not necessarily the same - * URL we want to send users to in the front-end (e.g. if a vanity URL is set). - * - * This helper checks a Kibana API endpoint (which has checks an Enterprise - * Search internal API endpoint) for the correct public-facing URL to use. - */ -export const getPublicUrl = async (http: HttpSetup): Promise => { - try { - const { publicUrl } = await http.get('/api/enterprise_search/public_url'); - return stripTrailingSlash(publicUrl); - } catch { - return ''; - } -}; - -const stripTrailingSlash = (url: string): string => { - return url.endsWith('/') ? url.slice(0, -1) : url; -}; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/enterprise_search_url/index.ts b/x-pack/plugins/enterprise_search/public/applications/shared/enterprise_search_url/index.ts index 563d19f9fdeb5..d2d82a43c6dd9 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/enterprise_search_url/index.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/enterprise_search_url/index.ts @@ -4,5 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -export { getPublicUrl } from './get_enterprise_search_url'; export { ExternalUrl, IExternalUrl } from './generate_external_url'; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/layout/side_nav.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/layout/side_nav.tsx index 5969fa7806a44..72e4f2f091496 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/layout/side_nav.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/layout/side_nav.tsx @@ -13,6 +13,7 @@ import { EuiIcon, EuiTitle, EuiText, EuiLink as EuiLinkExternal } from '@elastic import { EuiLink } from '../react_router_helpers'; import { ENTERPRISE_SEARCH_PLUGIN } from '../../../../common/constants'; +import { stripTrailingSlash } from '../../../../common/strip_trailing_slash'; import { NavContext, INavContext } from './layout'; @@ -78,7 +79,7 @@ export const SideNavLink: React.FC = ({ const { closeNavigation } = useContext(NavContext) as INavContext; const { pathname } = useLocation(); - const currentPath = pathname.endsWith('/') ? pathname.slice(0, -1) : pathname; + const currentPath = stripTrailingSlash(pathname); const isActive = currentPath === to || (isRoot && currentPath === ''); const classes = classNames('enterpriseSearchNavLinks__item', className, { diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/__mocks__/overview_logic.mock.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/__mocks__/overview_logic.mock.ts index 43cff5de6668d..395d2044e7dbc 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/__mocks__/overview_logic.mock.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/__mocks__/overview_logic.mock.ts @@ -5,14 +5,13 @@ */ import { IOverviewValues } from '../overview_logic'; -import { IAccount, IOrganization, IUser } from '../../../types'; +import { IAccount, IOrganization } from '../../../types'; export const mockLogicValues = { accountsCount: 0, activityFeed: [], canCreateContentSources: false, canCreateInvitations: false, - currentUser: {} as IUser, fpAccount: {} as IAccount, hasOrgSources: false, hasUsers: false, diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/onboarding_steps.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/onboarding_steps.test.tsx index 3cf88cf120cc4..acbc66259c2a1 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/onboarding_steps.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/onboarding_steps.test.tsx @@ -24,7 +24,6 @@ const account = { isAdmin: true, canCreatePersonalSources: true, groups: [], - supportEligible: true, isCurated: false, }; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/overview_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/overview_logic.test.ts index 285ec9b973378..7df4de4719f31 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/overview_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/overview_logic.test.ts @@ -31,14 +31,13 @@ describe('OverviewLogic', () => { describe('setServerData', () => { const feed = [{ foo: 'bar' }] as any; - const user = { firstName: 'Joe', email: 'e@e.e', name: 'Joe Jo', color: 'pearl' }; const account = { - name: 'Jane doe', id: '1243', + groups: ['Default'], isAdmin: true, + isCurated: false, canCreatePersonalSources: true, - groups: [], - supportEligible: true, + viewedOnboardingPage: false, }; const org = { name: 'ACME', defaultOrgName: 'Org' }; @@ -47,7 +46,6 @@ describe('OverviewLogic', () => { activityFeed: feed, canCreateContentSources: true, canCreateInvitations: true, - currentUser: user, fpAccount: account, hasOrgSources: true, hasUsers: true, @@ -70,7 +68,6 @@ describe('OverviewLogic', () => { it('will set server values', () => { expect(OverviewLogic.values.organization).toEqual(org); expect(OverviewLogic.values.isFederatedAuth).toEqual(false); - expect(OverviewLogic.values.currentUser).toEqual(user); expect(OverviewLogic.values.fpAccount).toEqual(account); expect(OverviewLogic.values.canCreateInvitations).toEqual(true); expect(OverviewLogic.values.hasUsers).toEqual(true); diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/overview_logic.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/overview_logic.ts index f1b4f447f7445..8bb177a2e742b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/overview_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/overview_logic.ts @@ -8,7 +8,7 @@ import { HttpSetup } from 'src/core/public'; import { kea } from 'kea'; -import { IAccount, IOrganization, IUser } from '../../types'; +import { IAccount, IOrganization } from '../../types'; import { IFlashMessagesProps, IKeaLogic, TKeaReducers, IKeaParams } from '../../../shared/types'; import { IFeedActivity } from './recent_activity'; @@ -26,7 +26,6 @@ export interface IOverviewServerData { activityFeed: IFeedActivity[]; organization: IOrganization; isFederatedAuth: boolean; - currentUser: IUser; fpAccount: IAccount; } @@ -63,12 +62,6 @@ export const OverviewLogic = kea({ setServerData: (_, { isFederatedAuth }) => isFederatedAuth, }, ], - currentUser: [ - {} as IUser, - { - setServerData: (_, { currentUser }) => currentUser, - }, - ], fpAccount: [ {} as IAccount, { diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.tsx index 4aa171a5a5762..94462aa8de7d1 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.tsx @@ -6,14 +6,8 @@ import React, { useContext } from 'react'; import { Route, Redirect, Switch } from 'react-router-dom'; -import { Provider } from 'react-redux'; -import { Store } from 'redux'; -import { getContext, resetContext } from 'kea'; - -resetContext({ createStore: true }); - -const store = getContext().store as Store; +import { IInitialAppData } from '../../../common/types'; import { KibanaContext, IKibanaContext } from '../index'; import { Layout } from '../shared/layout'; import { WorkplaceSearchNav } from './components/layout/nav'; @@ -23,7 +17,7 @@ import { SETUP_GUIDE_PATH } from './routes'; import { SetupGuide } from './components/setup_guide'; import { Overview } from './components/overview'; -export const WorkplaceSearch: React.FC = () => { +export const WorkplaceSearch: React.FC = (props) => { const { config } = useContext(KibanaContext) as IKibanaContext; if (!config.host) return ( @@ -38,25 +32,23 @@ export const WorkplaceSearch: React.FC = () => { ); return ( - - - - - - - - - - }> - - - {/* Will replace with groups component subsequent PR */} -
- - - - - - + + + + + + + + + }> + + + {/* Will replace with groups component subsequent PR */} +
+ + + + + ); }; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/types.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/types.ts index 77c35adef3300..a8348a6f69a39 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/types.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/types.ts @@ -4,24 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -export interface IAccount { - id: string; - isCurated?: boolean; - isAdmin: boolean; - canCreatePersonalSources: boolean; - groups: string[]; - supportEligible: boolean; -} - -export interface IOrganization { - name: string; - defaultOrgName: string; -} -export interface IUser { - firstName: string; - email: string; - name: string; - color: string; -} +export * from '../../../common/types/workplace_search'; export type TSpacerSize = 'xs' | 's' | 'm' | 'l' | 'xl' | 'xxl'; diff --git a/x-pack/plugins/enterprise_search/public/plugin.ts b/x-pack/plugins/enterprise_search/public/plugin.ts index 0d392eefe0aa2..148a50fb4a5ce 100644 --- a/x-pack/plugins/enterprise_search/public/plugin.ts +++ b/x-pack/plugins/enterprise_search/public/plugin.ts @@ -20,19 +20,16 @@ import { import { DEFAULT_APP_CATEGORIES } from '../../../../src/core/public'; import { LicensingPluginSetup } from '../../licensing/public'; +import { IInitialAppData } from '../common/types'; import { APP_SEARCH_PLUGIN, WORKPLACE_SEARCH_PLUGIN } from '../common/constants'; -import { - getPublicUrl, - ExternalUrl, - IExternalUrl, -} from './applications/shared/enterprise_search_url'; +import { ExternalUrl, IExternalUrl } from './applications/shared/enterprise_search_url'; import AppSearchLogo from './applications/app_search/assets/logo.svg'; import WorkplaceSearchLogo from './applications/workplace_search/assets/logo.svg'; export interface ClientConfigType { host?: string; } -export interface ClientData { +export interface ClientData extends IInitialAppData { externalUrl: IExternalUrl; } @@ -119,10 +116,14 @@ export class EnterpriseSearchPlugin implements Plugin { if (!this.config.host) return; // No API to call if (this.hasInitialized) return; // We've already made an initial call - // TODO: Rename to something more generic once we start fetching more data than just external_url from this endpoint - const publicUrl = await getPublicUrl(http); + try { + const { publicUrl, ...initialData } = await http.get('/api/enterprise_search/config_data'); + this.data = { ...this.data, ...initialData }; + if (publicUrl) this.data.externalUrl = new ExternalUrl(publicUrl); - if (publicUrl) this.data.externalUrl = new ExternalUrl(publicUrl); - this.hasInitialized = true; + this.hasInitialized = true; + } catch { + // The plugin will attempt to re-fetch config data on page change + } } } diff --git a/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.test.ts b/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.test.ts index ee96f8099cf7c..c26ada77f504f 100644 --- a/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.test.ts +++ b/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.test.ts @@ -11,6 +11,7 @@ const { Response } = jest.requireActual('node-fetch'); import { loggingSystemMock } from 'src/core/server/mocks'; +import { DEFAULT_INITIAL_APP_DATA } from '../../common/__mocks__'; import { callEnterpriseSearchConfigAPI } from './enterprise_search_config_api'; describe('callEnterpriseSearchConfigAPI', () => { @@ -35,13 +36,50 @@ describe('callEnterpriseSearchConfigAPI', () => { }, settings: { external_url: 'http://some.vanity.url/', + read_only_mode: false, + ilm_enabled: true, + configured_limits: { + max_document_byte_size: 102400, + max_engines_per_meta_engine: 15, + }, + app_search: { + account_id: 'some-id-string', + onboarding_complete: true, + }, + workplace_search: { + organization: { + name: 'ACME Donuts', + default_org_name: 'My Organization', + }, + fp_account: { + id: 'some-id-string', + groups: ['Default', 'Cats'], + is_admin: true, + can_create_personal_sources: true, + is_curated: false, + viewed_onboarding_page: true, + }, + }, }, - access: { - user: 'someuser', - products: { + current_user: { + name: 'someuser', + access: { app_search: true, workplace_search: false, }, + app_search_role: { + id: 'account_id:somestring|user_oid:somestring', + role_type: 'owner', + ability: { + access_all_engines: true, + destroy: ['session'], + manage: ['account_credentials', 'account_engines'], // etc + edit: ['LocoMoco::Account'], // etc + view: ['Engine'], // etc + credential_types: ['admin', 'private', 'search'], + available_role_types: ['owner', 'admin'], + }, + }, }, }; @@ -56,11 +94,61 @@ describe('callEnterpriseSearchConfigAPI', () => { }); expect(await callEnterpriseSearchConfigAPI(mockDependencies)).toEqual({ - publicUrl: 'http://some.vanity.url/', access: { hasAppSearchAccess: true, hasWorkplaceSearchAccess: false, }, + publicUrl: 'http://some.vanity.url', + ...DEFAULT_INITIAL_APP_DATA, + }); + }); + + it('falls back without error when data is unavailable', async () => { + fetchMock.mockImplementationOnce((url: string) => Promise.resolve(new Response('{}'))); + + expect(await callEnterpriseSearchConfigAPI(mockDependencies)).toEqual({ + access: { + hasAppSearchAccess: false, + hasWorkplaceSearchAccess: false, + }, + publicUrl: undefined, + readOnlyMode: false, + ilmEnabled: false, + configuredLimits: { + maxDocumentByteSize: undefined, + maxEnginesPerMetaEngine: undefined, + }, + appSearch: { + accountId: undefined, + onBoardingComplete: false, + role: { + id: undefined, + roleType: undefined, + ability: { + accessAllEngines: false, + destroy: [], + manage: [], + edit: [], + view: [], + credentialTypes: [], + availableRoleTypes: [], + }, + }, + }, + workplaceSearch: { + organization: { + name: undefined, + defaultOrgName: undefined, + }, + fpAccount: { + id: undefined, + groups: [], + isAdmin: false, + canCreatePersonalSources: false, + isCurated: false, + viewedOnboardingPage: false, + }, + }, }); }); diff --git a/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.ts b/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.ts index 7a6d1eac1b454..1dbec76806ba8 100644 --- a/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.ts +++ b/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.ts @@ -11,14 +11,17 @@ import { KibanaRequest, Logger } from 'src/core/server'; import { ConfigType } from '../'; import { IAccess } from './check_access'; +import { IInitialAppData } from '../../common/types'; +import { stripTrailingSlash } from '../../common/strip_trailing_slash'; + interface IParams { request: KibanaRequest; config: ConfigType; log: Logger; } -interface IReturn { - publicUrl?: string; +interface IReturn extends IInitialAppData { access?: IAccess; + publicUrl?: string; } /** @@ -57,10 +60,50 @@ export const callEnterpriseSearchConfigAPI = async ({ const data = await response.json(); return { - publicUrl: data?.settings?.external_url, access: { - hasAppSearchAccess: !!data?.access?.products?.app_search, - hasWorkplaceSearchAccess: !!data?.access?.products?.workplace_search, + hasAppSearchAccess: !!data?.current_user?.access?.app_search, + hasWorkplaceSearchAccess: !!data?.current_user?.access?.workplace_search, + }, + publicUrl: stripTrailingSlash(data?.settings?.external_url), + readOnlyMode: !!data?.settings?.read_only_mode, + ilmEnabled: !!data?.settings?.ilm_enabled, + configuredLimits: { + maxDocumentByteSize: data?.settings?.configured_limits?.max_document_byte_size, + maxEnginesPerMetaEngine: data?.settings?.configured_limits?.max_engines_per_meta_engine, + }, + appSearch: { + accountId: data?.settings?.app_search?.account_id, + onBoardingComplete: !!data?.settings?.app_search?.onboarding_complete, + role: { + id: data?.current_user?.app_search_role?.id, + roleType: data?.current_user?.app_search_role?.role_type, + ability: { + accessAllEngines: !!data?.current_user?.app_search_role?.ability?.access_all_engines, + destroy: data?.current_user?.app_search_role?.ability?.destroy || [], + manage: data?.current_user?.app_search_role?.ability?.manage || [], + edit: data?.current_user?.app_search_role?.ability?.edit || [], + view: data?.current_user?.app_search_role?.ability?.view || [], + credentialTypes: data?.current_user?.app_search_role?.ability?.credential_types || [], + availableRoleTypes: + data?.current_user?.app_search_role?.ability?.available_role_types || [], + }, + }, + }, + workplaceSearch: { + organization: { + name: data?.settings?.workplace_search?.organization?.name, + defaultOrgName: data?.settings?.workplace_search?.organization?.default_org_name, + }, + fpAccount: { + id: data?.settings?.workplace_search?.fp_account.id, + groups: data?.settings?.workplace_search?.fp_account.groups || [], + isAdmin: !!data?.settings?.workplace_search?.fp_account?.is_admin, + canCreatePersonalSources: !!data?.settings?.workplace_search?.fp_account + ?.can_create_personal_sources, + isCurated: !!data?.settings?.workplace_search?.fp_account.is_curated, + viewedOnboardingPage: !!data?.settings?.workplace_search?.fp_account + .viewed_onboarding_page, + }, }, }; } catch (err) { diff --git a/x-pack/plugins/enterprise_search/server/plugin.ts b/x-pack/plugins/enterprise_search/server/plugin.ts index 6de6671337797..770ea8d420c20 100644 --- a/x-pack/plugins/enterprise_search/server/plugin.ts +++ b/x-pack/plugins/enterprise_search/server/plugin.ts @@ -26,7 +26,7 @@ import { } from '../common/constants'; import { ConfigType } from './'; import { checkAccess } from './lib/check_access'; -import { registerPublicUrlRoute } from './routes/enterprise_search/public_url'; +import { registerConfigDataRoute } from './routes/enterprise_search/config_data'; import { registerTelemetryRoute } from './routes/enterprise_search/telemetry'; import { appSearchTelemetryType } from './saved_objects/app_search/telemetry'; @@ -105,7 +105,7 @@ export class EnterpriseSearchPlugin implements Plugin { const router = http.createRouter(); const dependencies = { router, config, log: this.logger }; - registerPublicUrlRoute(dependencies); + registerConfigDataRoute(dependencies); registerEnginesRoute(dependencies); registerWSOverviewRoute(dependencies); diff --git a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/public_url.test.ts b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/config_data.test.ts similarity index 50% rename from x-pack/plugins/enterprise_search/server/routes/enterprise_search/public_url.test.ts rename to x-pack/plugins/enterprise_search/server/routes/enterprise_search/config_data.test.ts index 846aae3fce56f..7484e27594df4 100644 --- a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/public_url.test.ts +++ b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/config_data.test.ts @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ +import { DEFAULT_INITIAL_APP_DATA } from '../../../common/__mocks__'; import { MockRouter, mockDependencies } from '../__mocks__'; jest.mock('../../lib/enterprise_search_config_api', () => ({ @@ -11,41 +12,51 @@ jest.mock('../../lib/enterprise_search_config_api', () => ({ })); import { callEnterpriseSearchConfigAPI } from '../../lib/enterprise_search_config_api'; -import { registerPublicUrlRoute } from './public_url'; +import { registerConfigDataRoute } from './config_data'; -describe('Enterprise Search Public URL API', () => { +describe('Enterprise Search Config Data API', () => { let mockRouter: MockRouter; beforeEach(() => { mockRouter = new MockRouter({ method: 'get' }); - registerPublicUrlRoute({ + registerConfigDataRoute({ ...mockDependencies, router: mockRouter.router, }); }); - describe('GET /api/enterprise_search/public_url', () => { - it('returns a publicUrl', async () => { + describe('GET /api/enterprise_search/config_data', () => { + it('returns an initial set of config data from Enterprise Search', async () => { + const mockData = { + access: { + hasAppSearchAccess: true, + hasWorkplaceSearchAccess: true, + }, + publicUrl: 'http://localhost:3002', + ...DEFAULT_INITIAL_APP_DATA, + }; + (callEnterpriseSearchConfigAPI as jest.Mock).mockImplementationOnce(() => { - return Promise.resolve({ publicUrl: 'http://some.vanity.url' }); + return Promise.resolve(mockData); }); - await mockRouter.callRoute({}); expect(mockRouter.response.ok).toHaveBeenCalledWith({ - body: { publicUrl: 'http://some.vanity.url' }, + body: mockData, headers: { 'content-type': 'application/json' }, }); }); - // For the most part, all error logging is handled by callEnterpriseSearchConfigAPI. - // This endpoint should mostly just fall back gracefully to an empty string - it('falls back to an empty string', async () => { + it('throws a 502 error if data returns an empty obj', async () => { + (callEnterpriseSearchConfigAPI as jest.Mock).mockImplementationOnce(() => { + return Promise.resolve({}); + }); await mockRouter.callRoute({}); - expect(mockRouter.response.ok).toHaveBeenCalledWith({ - body: { publicUrl: '' }, - headers: { 'content-type': 'application/json' }, + + expect(mockRouter.response.customError).toHaveBeenCalledWith({ + statusCode: 502, + body: 'Error fetching data from Enterprise Search', }); }); }); diff --git a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/config_data.ts b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/config_data.ts new file mode 100644 index 0000000000000..453c7fd99bf4c --- /dev/null +++ b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/config_data.ts @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { IRouteDependencies } from '../../plugin'; +import { callEnterpriseSearchConfigAPI } from '../../lib/enterprise_search_config_api'; + +export function registerConfigDataRoute({ router, config, log }: IRouteDependencies) { + router.get( + { + path: '/api/enterprise_search/config_data', + validate: false, + }, + async (context, request, response) => { + const data = await callEnterpriseSearchConfigAPI({ request, config, log }); + + if (!Object.keys(data).length) { + return response.customError({ + statusCode: 502, + body: 'Error fetching data from Enterprise Search', + }); + } else { + return response.ok({ + body: data, + headers: { 'content-type': 'application/json' }, + }); + } + } + ); +} diff --git a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/public_url.ts b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/public_url.ts deleted file mode 100644 index a9edd4eb10da0..0000000000000 --- a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/public_url.ts +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { IRouteDependencies } from '../../plugin'; -import { callEnterpriseSearchConfigAPI } from '../../lib/enterprise_search_config_api'; - -export function registerPublicUrlRoute({ router, config, log }: IRouteDependencies) { - router.get( - { - path: '/api/enterprise_search/public_url', - validate: false, - }, - async (context, request, response) => { - const { publicUrl = '' } = - (await callEnterpriseSearchConfigAPI({ request, config, log })) || {}; - - return response.ok({ - body: { publicUrl }, - headers: { 'content-type': 'application/json' }, - }); - } - ); -} From 471b11408929cb58b3fc10f886bef220f93378d6 Mon Sep 17 00:00:00 2001 From: DeDe Morton Date: Fri, 21 Aug 2020 09:08:07 -0700 Subject: [PATCH 26/45] [DOCS] Update links to Beats documentation (#70380) * Update links to Beats documentation * Update snapshot files * Fix lint errors --- docs/management/watcher-ui/index.asciidoc | 2 +- .../monitoring/monitoring-metricbeat.asciidoc | 2 +- .../public/doc_links/doc_links_service.ts | 4 ++-- .../server/tutorials/cloudwatch_logs/index.ts | 3 ++- .../instructions/auditbeat_instructions.ts | 16 ++++++------- .../instructions/filebeat_instructions.ts | 16 ++++++------- .../instructions/functionbeat_instructions.ts | 17 ++++++++----- .../instructions/heartbeat_instructions.ts | 21 ++++++++-------- .../instructions/metricbeat_instructions.ts | 23 +++++++++++------- .../instructions/winlogbeat_instructions.ts | 5 ++-- .../server/tutorials/uptime_monitors/index.ts | 2 +- .../logs/__snapshots__/reason.test.js.snap | 4 ++-- .../public/components/logs/reason.js | 4 ++-- .../flyout/__snapshots__/flyout.test.js.snap | 24 +++++++++---------- .../apm/enable_metricbeat_instructions.js | 4 ++-- .../beats/enable_metricbeat_instructions.js | 4 ++-- .../enable_metricbeat_instructions.js | 2 +- .../kibana/enable_metricbeat_instructions.js | 2 +- .../enable_metricbeat_instructions.js | 2 +- 19 files changed, 86 insertions(+), 71 deletions(-) diff --git a/docs/management/watcher-ui/index.asciidoc b/docs/management/watcher-ui/index.asciidoc index fbe5fcd5cd3a5..23a0acbff5718 100644 --- a/docs/management/watcher-ui/index.asciidoc +++ b/docs/management/watcher-ui/index.asciidoc @@ -60,7 +60,7 @@ The following example walks you through creating a threshold alert. The alert is triggered when the maximum total CPU usage on a machine goes above a certain percentage. The example uses https://www.elastic.co/products/beats/metricbeat[Metricbeat] to collect metrics from your systems and services. -{metricbeat-ref}/metricbeat-installation.html[Learn more] on how to install +{metricbeat-ref}/metricbeat-installation-configuration.html[Learn more] on how to install and get started with Metricbeat. [float] diff --git a/docs/user/monitoring/monitoring-metricbeat.asciidoc b/docs/user/monitoring/monitoring-metricbeat.asciidoc index d18ebe95c7974..5ef3b8177a9c5 100644 --- a/docs/user/monitoring/monitoring-metricbeat.asciidoc +++ b/docs/user/monitoring/monitoring-metricbeat.asciidoc @@ -82,7 +82,7 @@ For more information, see {ref}/monitoring-settings.html[Monitoring settings in and {ref}/cluster-update-settings.html[Cluster update settings]. -- -. {metricbeat-ref}/metricbeat-installation.html[Install {metricbeat}] on the +. {metricbeat-ref}/metricbeat-installation-configuration.html[Install {metricbeat}] on the same server as {kib}. . Enable the {kib} {xpack} module in {metricbeat}. + diff --git a/src/core/public/doc_links/doc_links_service.ts b/src/core/public/doc_links/doc_links_service.ts index bd279baa78d98..fc753517fd940 100644 --- a/src/core/public/doc_links/doc_links_service.ts +++ b/src/core/public/doc_links/doc_links_service.ts @@ -41,8 +41,8 @@ export class DocLinksService { }, filebeat: { base: `${ELASTIC_WEBSITE_URL}guide/en/beats/filebeat/${DOC_LINK_VERSION}`, - installation: `${ELASTIC_WEBSITE_URL}guide/en/beats/filebeat/${DOC_LINK_VERSION}/filebeat-installation.html`, - configuration: `${ELASTIC_WEBSITE_URL}guide/en/beats/filebeat/${DOC_LINK_VERSION}/filebeat-configuration.html`, + installation: `${ELASTIC_WEBSITE_URL}guide/en/beats/filebeat/${DOC_LINK_VERSION}/filebeat-installation-configuration.html`, + configuration: `${ELASTIC_WEBSITE_URL}guide/en/beats/filebeat/${DOC_LINK_VERSION}/configuring-howto-filebeat.html`, elasticsearchOutput: `${ELASTIC_WEBSITE_URL}guide/en/beats/filebeat/${DOC_LINK_VERSION}/elasticsearch-output.html`, startup: `${ELASTIC_WEBSITE_URL}guide/en/beats/filebeat/${DOC_LINK_VERSION}/filebeat-starting.html`, exportedFields: `${ELASTIC_WEBSITE_URL}guide/en/beats/filebeat/${DOC_LINK_VERSION}/exported-fields.html`, diff --git a/src/plugins/home/server/tutorials/cloudwatch_logs/index.ts b/src/plugins/home/server/tutorials/cloudwatch_logs/index.ts index fb7b07c5dc1af..6b017fae1e21f 100644 --- a/src/plugins/home/server/tutorials/cloudwatch_logs/index.ts +++ b/src/plugins/home/server/tutorials/cloudwatch_logs/index.ts @@ -47,7 +47,8 @@ export function cloudwatchLogsSpecProvider(context: TutorialContext): TutorialSc an AWS Lambda function. \ [Learn more]({learnMoreLink}).', values: { - learnMoreLink: '{config.docs.beats.functionbeat}/functionbeat-getting-started.html', + learnMoreLink: + '{config.docs.beats.functionbeat}/functionbeat-installation-configuration.html', }, }), euiIconType: 'logoAWS', diff --git a/src/plugins/home/server/tutorials/instructions/auditbeat_instructions.ts b/src/plugins/home/server/tutorials/instructions/auditbeat_instructions.ts index 2a6cfa0358709..b6f7aa8c53ac9 100644 --- a/src/plugins/home/server/tutorials/instructions/auditbeat_instructions.ts +++ b/src/plugins/home/server/tutorials/instructions/auditbeat_instructions.ts @@ -31,9 +31,9 @@ export const createAuditbeatInstructions = (context?: TutorialContext) => ({ defaultMessage: 'Download and install Auditbeat', }), textPre: i18n.translate('home.tutorials.common.auditbeatInstructions.install.osxTextPre', { - defaultMessage: 'First time using Auditbeat? See the [Getting Started Guide]({linkUrl}).', + defaultMessage: 'First time using Auditbeat? See the [Quick Start]({linkUrl}).', values: { - linkUrl: '{config.docs.beats.auditbeat}/auditbeat-getting-started.html', + linkUrl: '{config.docs.beats.auditbeat}/auditbeat-installation-configuration.html', }, }), commands: [ @@ -47,9 +47,9 @@ export const createAuditbeatInstructions = (context?: TutorialContext) => ({ defaultMessage: 'Download and install Auditbeat', }), textPre: i18n.translate('home.tutorials.common.auditbeatInstructions.install.debTextPre', { - defaultMessage: 'First time using Auditbeat? See the [Getting Started Guide]({linkUrl}).', + defaultMessage: 'First time using Auditbeat? See the [Quick Start]({linkUrl}).', values: { - linkUrl: '{config.docs.beats.auditbeat}/auditbeat-getting-started.html', + linkUrl: '{config.docs.beats.auditbeat}/auditbeat-installation-configuration.html', }, }), commands: [ @@ -68,9 +68,9 @@ export const createAuditbeatInstructions = (context?: TutorialContext) => ({ defaultMessage: 'Download and install Auditbeat', }), textPre: i18n.translate('home.tutorials.common.auditbeatInstructions.install.rpmTextPre', { - defaultMessage: 'First time using Auditbeat? See the [Getting Started Guide]({linkUrl}).', + defaultMessage: 'First time using Auditbeat? See the [Quick Start]({linkUrl}).', values: { - linkUrl: '{config.docs.beats.auditbeat}/auditbeat-getting-started.html', + linkUrl: '{config.docs.beats.auditbeat}/auditbeat-installation-configuration.html', }, }), commands: [ @@ -92,7 +92,7 @@ export const createAuditbeatInstructions = (context?: TutorialContext) => ({ 'home.tutorials.common.auditbeatInstructions.install.windowsTextPre', { defaultMessage: - 'First time using Auditbeat? See the [Getting Started Guide]({guideLinkUrl}).\n\ + 'First time using Auditbeat? See the [Quick Start]({guideLinkUrl}).\n\ 1. Download the Auditbeat Windows zip file from the [Download]({auditbeatLinkUrl}) page.\n\ 2. Extract the contents of the zip file into {folderPath}.\n\ 3. Rename the `{directoryName}` directory to `Auditbeat`.\n\ @@ -101,7 +101,7 @@ export const createAuditbeatInstructions = (context?: TutorialContext) => ({ 5. From the PowerShell prompt, run the following commands to install Auditbeat as a Windows service.', values: { folderPath: '`C:\\Program Files`', - guideLinkUrl: '{config.docs.beats.auditbeat}/auditbeat-getting-started.html', + guideLinkUrl: '{config.docs.beats.auditbeat}/auditbeat-installation-configuration.html', auditbeatLinkUrl: 'https://www.elastic.co/downloads/beats/auditbeat', directoryName: 'auditbeat-{config.kibana.version}-windows', }, diff --git a/src/plugins/home/server/tutorials/instructions/filebeat_instructions.ts b/src/plugins/home/server/tutorials/instructions/filebeat_instructions.ts index 0e99033b2ea69..c760840165bfc 100644 --- a/src/plugins/home/server/tutorials/instructions/filebeat_instructions.ts +++ b/src/plugins/home/server/tutorials/instructions/filebeat_instructions.ts @@ -31,9 +31,9 @@ export const createFilebeatInstructions = (context?: TutorialContext) => ({ defaultMessage: 'Download and install Filebeat', }), textPre: i18n.translate('home.tutorials.common.filebeatInstructions.install.osxTextPre', { - defaultMessage: 'First time using Filebeat? See the [Getting Started Guide]({linkUrl}).', + defaultMessage: 'First time using Filebeat? See the [Quick Start]({linkUrl}).', values: { - linkUrl: '{config.docs.beats.filebeat}/filebeat-getting-started.html', + linkUrl: '{config.docs.beats.filebeat}/filebeat-installation-configuration.html', }, }), commands: [ @@ -47,9 +47,9 @@ export const createFilebeatInstructions = (context?: TutorialContext) => ({ defaultMessage: 'Download and install Filebeat', }), textPre: i18n.translate('home.tutorials.common.filebeatInstructions.install.debTextPre', { - defaultMessage: 'First time using Filebeat? See the [Getting Started Guide]({linkUrl}).', + defaultMessage: 'First time using Filebeat? See the [Quick Start]({linkUrl}).', values: { - linkUrl: '{config.docs.beats.filebeat}/filebeat-getting-started.html', + linkUrl: '{config.docs.beats.filebeat}/filebeat-installation-configuration.html', }, }), commands: [ @@ -68,9 +68,9 @@ export const createFilebeatInstructions = (context?: TutorialContext) => ({ defaultMessage: 'Download and install Filebeat', }), textPre: i18n.translate('home.tutorials.common.filebeatInstructions.install.rpmTextPre', { - defaultMessage: 'First time using Filebeat? See the [Getting Started Guide]({linkUrl}).', + defaultMessage: 'First time using Filebeat? See the [Quick Start]({linkUrl}).', values: { - linkUrl: '{config.docs.beats.filebeat}/filebeat-getting-started.html', + linkUrl: '{config.docs.beats.filebeat}/filebeat-installation-configuration.html', }, }), commands: [ @@ -90,7 +90,7 @@ export const createFilebeatInstructions = (context?: TutorialContext) => ({ }), textPre: i18n.translate('home.tutorials.common.filebeatInstructions.install.windowsTextPre', { defaultMessage: - 'First time using Filebeat? See the [Getting Started Guide]({guideLinkUrl}).\n\ + 'First time using Filebeat? See the [Quick Start]({guideLinkUrl}).\n\ 1. Download the Filebeat Windows zip file from the [Download]({filebeatLinkUrl}) page.\n\ 2. Extract the contents of the zip file into {folderPath}.\n\ 3. Rename the `{directoryName}` directory to `Filebeat`.\n\ @@ -99,7 +99,7 @@ export const createFilebeatInstructions = (context?: TutorialContext) => ({ 5. From the PowerShell prompt, run the following commands to install Filebeat as a Windows service.', values: { folderPath: '`C:\\Program Files`', - guideLinkUrl: '{config.docs.beats.filebeat}/filebeat-getting-started.html', + guideLinkUrl: '{config.docs.beats.filebeat}/filebeat-installation-configuration.html', filebeatLinkUrl: 'https://www.elastic.co/downloads/beats/filebeat', directoryName: 'filebeat-{config.kibana.version}-windows', }, diff --git a/src/plugins/home/server/tutorials/instructions/functionbeat_instructions.ts b/src/plugins/home/server/tutorials/instructions/functionbeat_instructions.ts index 06ff84146b5d8..61e76bd9d3c18 100644 --- a/src/plugins/home/server/tutorials/instructions/functionbeat_instructions.ts +++ b/src/plugins/home/server/tutorials/instructions/functionbeat_instructions.ts @@ -31,8 +31,10 @@ export const createFunctionbeatInstructions = (context?: TutorialContext) => ({ defaultMessage: 'Download and install Functionbeat', }), textPre: i18n.translate('home.tutorials.common.functionbeatInstructions.install.osxTextPre', { - defaultMessage: 'First time using Functionbeat? See the [Getting Started Guide]({link}).', - values: { link: '{config.docs.beats.functionbeat}/functionbeat-getting-started.html' }, + defaultMessage: 'First time using Functionbeat? See the [Quick Start]({link}).', + values: { + link: '{config.docs.beats.functionbeat}/functionbeat-installation-configuration.html', + }, }), commands: [ 'curl -L -O https://artifacts.elastic.co/downloads/beats/functionbeat/functionbeat-{config.kibana.version}-darwin-x86_64.tar.gz', @@ -47,8 +49,10 @@ export const createFunctionbeatInstructions = (context?: TutorialContext) => ({ textPre: i18n.translate( 'home.tutorials.common.functionbeatInstructions.install.linuxTextPre', { - defaultMessage: 'First time using Functionbeat? See the [Getting Started Guide]({link}).', - values: { link: '{config.docs.beats.functionbeat}/functionbeat-getting-started.html' }, + defaultMessage: 'First time using Functionbeat? See the [Quick Start]({link}).', + values: { + link: '{config.docs.beats.functionbeat}/functionbeat-installation-configuration.html', + }, } ), commands: [ @@ -65,7 +69,7 @@ export const createFunctionbeatInstructions = (context?: TutorialContext) => ({ 'home.tutorials.common.functionbeatInstructions.install.windowsTextPre', { defaultMessage: - 'First time using Functionbeat? See the [Getting Started Guide]({functionbeatLink}).\n\ + 'First time using Functionbeat? See the [Quick Start]({functionbeatLink}).\n\ 1. Download the Functionbeat Windows zip file from the [Download]({elasticLink}) page.\n\ 2. Extract the contents of the zip file into {folderPath}.\n\ 3. Rename the {directoryName} directory to `Functionbeat`.\n\ @@ -75,7 +79,8 @@ export const createFunctionbeatInstructions = (context?: TutorialContext) => ({ values: { directoryName: '`functionbeat-{config.kibana.version}-windows`', folderPath: '`C:\\Program Files`', - functionbeatLink: '{config.docs.beats.functionbeat}/functionbeat-getting-started.html', + functionbeatLink: + '{config.docs.beats.functionbeat}/functionbeat-installation-configuration.html', elasticLink: 'https://www.elastic.co/downloads/beats/functionbeat', }, } diff --git a/src/plugins/home/server/tutorials/instructions/heartbeat_instructions.ts b/src/plugins/home/server/tutorials/instructions/heartbeat_instructions.ts index fa5bf5df13b6b..4d519ad8aa01e 100644 --- a/src/plugins/home/server/tutorials/instructions/heartbeat_instructions.ts +++ b/src/plugins/home/server/tutorials/instructions/heartbeat_instructions.ts @@ -31,8 +31,8 @@ export const createHeartbeatInstructions = (context?: TutorialContext) => ({ defaultMessage: 'Download and install Heartbeat', }), textPre: i18n.translate('home.tutorials.common.heartbeatInstructions.install.osxTextPre', { - defaultMessage: 'First time using Heartbeat? See the [Getting Started Guide]({link}).', - values: { link: '{config.docs.beats.heartbeat}/heartbeat-getting-started.html' }, + defaultMessage: 'First time using Heartbeat? See the [Quick Start]({link}).', + values: { link: '{config.docs.beats.heartbeat}/heartbeat-installation-configuration.html' }, }), commands: [ 'curl -L -O https://artifacts.elastic.co/downloads/beats/heartbeat/heartbeat-{config.kibana.version}-darwin-x86_64.tar.gz', @@ -45,8 +45,8 @@ export const createHeartbeatInstructions = (context?: TutorialContext) => ({ defaultMessage: 'Download and install Heartbeat', }), textPre: i18n.translate('home.tutorials.common.heartbeatInstructions.install.debTextPre', { - defaultMessage: 'First time using Heartbeat? See the [Getting Started Guide]({link}).', - values: { link: '{config.docs.beats.heartbeat}/heartbeat-getting-started.html' }, + defaultMessage: 'First time using Heartbeat? See the [Quick Start]({link}).', + values: { link: '{config.docs.beats.heartbeat}/heartbeat-installation-configuration.html' }, }), commands: [ 'curl -L -O https://artifacts.elastic.co/downloads/beats/heartbeat/heartbeat-{config.kibana.version}-amd64.deb', @@ -62,8 +62,8 @@ export const createHeartbeatInstructions = (context?: TutorialContext) => ({ defaultMessage: 'Download and install Heartbeat', }), textPre: i18n.translate('home.tutorials.common.heartbeatInstructions.install.rpmTextPre', { - defaultMessage: 'First time using Heartbeat? See the [Getting Started Guide]({link}).', - values: { link: '{config.docs.beats.heartbeat}/heartbeat-getting-started.html' }, + defaultMessage: 'First time using Heartbeat? See the [Quick Start]({link}).', + values: { link: '{config.docs.beats.heartbeat}/heartbeat-installation-configuration.html' }, }), commands: [ 'curl -L -O https://artifacts.elastic.co/downloads/beats/heartbeat/heartbeat-{config.kibana.version}-x86_64.rpm', @@ -82,7 +82,7 @@ export const createHeartbeatInstructions = (context?: TutorialContext) => ({ 'home.tutorials.common.heartbeatInstructions.install.windowsTextPre', { defaultMessage: - 'First time using Heartbeat? See the [Getting Started Guide]({heartbeatLink}).\n\ + 'First time using Heartbeat? See the [Quick Start]({heartbeatLink}).\n\ 1. Download the Heartbeat Windows zip file from the [Download]({elasticLink}) page.\n\ 2. Extract the contents of the zip file into {folderPath}.\n\ 3. Rename the {directoryName} directory to `Heartbeat`.\n\ @@ -92,7 +92,8 @@ export const createHeartbeatInstructions = (context?: TutorialContext) => ({ values: { directoryName: '`heartbeat-{config.kibana.version}-windows`', folderPath: '`C:\\Program Files`', - heartbeatLink: '{config.docs.beats.heartbeat}/heartbeat-getting-started.html', + heartbeatLink: + '{config.docs.beats.heartbeat}/heartbeat-installation-configuration.html', elasticLink: 'https://www.elastic.co/downloads/beats/heartbeat', }, } @@ -357,7 +358,7 @@ export function heartbeatEnableInstructionsOnPrem() { 'Where {hostTemplate} is your monitored URL, For more details on how to configure Monitors in \ Heartbeat, read the [Heartbeat configuration docs.]({configureLink})', values: { - configureLink: '{config.docs.beats.heartbeat}/heartbeat-configuration.html', + configureLink: '{config.docs.beats.heartbeat}/configuring-howto-heartbeat.html', hostTemplate: '``', }, } @@ -428,7 +429,7 @@ export function heartbeatEnableInstructionsCloud() { { defaultMessage: 'For more details on how to configure Monitors in Heartbeat, read the [Heartbeat configuration docs.]({configureLink})', - values: { configureLink: '{config.docs.beats.heartbeat}/heartbeat-configuration.html' }, + values: { configureLink: '{config.docs.beats.heartbeat}/configuring-howto-heartbeat.html' }, } ); return { diff --git a/src/plugins/home/server/tutorials/instructions/metricbeat_instructions.ts b/src/plugins/home/server/tutorials/instructions/metricbeat_instructions.ts index 651405941610f..cce93e0dfb527 100644 --- a/src/plugins/home/server/tutorials/instructions/metricbeat_instructions.ts +++ b/src/plugins/home/server/tutorials/instructions/metricbeat_instructions.ts @@ -31,8 +31,10 @@ export const createMetricbeatInstructions = (context?: TutorialContext) => ({ defaultMessage: 'Download and install Metricbeat', }), textPre: i18n.translate('home.tutorials.common.metricbeatInstructions.install.osxTextPre', { - defaultMessage: 'First time using Metricbeat? See the [Getting Started Guide]({link}).', - values: { link: '{config.docs.beats.metricbeat}/metricbeat-getting-started.html' }, + defaultMessage: 'First time using Metricbeat? See the [Quick Start]({link}).', + values: { + link: '{config.docs.beats.metricbeat}/metricbeat-installation-configuration.html', + }, }), commands: [ 'curl -L -O https://artifacts.elastic.co/downloads/beats/metricbeat/metricbeat-{config.kibana.version}-darwin-x86_64.tar.gz', @@ -45,8 +47,10 @@ export const createMetricbeatInstructions = (context?: TutorialContext) => ({ defaultMessage: 'Download and install Metricbeat', }), textPre: i18n.translate('home.tutorials.common.metricbeatInstructions.install.debTextPre', { - defaultMessage: 'First time using Metricbeat? See the [Getting Started Guide]({link}).', - values: { link: '{config.docs.beats.metricbeat}/metricbeat-getting-started.html' }, + defaultMessage: 'First time using Metricbeat? See the [Quick Start]({link}).', + values: { + link: '{config.docs.beats.metricbeat}/metricbeat-installation-configuration.html', + }, }), commands: [ 'curl -L -O https://artifacts.elastic.co/downloads/beats/metricbeat/metricbeat-{config.kibana.version}-amd64.deb', @@ -62,8 +66,10 @@ export const createMetricbeatInstructions = (context?: TutorialContext) => ({ defaultMessage: 'Download and install Metricbeat', }), textPre: i18n.translate('home.tutorials.common.metricbeatInstructions.install.rpmTextPre', { - defaultMessage: 'First time using Metricbeat? See the [Getting Started Guide]({link}).', - values: { link: '{config.docs.beats.metricbeat}/metricbeat-getting-started.html' }, + defaultMessage: 'First time using Metricbeat? See the [Quick Start]({link}).', + values: { + link: '{config.docs.beats.metricbeat}/metricbeat-installation-configuration.html', + }, }), commands: [ 'curl -L -O https://artifacts.elastic.co/downloads/beats/metricbeat/metricbeat-{config.kibana.version}-x86_64.rpm', @@ -82,7 +88,7 @@ export const createMetricbeatInstructions = (context?: TutorialContext) => ({ 'home.tutorials.common.metricbeatInstructions.install.windowsTextPre', { defaultMessage: - 'First time using Metricbeat? See the [Getting Started Guide]({metricbeatLink}).\n\ + 'First time using Metricbeat? See the [Quick Start]({metricbeatLink}).\n\ 1. Download the Metricbeat Windows zip file from the [Download]({elasticLink}) page.\n\ 2. Extract the contents of the zip file into {folderPath}.\n\ 3. Rename the {directoryName} directory to `Metricbeat`.\n\ @@ -92,7 +98,8 @@ export const createMetricbeatInstructions = (context?: TutorialContext) => ({ values: { directoryName: '`metricbeat-{config.kibana.version}-windows`', folderPath: '`C:\\Program Files`', - metricbeatLink: '{config.docs.beats.metricbeat}/metricbeat-getting-started.html', + metricbeatLink: + '{config.docs.beats.metricbeat}/metricbeat-installation-configuration.html', elasticLink: 'https://www.elastic.co/downloads/beats/metricbeat', }, } diff --git a/src/plugins/home/server/tutorials/instructions/winlogbeat_instructions.ts b/src/plugins/home/server/tutorials/instructions/winlogbeat_instructions.ts index 27d7822e080a3..1eacbb729aee4 100644 --- a/src/plugins/home/server/tutorials/instructions/winlogbeat_instructions.ts +++ b/src/plugins/home/server/tutorials/instructions/winlogbeat_instructions.ts @@ -34,7 +34,7 @@ export const createWinlogbeatInstructions = (context?: TutorialContext) => ({ 'home.tutorials.common.winlogbeatInstructions.install.windowsTextPre', { defaultMessage: - 'First time using Winlogbeat? See the [Getting Started Guide]({winlogbeatLink}).\n\ + 'First time using Winlogbeat? See the [Quick Start]({winlogbeatLink}).\n\ 1. Download the Winlogbeat Windows zip file from the [Download]({elasticLink}) page.\n\ 2. Extract the contents of the zip file into {folderPath}.\n\ 3. Rename the {directoryName} directory to `Winlogbeat`.\n\ @@ -44,7 +44,8 @@ export const createWinlogbeatInstructions = (context?: TutorialContext) => ({ values: { directoryName: '`winlogbeat-{config.kibana.version}-windows`', folderPath: '`C:\\Program Files`', - winlogbeatLink: '{config.docs.beats.winlogbeat}/winlogbeat-getting-started.html', + winlogbeatLink: + '{config.docs.beats.winlogbeat}/winlogbeat-installation-configuration.html', elasticLink: 'https://www.elastic.co/downloads/beats/winlogbeat', }, } diff --git a/src/plugins/home/server/tutorials/uptime_monitors/index.ts b/src/plugins/home/server/tutorials/uptime_monitors/index.ts index 7366583e59778..96b81c9fb4181 100644 --- a/src/plugins/home/server/tutorials/uptime_monitors/index.ts +++ b/src/plugins/home/server/tutorials/uptime_monitors/index.ts @@ -47,7 +47,7 @@ export function uptimeMonitorsSpecProvider(context: TutorialContext): TutorialSc Given a list of URLs, Heartbeat asks the simple question: Are you alive? \ [Learn more]({learnMoreLink}).', values: { - learnMoreLink: '{config.docs.beats.heartbeat}/heartbeat-getting-started.html', + learnMoreLink: '{config.docs.beats.heartbeat}/heartbeat-installation-configuration.html', }, }), euiIconType: 'uptimeApp', diff --git a/x-pack/plugins/monitoring/public/components/logs/__snapshots__/reason.test.js.snap b/x-pack/plugins/monitoring/public/components/logs/__snapshots__/reason.test.js.snap index b63fe7047e96c..c925ecd1c98ff 100644 --- a/x-pack/plugins/monitoring/public/components/logs/__snapshots__/reason.test.js.snap +++ b/x-pack/plugins/monitoring/public/components/logs/__snapshots__/reason.test.js.snap @@ -13,7 +13,7 @@ exports[`Logs should render a default message 1`] = ` values={ Object { "link": Filebeat diff --git a/x-pack/plugins/monitoring/public/components/logs/reason.js b/x-pack/plugins/monitoring/public/components/logs/reason.js index ad21f7f81d9bd..55dca72bf645d 100644 --- a/x-pack/plugins/monitoring/public/components/logs/reason.js +++ b/x-pack/plugins/monitoring/public/components/logs/reason.js @@ -24,7 +24,7 @@ export const Reason = ({ reason }) => { link: ( { link: ( {i18n.translate('xpack.monitoring.logs.reason.noIndexPatternLink', { defaultMessage: 'Filebeat', diff --git a/x-pack/plugins/monitoring/public/components/metricbeat_migration/flyout/__snapshots__/flyout.test.js.snap b/x-pack/plugins/monitoring/public/components/metricbeat_migration/flyout/__snapshots__/flyout.test.js.snap index c5507efb989de..2f29cd9122a61 100644 --- a/x-pack/plugins/monitoring/public/components/metricbeat_migration/flyout/__snapshots__/flyout.test.js.snap +++ b/x-pack/plugins/monitoring/public/components/metricbeat_migration/flyout/__snapshots__/flyout.test.js.snap @@ -156,7 +156,7 @@ exports[`Flyout apm part two should show instructions to migrate to metricbeat 1 "children":

Date: Fri, 21 Aug 2020 18:08:25 +0200 Subject: [PATCH 27/45] [Lens] Register saved object references (#74523) --- x-pack/plugins/lens/common/types.ts | 10 + .../lens/public/app_plugin/app.test.tsx | 137 +++++++---- x-pack/plugins/lens/public/app_plugin/app.tsx | 92 ++++--- .../visualization.test.tsx | 19 +- .../datatable_visualization/visualization.tsx | 11 +- .../__mocks__/expression_helpers.ts | 14 ++ .../editor_frame/config_panel/layer_panel.tsx | 1 - .../editor_frame/editor_frame.test.tsx | 109 +++------ .../editor_frame/editor_frame.tsx | 116 ++++----- .../editor_frame/expression_helpers.ts | 60 +---- .../editor_frame/save.test.ts | 37 ++- .../editor_frame_service/editor_frame/save.ts | 73 +++--- .../editor_frame/state_helpers.ts | 87 +++++++ .../editor_frame/state_management.test.ts | 8 +- .../editor_frame/suggestion_helpers.ts | 2 +- .../editor_frame/suggestion_panel.test.tsx | 1 - .../editor_frame/suggestion_panel.tsx | 41 ++-- .../workspace_panel/chart_switch.tsx | 2 +- .../workspace_panel/workspace_panel.test.tsx | 19 +- .../workspace_panel/workspace_panel.tsx | 21 +- .../embeddable/embeddable.test.tsx | 56 ++++- .../embeddable/embeddable.tsx | 60 ++++- .../embeddable/embeddable_factory.ts | 15 +- .../embeddable/expression_wrapper.tsx | 13 +- .../public/editor_frame_service/mocks.tsx | 4 +- .../public/editor_frame_service/service.tsx | 20 +- .../__mocks__/loader.ts | 4 + .../indexpattern.test.ts | 107 ++++---- .../indexpattern_datasource/indexpattern.tsx | 34 ++- .../indexpattern_datasource/loader.test.ts | 86 ++++++- .../public/indexpattern_datasource/loader.ts | 54 ++++- .../public/indexpattern_datasource/types.ts | 9 +- .../metric_visualization.test.ts | 9 +- .../metric_visualization.tsx | 16 +- .../lens/public/metric_visualization/types.ts | 2 - .../persistence/filter_references.test.ts | 99 ++++++++ .../public/persistence/filter_references.ts | 56 +++++ .../plugins/lens/public/persistence/index.ts | 1 + .../persistence/saved_object_store.test.ts | 51 ++-- .../public/persistence/saved_object_store.ts | 37 +-- .../pie_visualization/pie_visualization.tsx | 4 +- .../public/pie_visualization/to_expression.ts | 20 +- x-pack/plugins/lens/public/types.ts | 37 ++- .../xy_visualization/to_expression.test.ts | 16 +- .../public/xy_visualization/to_expression.ts | 32 +-- .../lens/public/xy_visualization/types.ts | 1 - .../xy_visualization/xy_visualization.test.ts | 6 - .../xy_visualization/xy_visualization.tsx | 6 +- .../__snapshots__/migrations.test.ts.snap | 188 ++++++++++++++ x-pack/plugins/lens/server/migrations.test.ts | 229 ++++++++++++++++++ x-pack/plugins/lens/server/migrations.ts | 136 ++++++++++- 51 files changed, 1609 insertions(+), 659 deletions(-) create mode 100644 x-pack/plugins/lens/public/editor_frame_service/editor_frame/__mocks__/expression_helpers.ts create mode 100644 x-pack/plugins/lens/public/editor_frame_service/editor_frame/state_helpers.ts create mode 100644 x-pack/plugins/lens/public/persistence/filter_references.test.ts create mode 100644 x-pack/plugins/lens/public/persistence/filter_references.ts create mode 100644 x-pack/plugins/lens/server/__snapshots__/migrations.test.ts.snap diff --git a/x-pack/plugins/lens/common/types.ts b/x-pack/plugins/lens/common/types.ts index 56a56bdc2d59c..c572b59899fce 100644 --- a/x-pack/plugins/lens/common/types.ts +++ b/x-pack/plugins/lens/common/types.ts @@ -4,6 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +import { FilterMeta, Filter } from 'src/plugins/data/common'; + export interface ExistingFields { indexPatternTitle: string; existingFieldNames: string[]; @@ -13,3 +15,11 @@ export interface DateRange { fromDate: string; toDate: string; } + +export interface PersistableFilterMeta extends FilterMeta { + indexRefName?: string; +} + +export interface PersistableFilter extends Filter { + meta: PersistableFilterMeta; +} diff --git a/x-pack/plugins/lens/public/app_plugin/app.test.tsx b/x-pack/plugins/lens/public/app_plugin/app.test.tsx index 70136a486e8c1..442f82161512f 100644 --- a/x-pack/plugins/lens/public/app_plugin/app.test.tsx +++ b/x-pack/plugins/lens/public/app_plugin/app.test.tsx @@ -33,7 +33,7 @@ import { navigationPluginMock } from '../../../../../src/plugins/navigation/publ import { TopNavMenuData } from '../../../../../src/plugins/navigation/public'; import { coreMock } from 'src/core/public/mocks'; -jest.mock('../persistence'); +jest.mock('../editor_frame_service/editor_frame/expression_helpers'); jest.mock('src/core/public'); jest.mock('../../../../../src/plugins/saved_objects/public', () => { // eslint-disable-next-line no-shadow @@ -284,11 +284,11 @@ describe('Lens App', () => { (defaultArgs.docStorage.load as jest.Mock).mockResolvedValue({ id: '1234', title: 'Daaaaaaadaumching!', - expression: 'valid expression', state: { query: 'fake query', - datasourceMetaData: { filterableIndexPatterns: [{ id: '1', title: 'saved' }] }, + filters: [], }, + references: [], }); await act(async () => { instance.setProps({ docId: '1234' }); @@ -346,12 +346,11 @@ describe('Lens App', () => { args.editorFrame = frame; (args.docStorage.load as jest.Mock).mockResolvedValue({ id: '1234', - expression: 'valid expression', state: { query: 'fake query', filters: [{ query: { match_phrase: { src: 'test' } } }], - datasourceMetaData: { filterableIndexPatterns: [{ id: '1', title: 'saved' }] }, }, + references: [{ type: 'index-pattern', id: '1', name: 'index-pattern-0' }], }); instance = mount(); @@ -375,15 +374,13 @@ describe('Lens App', () => { expect(frame.mount).toHaveBeenCalledWith( expect.any(Element), expect.objectContaining({ - doc: { + doc: expect.objectContaining({ id: '1234', - expression: 'valid expression', - state: { + state: expect.objectContaining({ query: 'fake query', filters: [{ query: { match_phrase: { src: 'test' } } }], - datasourceMetaData: { filterableIndexPatterns: [{ id: '1', title: 'saved' }] }, - }, - }, + }), + }), }) ); }); @@ -444,7 +441,6 @@ describe('Lens App', () => { expression: 'valid expression', state: { query: 'kuery', - datasourceMetaData: { filterableIndexPatterns: [{ id: '1', title: 'saved' }] }, }, } as jest.ResolvedValue); }); @@ -467,7 +463,12 @@ describe('Lens App', () => { } async function save({ - lastKnownDoc = { expression: 'kibana 3' }, + lastKnownDoc = { + references: [], + state: { + filters: [], + }, + }, initialDocId, ...saveProps }: SaveProps & { @@ -481,16 +482,14 @@ describe('Lens App', () => { args.editorFrame = frame; (args.docStorage.load as jest.Mock).mockResolvedValue({ id: '1234', - expression: 'kibana', + references: [], state: { query: 'fake query', - datasourceMetaData: { filterableIndexPatterns: [{ id: '1', title: 'saved' }] }, filters: [], }, }); (args.docStorage.save as jest.Mock).mockImplementation(async ({ id }) => ({ id: id || 'aaa', - expression: 'kibana 2', })); await act(async () => { @@ -508,6 +507,7 @@ describe('Lens App', () => { onChange({ filterableIndexPatterns: [], doc: { id: initialDocId, ...lastKnownDoc } as Document, + isSaveable: true, }) ); @@ -541,7 +541,8 @@ describe('Lens App', () => { act(() => onChange({ filterableIndexPatterns: [], - doc: ({ id: 'will save this', expression: 'valid expression' } as unknown) as Document, + doc: ({ id: 'will save this' } as unknown) as Document, + isSaveable: true, }) ); instance.update(); @@ -560,7 +561,8 @@ describe('Lens App', () => { act(() => onChange({ filterableIndexPatterns: [], - doc: ({ id: 'will save this', expression: 'valid expression' } as unknown) as Document, + doc: ({ id: 'will save this' } as unknown) as Document, + isSaveable: true, }) ); instance.update(); @@ -575,11 +577,12 @@ describe('Lens App', () => { newTitle: 'hello there', }); - expect(args.docStorage.save).toHaveBeenCalledWith({ - id: undefined, - title: 'hello there', - expression: 'kibana 3', - }); + expect(args.docStorage.save).toHaveBeenCalledWith( + expect.objectContaining({ + id: undefined, + title: 'hello there', + }) + ); expect(args.redirectTo).toHaveBeenCalledWith('aaa', undefined, true); @@ -595,11 +598,12 @@ describe('Lens App', () => { newTitle: 'hello there', }); - expect(args.docStorage.save).toHaveBeenCalledWith({ - id: undefined, - title: 'hello there', - expression: 'kibana 3', - }); + expect(args.docStorage.save).toHaveBeenCalledWith( + expect.objectContaining({ + id: undefined, + title: 'hello there', + }) + ); expect(args.redirectTo).toHaveBeenCalledWith('aaa', undefined, true); @@ -615,11 +619,12 @@ describe('Lens App', () => { newTitle: 'hello there', }); - expect(args.docStorage.save).toHaveBeenCalledWith({ - id: '1234', - title: 'hello there', - expression: 'kibana 3', - }); + expect(args.docStorage.save).toHaveBeenCalledWith( + expect.objectContaining({ + id: '1234', + title: 'hello there', + }) + ); expect(args.redirectTo).not.toHaveBeenCalled(); @@ -639,7 +644,8 @@ describe('Lens App', () => { act(() => onChange({ filterableIndexPatterns: [], - doc: ({ id: undefined, expression: 'new expression' } as unknown) as Document, + doc: ({ id: undefined } as unknown) as Document, + isSaveable: true, }) ); @@ -663,11 +669,12 @@ describe('Lens App', () => { newTitle: 'hello there', }); - expect(args.docStorage.save).toHaveBeenCalledWith({ - expression: 'kibana 3', - id: undefined, - title: 'hello there', - }); + expect(args.docStorage.save).toHaveBeenCalledWith( + expect.objectContaining({ + id: undefined, + title: 'hello there', + }) + ); expect(args.redirectTo).toHaveBeenCalledWith('aaa', true, true); }); @@ -717,7 +724,8 @@ describe('Lens App', () => { await act(async () => onChange({ filterableIndexPatterns: [], - doc: ({ id: '123', expression: 'valid expression' } as unknown) as Document, + doc: ({ id: '123' } as unknown) as Document, + isSaveable: true, }) ); instance.update(); @@ -756,7 +764,8 @@ describe('Lens App', () => { await act(async () => onChange({ filterableIndexPatterns: [], - doc: ({ expression: 'valid expression' } as unknown) as Document, + doc: ({} as unknown) as Document, + isSaveable: true, }) ); instance.update(); @@ -779,7 +788,6 @@ describe('Lens App', () => { expression: 'valid expression', state: { query: 'kuery', - datasourceMetaData: { filterableIndexPatterns: [{ id: '1', title: 'saved' }] }, }, } as jest.ResolvedValue); }); @@ -824,8 +832,9 @@ describe('Lens App', () => { await act(async () => { onChange({ - filterableIndexPatterns: [{ id: '1', title: 'newIndex' }], - doc: ({ id: undefined, expression: 'valid expression' } as unknown) as Document, + filterableIndexPatterns: ['1'], + doc: ({ id: undefined } as unknown) as Document, + isSaveable: true, }); }); @@ -842,8 +851,9 @@ describe('Lens App', () => { await act(async () => { onChange({ - filterableIndexPatterns: [{ id: '2', title: 'second index' }], - doc: ({ id: undefined, expression: 'valid expression' } as unknown) as Document, + filterableIndexPatterns: ['2'], + doc: ({ id: undefined } as unknown) as Document, + isSaveable: true, }); }); @@ -1078,11 +1088,11 @@ describe('Lens App', () => { (defaultArgs.docStorage.load as jest.Mock).mockResolvedValue({ id: '1234', title: 'My cool doc', - expression: 'valid expression', state: { query: 'kuery', - datasourceMetaData: { filterableIndexPatterns: [{ id: '1', title: 'saved' }] }, + filters: [], }, + references: [], } as jest.ResolvedValue); }); @@ -1114,7 +1124,12 @@ describe('Lens App', () => { act(() => onChange({ filterableIndexPatterns: [], - doc: ({ id: undefined, expression: 'valid expression' } as unknown) as Document, + doc: ({ + id: undefined, + + references: [], + } as unknown) as Document, + isSaveable: true, }) ); instance.update(); @@ -1135,7 +1150,8 @@ describe('Lens App', () => { act(() => onChange({ filterableIndexPatterns: [], - doc: ({ id: undefined, expression: 'valid expression' } as unknown) as Document, + doc: ({ id: undefined, state: {} } as unknown) as Document, + isSaveable: true, }) ); instance.update(); @@ -1159,7 +1175,12 @@ describe('Lens App', () => { act(() => onChange({ filterableIndexPatterns: [], - doc: ({ id: '1234', expression: 'different expression' } as unknown) as Document, + doc: ({ + id: '1234', + + references: [], + } as unknown) as Document, + isSaveable: true, }) ); instance.update(); @@ -1183,7 +1204,16 @@ describe('Lens App', () => { act(() => onChange({ filterableIndexPatterns: [], - doc: ({ id: '1234', expression: 'valid expression' } as unknown) as Document, + doc: ({ + id: '1234', + title: 'My cool doc', + references: [], + state: { + query: 'kuery', + filters: [], + }, + } as unknown) as Document, + isSaveable: true, }) ); instance.update(); @@ -1207,7 +1237,8 @@ describe('Lens App', () => { act(() => onChange({ filterableIndexPatterns: [], - doc: ({ id: '1234', expression: null } as unknown) as Document, + doc: ({ id: '1234', references: [] } as unknown) as Document, + isSaveable: true, }) ); instance.update(); diff --git a/x-pack/plugins/lens/public/app_plugin/app.tsx b/x-pack/plugins/lens/public/app_plugin/app.tsx index 5ca6f27a0c578..021ca8b182b2b 100644 --- a/x-pack/plugins/lens/public/app_plugin/app.tsx +++ b/x-pack/plugins/lens/public/app_plugin/app.tsx @@ -28,7 +28,7 @@ import { OnSaveProps, checkForDuplicateTitle, } from '../../../../../src/plugins/saved_objects/public'; -import { Document, SavedObjectStore } from '../persistence'; +import { Document, SavedObjectStore, injectFilterReferences } from '../persistence'; import { EditorFrameInstance } from '../types'; import { NativeRenderer } from '../native_renderer'; import { trackUiEvent } from '../lens_ui_telemetry'; @@ -57,6 +57,7 @@ interface State { query: Query; filters: Filter[]; savedQuery?: SavedQuery; + isSaveable: boolean; } export function App({ @@ -100,6 +101,7 @@ export function App({ originatingApp, filters: data.query.filterManager.getFilters(), indicateNoData: false, + isSaveable: false, }; }); @@ -122,11 +124,7 @@ export function App({ const { lastKnownDoc } = state; - const isSaveable = - lastKnownDoc && - lastKnownDoc.expression && - lastKnownDoc.expression.length > 0 && - core.application.capabilities.visualize.save; + const savingPermitted = state.isSaveable && core.application.capabilities.visualize.save; useEffect(() => { // Clear app-specific filters when navigating to Lens. Necessary because Lens @@ -177,15 +175,34 @@ export function App({ history, ]); + const getLastKnownDocWithoutPinnedFilters = useCallback( + function () { + if (!lastKnownDoc) return undefined; + const [pinnedFilters, appFilters] = _.partition( + injectFilterReferences(lastKnownDoc.state?.filters || [], lastKnownDoc.references), + esFilters.isFilterPinned + ); + return pinnedFilters?.length + ? { + ...lastKnownDoc, + state: { + ...lastKnownDoc.state, + filters: appFilters, + }, + } + : lastKnownDoc; + }, + [lastKnownDoc] + ); + useEffect(() => { onAppLeave((actions) => { // Confirm when the user has made any changes to an existing doc // or when the user has configured something without saving if ( core.application.capabilities.visualize.save && - (state.persistedDoc?.expression - ? !_.isEqual(lastKnownDoc?.expression, state.persistedDoc.expression) - : lastKnownDoc?.expression) + !_.isEqual(state.persistedDoc?.state, getLastKnownDocWithoutPinnedFilters()?.state) && + (state.isSaveable || state.persistedDoc) ) { return actions.confirm( i18n.translate('xpack.lens.app.unsavedWorkMessage', { @@ -199,7 +216,14 @@ export function App({ return actions.default(); } }); - }, [lastKnownDoc, onAppLeave, state.persistedDoc, core.application.capabilities.visualize.save]); + }, [ + lastKnownDoc, + onAppLeave, + state.persistedDoc, + state.isSaveable, + core.application.capabilities.visualize.save, + getLastKnownDocWithoutPinnedFilters, + ]); // Sync Kibana breadcrumbs any time the saved document's title changes useEffect(() => { @@ -248,13 +272,17 @@ export function App({ .load(docId) .then((doc) => { getAllIndexPatterns( - doc.state.datasourceMetaData.filterableIndexPatterns, + _.uniq( + doc.references.filter(({ type }) => type === 'index-pattern').map(({ id }) => id) + ), data.indexPatterns, core.notifications ) .then((indexPatterns) => { // Don't overwrite any pinned filters - data.query.filterManager.setAppFilters(doc.state.filters); + data.query.filterManager.setAppFilters( + injectFilterReferences(doc.state.filters, doc.references) + ); setState((s) => ({ ...s, isLoading: false, @@ -264,13 +292,13 @@ export function App({ indexPatternsForTopNav: indexPatterns, })); }) - .catch(() => { + .catch((e) => { setState((s) => ({ ...s, isLoading: false })); redirectTo(); }); }) - .catch(() => { + .catch((e) => { setState((s) => ({ ...s, isLoading: false })); core.notifications.toasts.addDanger( @@ -306,22 +334,9 @@ export function App({ if (!lastKnownDoc) { return; } - const [pinnedFilters, appFilters] = _.partition( - lastKnownDoc.state?.filters, - esFilters.isFilterPinned - ); - const lastDocWithoutPinned = pinnedFilters?.length - ? { - ...lastKnownDoc, - state: { - ...lastKnownDoc.state, - filters: appFilters, - }, - } - : lastKnownDoc; const doc = { - ...lastDocWithoutPinned, + ...getLastKnownDocWithoutPinnedFilters()!, description: saveProps.newDescription, id: saveProps.newCopyOnSave ? undefined : lastKnownDoc.id, title: saveProps.newTitle, @@ -411,7 +426,7 @@ export function App({ emphasize: true, iconType: 'check', run: () => { - if (isSaveable && lastKnownDoc) { + if (savingPermitted) { runSave({ newTitle: lastKnownDoc.title, newCopyOnSave: false, @@ -421,7 +436,7 @@ export function App({ } }, testId: 'lnsApp_saveAndReturnButton', - disableButton: !isSaveable, + disableButton: !savingPermitted, }, ] : []), @@ -436,12 +451,12 @@ export function App({ }), emphasize: !state.originatingApp || !lastKnownDoc?.id, run: () => { - if (isSaveable && lastKnownDoc) { + if (savingPermitted) { setState((s) => ({ ...s, isSaveModalVisible: true })); } }, testId: 'lnsApp_saveButton', - disableButton: !isSaveable, + disableButton: !savingPermitted, }, ]} data-test-subj="lnsApp_topNav" @@ -522,7 +537,10 @@ export function App({ doc: state.persistedDoc, onError, showNoDataPopover, - onChange: ({ filterableIndexPatterns, doc }) => { + onChange: ({ filterableIndexPatterns, doc, isSaveable }) => { + if (isSaveable !== state.isSaveable) { + setState((s) => ({ ...s, isSaveable })); + } if (!_.isEqual(state.persistedDoc, doc)) { setState((s) => ({ ...s, lastKnownDoc: doc })); } @@ -530,8 +548,8 @@ export function App({ // Update the cached index patterns if the user made a change to any of them if ( state.indexPatternsForTopNav.length !== filterableIndexPatterns.length || - filterableIndexPatterns.find( - ({ id }) => + filterableIndexPatterns.some( + (id) => !state.indexPatternsForTopNav.find((indexPattern) => indexPattern.id === id) ) ) { @@ -573,12 +591,12 @@ export function App({ } export async function getAllIndexPatterns( - ids: Array<{ id: string }>, + ids: string[], indexPatternsService: IndexPatternsContract, notifications: NotificationsStart ): Promise { try { - return await Promise.all(ids.map(({ id }) => indexPatternsService.get(id))); + return await Promise.all(ids.map((id) => indexPatternsService.get(id))); } catch (e) { notifications.toasts.addDanger( i18n.translate('xpack.lens.app.indexPatternLoadingError', { diff --git a/x-pack/plugins/lens/public/datatable_visualization/visualization.test.tsx b/x-pack/plugins/lens/public/datatable_visualization/visualization.test.tsx index 0b6584277ffa7..194f12cf9291b 100644 --- a/x-pack/plugins/lens/public/datatable_visualization/visualization.test.tsx +++ b/x-pack/plugins/lens/public/datatable_visualization/visualization.test.tsx @@ -50,20 +50,6 @@ describe('Datatable Visualization', () => { }); }); - describe('#getPersistableState', () => { - it('should persist the internal state', () => { - const expectedState: DatatableVisualizationState = { - layers: [ - { - layerId: 'baz', - columns: ['a', 'b', 'c'], - }, - ], - }; - expect(datatableVisualization.getPersistableState(expectedState)).toEqual(expectedState); - }); - }); - describe('#getLayerIds', () => { it('return the layer ids', () => { const state: DatatableVisualizationState = { @@ -340,7 +326,10 @@ describe('Datatable Visualization', () => { label: 'label', }); - const expression = datatableVisualization.toExpression({ layers: [layer] }, frame) as Ast; + const expression = datatableVisualization.toExpression( + { layers: [layer] }, + frame.datasourceLayers + ) as Ast; const tableArgs = buildExpression(expression).findFunction('lens_datatable_columns'); expect(tableArgs).toHaveLength(1); diff --git a/x-pack/plugins/lens/public/datatable_visualization/visualization.tsx b/x-pack/plugins/lens/public/datatable_visualization/visualization.tsx index 659f8ea12bcb0..5aff4e14b17f2 100644 --- a/x-pack/plugins/lens/public/datatable_visualization/visualization.tsx +++ b/x-pack/plugins/lens/public/datatable_visualization/visualization.tsx @@ -25,10 +25,7 @@ function newLayerState(layerId: string): LayerState { }; } -export const datatableVisualization: Visualization< - DatatableVisualizationState, - DatatableVisualizationState -> = { +export const datatableVisualization: Visualization = { id: 'lnsDatatable', visualizationTypes: [ @@ -75,8 +72,6 @@ export const datatableVisualization: Visualization< ); }, - getPersistableState: (state) => state, - getSuggestions({ table, state, @@ -186,9 +181,9 @@ export const datatableVisualization: Visualization< }; }, - toExpression(state, frame): Ast { + toExpression(state, datasourceLayers): Ast { const layer = state.layers[0]; - const datasource = frame.datasourceLayers[layer.layerId]; + const datasource = datasourceLayers[layer.layerId]; const originalOrder = datasource.getTableSpec().map(({ columnId }) => columnId); // When we add a column it could be empty, and therefore have no order const sortedColumns = Array.from(new Set(originalOrder.concat(layer.columns))); diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/__mocks__/expression_helpers.ts b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/__mocks__/expression_helpers.ts new file mode 100644 index 0000000000000..e0b3616315cbd --- /dev/null +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/__mocks__/expression_helpers.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { Ast } from '@kbn/interpreter/common'; + +export function buildExpression(): Ast { + return { + type: 'expression', + chain: [{ type: 'function', function: 'test', arguments: {} }], + }; +} diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx index 38224bf962a3f..b2804cfddba58 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx @@ -124,7 +124,6 @@ export function LayerPanel( const nextPublicAPI = layerDatasource.getPublicAPI({ state: newState, layerId, - dateRange: props.framePublicAPI.dateRange, }); const nextTable = new Set( nextPublicAPI.getTableSpec().map(({ columnId }) => columnId) diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.test.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.test.tsx index 2f7a78197b2b2..e628ea0675a8d 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.test.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.test.tsx @@ -170,25 +170,22 @@ describe('editor_frame', () => { doc={{ visualizationType: 'testVis', title: '', - expression: '', state: { datasourceStates: { testDatasource: datasource1State, testDatasource2: datasource2State, }, visualization: {}, - datasourceMetaData: { - filterableIndexPatterns: [], - }, query: { query: '', language: 'lucene' }, filters: [], }, + references: [], }} /> ); }); - expect(mockDatasource.initialize).toHaveBeenCalledWith(datasource1State); - expect(mockDatasource2.initialize).toHaveBeenCalledWith(datasource2State); + expect(mockDatasource.initialize).toHaveBeenCalledWith(datasource1State, []); + expect(mockDatasource2.initialize).toHaveBeenCalledWith(datasource2State, []); expect(mockDatasource3.initialize).not.toHaveBeenCalled(); }); @@ -425,21 +422,6 @@ describe('editor_frame', () => { "function": "kibana", "type": "function", }, - Object { - "arguments": Object { - "filters": Array [ - "[]", - ], - "query": Array [ - "{\\"query\\":\\"\\",\\"language\\":\\"lucene\\"}", - ], - "timeRange": Array [ - "{\\"from\\":\\"\\",\\"to\\":\\"\\"}", - ], - }, - "function": "kibana_context", - "type": "function", - }, Object { "arguments": Object { "layerIds": Array [ @@ -499,19 +481,16 @@ describe('editor_frame', () => { doc={{ visualizationType: 'testVis', title: '', - expression: '', state: { datasourceStates: { testDatasource: {}, testDatasource2: {}, }, visualization: {}, - datasourceMetaData: { - filterableIndexPatterns: [], - }, query: { query: '', language: 'lucene' }, filters: [], }, + references: [], }} /> ); @@ -535,21 +514,6 @@ describe('editor_frame', () => { "function": "kibana", "type": "function", }, - Object { - "arguments": Object { - "filters": Array [ - "[]", - ], - "query": Array [ - "{\\"query\\":\\"\\",\\"language\\":\\"lucene\\"}", - ], - "timeRange": Array [ - "{\\"from\\":\\"\\",\\"to\\":\\"\\"}", - ], - }, - "function": "kibana_context", - "type": "function", - }, Object { "arguments": Object { "layerIds": Array [ @@ -747,19 +711,16 @@ describe('editor_frame', () => { doc={{ visualizationType: 'testVis', title: '', - expression: '', state: { datasourceStates: { testDatasource: {}, testDatasource2: {}, }, visualization: {}, - datasourceMetaData: { - filterableIndexPatterns: [], - }, query: { query: '', language: 'lucene' }, filters: [], }, + references: [], }} /> ); @@ -802,19 +763,16 @@ describe('editor_frame', () => { doc={{ visualizationType: 'testVis', title: '', - expression: '', state: { datasourceStates: { testDatasource: datasource1State, testDatasource2: datasource2State, }, visualization: {}, - datasourceMetaData: { - filterableIndexPatterns: [], - }, query: { query: '', language: 'lucene' }, filters: [], }, + references: [], }} /> ); @@ -842,7 +800,6 @@ describe('editor_frame', () => { it('should give access to the datasource state in the datasource factory function', async () => { const datasourceState = {}; - const dateRange = { fromDate: 'now-1w', toDate: 'now' }; mockDatasource.initialize.mockResolvedValue(datasourceState); mockDatasource.getLayers.mockReturnValue(['first']); @@ -850,7 +807,6 @@ describe('editor_frame', () => { mount( { }); expect(mockDatasource.getPublicAPI).toHaveBeenCalledWith({ - dateRange, state: datasourceState, layerId: 'first', }); @@ -1460,9 +1415,10 @@ describe('editor_frame', () => { }) ); mockDatasource.getLayers.mockReturnValue(['first']); - mockDatasource.getMetaData.mockReturnValue({ - filterableIndexPatterns: [{ id: '1', title: 'resolved' }], - }); + mockDatasource.getPersistableState = jest.fn((x) => ({ + state: x, + savedObjectReferences: [{ type: 'index-pattern', id: '1', name: 'index-pattern-0' }], + })); mockVisualization.initialize.mockReturnValue({ initialState: true }); await act(async () => { @@ -1487,14 +1443,20 @@ describe('editor_frame', () => { expect(onChange).toHaveBeenCalledTimes(2); expect(onChange).toHaveBeenNthCalledWith(1, { - filterableIndexPatterns: [{ id: '1', title: 'resolved' }], + filterableIndexPatterns: ['1'], doc: { - expression: '', id: undefined, + description: undefined, + references: [ + { + id: '1', + name: 'index-pattern-0', + type: 'index-pattern', + }, + ], state: { visualization: null, // Not yet loaded - datasourceMetaData: { filterableIndexPatterns: [{ id: '1', title: 'resolved' }] }, - datasourceStates: { testDatasource: undefined }, + datasourceStates: { testDatasource: {} }, query: { query: '', language: 'lucene' }, filters: [], }, @@ -1502,18 +1464,23 @@ describe('editor_frame', () => { type: 'lens', visualizationType: 'testVis', }, + isSaveable: false, }); expect(onChange).toHaveBeenLastCalledWith({ - filterableIndexPatterns: [{ id: '1', title: 'resolved' }], + filterableIndexPatterns: ['1'], doc: { - expression: '', + references: [ + { + id: '1', + name: 'index-pattern-0', + type: 'index-pattern', + }, + ], + description: undefined, id: undefined, state: { visualization: { initialState: true }, // Now loaded - datasourceMetaData: { - filterableIndexPatterns: [{ id: '1', title: 'resolved' }], - }, - datasourceStates: { testDatasource: undefined }, + datasourceStates: { testDatasource: {} }, query: { query: '', language: 'lucene' }, filters: [], }, @@ -1521,6 +1488,7 @@ describe('editor_frame', () => { type: 'lens', visualizationType: 'testVis', }, + isSaveable: false, }); }); @@ -1562,11 +1530,10 @@ describe('editor_frame', () => { expect(onChange).toHaveBeenNthCalledWith(3, { filterableIndexPatterns: [], doc: { - expression: expect.stringContaining('vis "expression"'), id: undefined, + references: [], state: { - datasourceMetaData: { filterableIndexPatterns: [] }, - datasourceStates: { testDatasource: undefined }, + datasourceStates: { testDatasource: { datasource: '' } }, visualization: { initialState: true }, query: { query: 'new query', language: 'lucene' }, filters: [], @@ -1575,6 +1542,7 @@ describe('editor_frame', () => { type: 'lens', visualizationType: 'testVis', }, + isSaveable: true, }); }); @@ -1583,9 +1551,10 @@ describe('editor_frame', () => { mockDatasource.initialize.mockResolvedValue({}); mockDatasource.getLayers.mockReturnValue(['first']); - mockDatasource.getMetaData.mockReturnValue({ - filterableIndexPatterns: [{ id: '1', title: 'resolved' }], - }); + mockDatasource.getPersistableState = jest.fn((x) => ({ + state: x, + savedObjectReferences: [{ type: 'index-pattern', id: '1', name: '' }], + })); mockVisualization.initialize.mockReturnValue({ initialState: true }); await act(async () => { diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.tsx index 48a3511a8f359..72ad8e074226c 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.tsx @@ -7,13 +7,7 @@ import React, { useEffect, useReducer } from 'react'; import { CoreSetup, CoreStart } from 'kibana/public'; import { ReactExpressionRendererType } from '../../../../../../src/plugins/expressions/public'; -import { - Datasource, - DatasourcePublicAPI, - FramePublicAPI, - Visualization, - DatasourceMetaData, -} from '../../types'; +import { Datasource, FramePublicAPI, Visualization } from '../../types'; import { reducer, getInitialState } from './state_management'; import { DataPanelWrapper } from './data_panel_wrapper'; import { ConfigPanelWrapper } from './config_panel'; @@ -26,6 +20,7 @@ import { getSavedObjectFormat } from './save'; import { generateId } from '../../id_generator'; import { Filter, Query, SavedQuery } from '../../../../../../src/plugins/data/public'; import { EditorFrameStartPlugins } from '../service'; +import { initializeDatasources, createDatasourceLayers } from './state_helpers'; export interface EditorFrameProps { doc?: Document; @@ -45,8 +40,9 @@ export interface EditorFrameProps { filters: Filter[]; savedQuery?: SavedQuery; onChange: (arg: { - filterableIndexPatterns: DatasourceMetaData['filterableIndexPatterns']; + filterableIndexPatterns: string[]; doc: Document; + isSaveable: boolean; }) => void; showNoDataPopover: () => void; } @@ -67,25 +63,19 @@ export function EditorFrame(props: EditorFrameProps) { // prevents executing dispatch on unmounted component let isUnmounted = false; if (!allLoaded) { - Object.entries(props.datasourceMap).forEach(([datasourceId, datasource]) => { - if ( - state.datasourceStates[datasourceId] && - state.datasourceStates[datasourceId].isLoading - ) { - datasource - .initialize(state.datasourceStates[datasourceId].state || undefined) - .then((datasourceState) => { - if (!isUnmounted) { - dispatch({ - type: 'UPDATE_DATASOURCE_STATE', - updater: datasourceState, - datasourceId, - }); - } - }) - .catch(onError); - } - }); + initializeDatasources(props.datasourceMap, state.datasourceStates, props.doc?.references) + .then((result) => { + if (!isUnmounted) { + Object.entries(result).forEach(([datasourceId, { state: datasourceState }]) => { + dispatch({ + type: 'UPDATE_DATASOURCE_STATE', + updater: datasourceState, + datasourceId, + }); + }); + } + }) + .catch(onError); } return () => { isUnmounted = true; @@ -95,22 +85,7 @@ export function EditorFrame(props: EditorFrameProps) { [allLoaded, onError] ); - const datasourceLayers: Record = {}; - Object.keys(props.datasourceMap) - .filter((id) => state.datasourceStates[id] && !state.datasourceStates[id].isLoading) - .forEach((id) => { - const datasourceState = state.datasourceStates[id].state; - const datasource = props.datasourceMap[id]; - - const layers = datasource.getLayers(datasourceState); - layers.forEach((layer) => { - datasourceLayers[layer] = props.datasourceMap[id].getPublicAPI({ - state: datasourceState, - layerId: layer, - dateRange: props.dateRange, - }); - }); - }); + const datasourceLayers = createDatasourceLayers(props.datasourceMap, state.datasourceStates); const framePublicAPI: FramePublicAPI = { datasourceLayers, @@ -165,7 +140,18 @@ export function EditorFrame(props: EditorFrameProps) { if (props.doc) { dispatch({ type: 'VISUALIZATION_LOADED', - doc: props.doc, + doc: { + ...props.doc, + state: { + ...props.doc.state, + visualization: props.doc.visualizationType + ? props.visualizationMap[props.doc.visualizationType].initialize( + framePublicAPI, + props.doc.state.visualization + ) + : props.doc.state.visualization, + }, + }, }); } else { dispatch({ @@ -206,36 +192,20 @@ export function EditorFrame(props: EditorFrameProps) { return; } - const indexPatterns: DatasourceMetaData['filterableIndexPatterns'] = []; - Object.entries(props.datasourceMap) - .filter(([id, datasource]) => { - const stateWrapper = state.datasourceStates[id]; - return ( - stateWrapper && - !stateWrapper.isLoading && - datasource.getLayers(stateWrapper.state).length > 0 - ); + props.onChange( + getSavedObjectFormat({ + activeDatasources: Object.keys(state.datasourceStates).reduce( + (datasourceMap, datasourceId) => ({ + ...datasourceMap, + [datasourceId]: props.datasourceMap[datasourceId], + }), + {} + ), + visualization: activeVisualization, + state, + framePublicAPI, }) - .forEach(([id, datasource]) => { - indexPatterns.push( - ...datasource.getMetaData(state.datasourceStates[id].state).filterableIndexPatterns - ); - }); - - const doc = getSavedObjectFormat({ - activeDatasources: Object.keys(state.datasourceStates).reduce( - (datasourceMap, datasourceId) => ({ - ...datasourceMap, - [datasourceId]: props.datasourceMap[datasourceId], - }), - {} - ), - visualization: activeVisualization, - state, - framePublicAPI, - }); - - props.onChange({ filterableIndexPatterns: indexPatterns, doc }); + ); }, // eslint-disable-next-line react-hooks/exhaustive-deps [ diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/expression_helpers.ts b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/expression_helpers.ts index ee28ccfe1bf53..952718e13c8cf 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/expression_helpers.ts +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/expression_helpers.ts @@ -5,8 +5,7 @@ */ import { Ast, fromExpression, ExpressionFunctionAST } from '@kbn/interpreter/common'; -import { Visualization, Datasource, FramePublicAPI } from '../../types'; -import { Filter, TimeRange, Query } from '../../../../../../src/plugins/data/public'; +import { Visualization, Datasource, DatasourcePublicAPI } from '../../types'; export function prependDatasourceExpression( visualizationExpression: Ast | string | null, @@ -58,40 +57,12 @@ export function prependDatasourceExpression( ? fromExpression(visualizationExpression) : visualizationExpression; - return { - type: 'expression', - chain: [datafetchExpression, ...parsedVisualizationExpression.chain], - }; -} - -export function prependKibanaContext( - expression: Ast | string, - { - timeRange, - query, - filters, - }: { - timeRange?: TimeRange; - query?: Query; - filters?: Filter[]; - } -): Ast { - const parsedExpression = typeof expression === 'string' ? fromExpression(expression) : expression; - return { type: 'expression', chain: [ { type: 'function', function: 'kibana', arguments: {} }, - { - type: 'function', - function: 'kibana_context', - arguments: { - timeRange: timeRange ? [JSON.stringify(timeRange)] : [], - query: query ? [JSON.stringify(query)] : [], - filters: [JSON.stringify(filters || [])], - }, - }, - ...parsedExpression.chain, + datafetchExpression, + ...parsedVisualizationExpression.chain, ], }; } @@ -101,8 +72,7 @@ export function buildExpression({ visualizationState, datasourceMap, datasourceStates, - framePublicAPI, - removeDateRange, + datasourceLayers, }: { visualization: Visualization | null; visualizationState: unknown; @@ -114,24 +84,12 @@ export function buildExpression({ state: unknown; } >; - framePublicAPI: FramePublicAPI; - removeDateRange?: boolean; + datasourceLayers: Record; }): Ast | null { if (visualization === null) { return null; } - const visualizationExpression = visualization.toExpression(visualizationState, framePublicAPI); - - const expressionContext = removeDateRange - ? { query: framePublicAPI.query, filters: framePublicAPI.filters } - : { - query: framePublicAPI.query, - timeRange: { - from: framePublicAPI.dateRange.fromDate, - to: framePublicAPI.dateRange.toDate, - }, - filters: framePublicAPI.filters, - }; + const visualizationExpression = visualization.toExpression(visualizationState, datasourceLayers); const completeExpression = prependDatasourceExpression( visualizationExpression, @@ -139,9 +97,5 @@ export function buildExpression({ datasourceStates ); - if (completeExpression) { - return prependKibanaContext(completeExpression, expressionContext); - } else { - return null; - } + return completeExpression; } diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/save.test.ts b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/save.test.ts index d72e5c57ce56e..45d24fd30e2fc 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/save.test.ts +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/save.test.ts @@ -8,14 +8,18 @@ import { getSavedObjectFormat, Props } from './save'; import { createMockDatasource, createMockVisualization } from '../mocks'; import { esFilters, IIndexPattern, IFieldType } from '../../../../../../src/plugins/data/public'; +jest.mock('./expression_helpers'); + describe('save editor frame state', () => { const mockVisualization = createMockVisualization(); - mockVisualization.getPersistableState.mockImplementation((x) => x); const mockDatasource = createMockDatasource('a'); const mockIndexPattern = ({ id: 'indexpattern' } as unknown) as IIndexPattern; const mockField = ({ name: '@timestamp' } as unknown) as IFieldType; - mockDatasource.getPersistableState.mockImplementation((x) => x); + mockDatasource.getPersistableState.mockImplementation((x) => ({ + state: x, + savedObjectReferences: [], + })); const saveArgs: Props = { activeDatasources: { indexpattern: mockDatasource, @@ -47,15 +51,17 @@ describe('save editor frame state', () => { it('transforms from internal state to persisted doc format', async () => { const datasource = createMockDatasource('a'); datasource.getPersistableState.mockImplementation((state) => ({ - stuff: `${state}_datasource_persisted`, + state: { + stuff: `${state}_datasource_persisted`, + }, + savedObjectReferences: [], })); + datasource.toExpression.mockReturnValue('my | expr'); const visualization = createMockVisualization(); - visualization.getPersistableState.mockImplementation((state) => ({ - things: `${state}_vis_persisted`, - })); + visualization.toExpression.mockReturnValue('vis | expr'); - const doc = await getSavedObjectFormat({ + const { doc, filterableIndexPatterns, isSaveable } = await getSavedObjectFormat({ ...saveArgs, activeDatasources: { indexpattern: datasource, @@ -74,27 +80,32 @@ describe('save editor frame state', () => { visualization, }); + expect(filterableIndexPatterns).toEqual([]); + expect(isSaveable).toEqual(true); expect(doc).toEqual({ id: undefined, - expression: '', state: { - datasourceMetaData: { - filterableIndexPatterns: [], - }, datasourceStates: { indexpattern: { stuff: '2_datasource_persisted', }, }, - visualization: { things: '4_vis_persisted' }, + visualization: '4', query: { query: '', language: 'lucene' }, filters: [ { - meta: { index: 'indexpattern' }, + meta: { indexRefName: 'filter-index-pattern-0' }, exists: { field: '@timestamp' }, }, ], }, + references: [ + { + id: 'indexpattern', + name: 'filter-index-pattern-0', + type: 'index-pattern', + }, + ], title: 'bbb', type: 'lens', visualizationType: '3', diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/save.ts b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/save.ts index b41e93def966e..6da6d5a8c118f 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/save.ts +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/save.ts @@ -5,11 +5,12 @@ */ import _ from 'lodash'; -import { toExpression } from '@kbn/interpreter/target/common'; +import { SavedObjectReference } from 'kibana/public'; import { EditorFrameState } from './state_management'; import { Document } from '../../persistence/saved_object_store'; -import { buildExpression } from './expression_helpers'; import { Datasource, Visualization, FramePublicAPI } from '../../types'; +import { extractFilterReferences } from '../../persistence'; +import { buildExpression } from './expression_helpers'; export interface Props { activeDatasources: Record; @@ -23,43 +24,55 @@ export function getSavedObjectFormat({ state, visualization, framePublicAPI, -}: Props): Document { +}: Props): { + doc: Document; + filterableIndexPatterns: string[]; + isSaveable: boolean; +} { + const datasourceStates: Record = {}; + const references: SavedObjectReference[] = []; + Object.entries(activeDatasources).forEach(([id, datasource]) => { + const { state: persistableState, savedObjectReferences } = datasource.getPersistableState( + state.datasourceStates[id].state + ); + datasourceStates[id] = persistableState; + references.push(...savedObjectReferences); + }); + + const uniqueFilterableIndexPatternIds = _.uniq( + references.filter(({ type }) => type === 'index-pattern').map(({ id }) => id) + ); + + const { persistableFilters, references: filterReferences } = extractFilterReferences( + framePublicAPI.filters + ); + + references.push(...filterReferences); + const expression = buildExpression({ visualization, visualizationState: state.visualization.state, datasourceMap: activeDatasources, datasourceStates: state.datasourceStates, - framePublicAPI, - removeDateRange: true, - }); - - const datasourceStates: Record = {}; - Object.entries(activeDatasources).forEach(([id, datasource]) => { - datasourceStates[id] = datasource.getPersistableState(state.datasourceStates[id].state); - }); - - const filterableIndexPatterns: Array<{ id: string; title: string }> = []; - Object.entries(activeDatasources).forEach(([id, datasource]) => { - filterableIndexPatterns.push( - ...datasource.getMetaData(state.datasourceStates[id].state).filterableIndexPatterns - ); + datasourceLayers: framePublicAPI.datasourceLayers, }); return { - id: state.persistedId, - title: state.title, - description: state.description, - type: 'lens', - visualizationType: state.visualization.activeId, - expression: expression ? toExpression(expression) : '', - state: { - datasourceStates, - datasourceMetaData: { - filterableIndexPatterns: _.uniqBy(filterableIndexPatterns, 'id'), + doc: { + id: state.persistedId, + title: state.title, + description: state.description, + type: 'lens', + visualizationType: state.visualization.activeId, + state: { + datasourceStates, + visualization: state.visualization.state, + query: framePublicAPI.query, + filters: persistableFilters, }, - visualization: visualization.getPersistableState(state.visualization.state), - query: framePublicAPI.query, - filters: framePublicAPI.filters, + references, }, + filterableIndexPatterns: uniqueFilterableIndexPatternIds, + isSaveable: expression !== null, }; } diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/state_helpers.ts b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/state_helpers.ts new file mode 100644 index 0000000000000..6deb9ffd37a06 --- /dev/null +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/state_helpers.ts @@ -0,0 +1,87 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { SavedObjectReference } from 'kibana/public'; +import { Ast } from '@kbn/interpreter/common'; +import { Datasource, DatasourcePublicAPI, Visualization } from '../../types'; +import { buildExpression } from './expression_helpers'; +import { Document } from '../../persistence/saved_object_store'; + +export async function initializeDatasources( + datasourceMap: Record, + datasourceStates: Record, + references?: SavedObjectReference[] +) { + const states: Record = {}; + await Promise.all( + Object.entries(datasourceMap).map(([datasourceId, datasource]) => { + if (datasourceStates[datasourceId]) { + return datasource + .initialize(datasourceStates[datasourceId].state || undefined, references) + .then((datasourceState) => { + states[datasourceId] = { isLoading: false, state: datasourceState }; + }); + } + }) + ); + return states; +} + +export function createDatasourceLayers( + datasourceMap: Record, + datasourceStates: Record +) { + const datasourceLayers: Record = {}; + Object.keys(datasourceMap) + .filter((id) => datasourceStates[id] && !datasourceStates[id].isLoading) + .forEach((id) => { + const datasourceState = datasourceStates[id].state; + const datasource = datasourceMap[id]; + + const layers = datasource.getLayers(datasourceState); + layers.forEach((layer) => { + datasourceLayers[layer] = datasourceMap[id].getPublicAPI({ + state: datasourceState, + layerId: layer, + }); + }); + }); + return datasourceLayers; +} + +export async function persistedStateToExpression( + datasources: Record, + visualizations: Record, + doc: Document +): Promise { + const { + state: { visualization: visualizationState, datasourceStates: persistedDatasourceStates }, + visualizationType, + references, + } = doc; + if (!visualizationType) return null; + const visualization = visualizations[visualizationType!]; + const datasourceStates = await initializeDatasources( + datasources, + Object.fromEntries( + Object.entries(persistedDatasourceStates).map(([id, state]) => [ + id, + { isLoading: false, state }, + ]) + ), + references + ); + + const datasourceLayers = createDatasourceLayers(datasources, datasourceStates); + + return buildExpression({ + visualization, + visualizationState, + datasourceMap: datasources, + datasourceStates, + datasourceLayers, + }); +} diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/state_management.test.ts b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/state_management.test.ts index 969467b5789ec..c7f505aeca517 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/state_management.test.ts +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/state_management.test.ts @@ -57,19 +57,16 @@ describe('editor_frame state management', () => { const initialState = getInitialState({ ...props, doc: { - expression: '', state: { datasourceStates: { testDatasource: { internalState1: '' }, testDatasource2: { internalState2: '' }, }, visualization: {}, - datasourceMetaData: { - filterableIndexPatterns: [], - }, query: { query: '', language: 'lucene' }, filters: [], }, + references: [], title: '', visualizationType: 'testVis', }, @@ -380,9 +377,7 @@ describe('editor_frame state management', () => { type: 'VISUALIZATION_LOADED', doc: { id: 'b', - expression: '', state: { - datasourceMetaData: { filterableIndexPatterns: [] }, datasourceStates: { a: { foo: 'c' } }, visualization: { bar: 'd' }, query: { query: '', language: 'lucene' }, @@ -392,6 +387,7 @@ describe('editor_frame state management', () => { description: 'My lens', type: 'lens', visualizationType: 'line', + references: [], }, } ); diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_helpers.ts b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_helpers.ts index 263f7cd65f43d..2bb1baf9d54f2 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_helpers.ts +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_helpers.ts @@ -107,7 +107,7 @@ export function getSuggestions({ * title and preview expression. */ function getVisualizationSuggestions( - visualization: Visualization, + visualization: Visualization, table: TableSuggestion, visualizationId: string, datasourceSuggestion: DatasourceSuggestion & { datasourceId: string }, diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.test.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.test.tsx index fd509c0046e13..323472d717352 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.test.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.test.tsx @@ -249,7 +249,6 @@ describe('suggestion_panel', () => { expect(passedExpression).toMatchInlineSnapshot(` "kibana - | kibana_context timeRange=\\"{\\\\\\"from\\\\\\":\\\\\\"now-7d\\\\\\",\\\\\\"to\\\\\\":\\\\\\"now\\\\\\"}\\" query=\\"{\\\\\\"query\\\\\\":\\\\\\"\\\\\\",\\\\\\"language\\\\\\":\\\\\\"lucene\\\\\\"}\\" filters=\\"[{\\\\\\"meta\\\\\\":{\\\\\\"index\\\\\\":\\\\\\"index1\\\\\\"},\\\\\\"exists\\\\\\":{\\\\\\"field\\\\\\":\\\\\\"myfield\\\\\\"}}]\\" | lens_merge_tables layerIds=\\"first\\" tables={datasource_expression} | test | expression" diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx index 7395075cf9f74..f1dc3fa306d15 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx @@ -21,6 +21,7 @@ import { IconType } from '@elastic/eui/src/components/icon/icon'; import { Ast, toExpression } from '@kbn/interpreter/common'; import { i18n } from '@kbn/i18n'; import classNames from 'classnames'; +import { ExecutionContextSearch } from 'src/plugins/expressions'; import { Action, PreviewState } from './state_management'; import { Datasource, Visualization, FramePublicAPI, DatasourcePublicAPI } from '../../types'; import { getSuggestions, switchToSuggestion } from './suggestion_helpers'; @@ -28,7 +29,7 @@ import { ReactExpressionRendererProps, ReactExpressionRendererType, } from '../../../../../../src/plugins/expressions/public'; -import { prependDatasourceExpression, prependKibanaContext } from './expression_helpers'; +import { prependDatasourceExpression } from './expression_helpers'; import { debouncedComponent } from '../../debounced_component'; import { trackUiEvent, trackSuggestionEvent } from '../../lens_ui_telemetry'; import { DataPublicPluginStart } from '../../../../../../src/plugins/data/public'; @@ -112,7 +113,7 @@ const SuggestionPreview = ({ }: { onSelect: () => void; preview: { - expression?: Ast; + expression?: Ast | null; icon: IconType; title: string; }; @@ -215,12 +216,24 @@ export function SuggestionPanel({ visualizationMap, ]); + const context: ExecutionContextSearch = useMemo( + () => ({ + query: frame.query, + timeRange: { + from: frame.dateRange.fromDate, + to: frame.dateRange.toDate, + }, + filters: frame.filters, + }), + [frame.query, frame.dateRange.fromDate, frame.dateRange.toDate, frame.filters] + ); + const AutoRefreshExpressionRenderer = useMemo(() => { const autoRefreshFetch$ = plugins.data.query.timefilter.timefilter.getAutoRefreshFetch$(); return (props: ReactExpressionRendererProps) => ( - + ); - }, [plugins.data.query.timefilter.timefilter]); + }, [plugins.data.query.timefilter.timefilter, context]); const [lastSelectedSuggestion, setLastSelectedSuggestion] = useState(-1); @@ -252,15 +265,6 @@ export function SuggestionPanel({ } } - const expressionContext = { - query: frame.query, - filters: frame.filters, - timeRange: { - from: frame.dateRange.fromDate, - to: frame.dateRange.toDate, - }, - }; - return (

@@ -305,9 +309,7 @@ export function SuggestionPanel({ {currentVisualizationId && ( , + newVisualization: Visualization, subVisualizationId?: string ): Suggestion | undefined { const unfilteredSuggestions = getSuggestions({ diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.test.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.test.tsx index a9c638df8cad1..47e3b41df3b21 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.test.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.test.tsx @@ -172,21 +172,6 @@ describe('workspace_panel', () => { "function": "kibana", "type": "function", }, - Object { - "arguments": Object { - "filters": Array [ - "[]", - ], - "query": Array [ - "{\\"query\\":\\"\\",\\"language\\":\\"lucene\\"}", - ], - "timeRange": Array [ - "{\\"from\\":\\"now-7d\\",\\"to\\":\\"now\\"}", - ], - }, - "function": "kibana_context", - "type": "function", - }, Object { "arguments": Object { "layerIds": Array [ @@ -305,10 +290,10 @@ describe('workspace_panel', () => { ); expect( - (instance.find(expressionRendererMock).prop('expression') as Ast).chain[2].arguments.layerIds + (instance.find(expressionRendererMock).prop('expression') as Ast).chain[1].arguments.layerIds ).toEqual(['first', 'second', 'third']); expect( - (instance.find(expressionRendererMock).prop('expression') as Ast).chain[2].arguments.tables + (instance.find(expressionRendererMock).prop('expression') as Ast).chain[1].arguments.tables ).toMatchInlineSnapshot(` Array [ Object { diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx index b3a12271f377b..4f914bc65dc7c 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx @@ -18,6 +18,7 @@ import { EuiLink, } from '@elastic/eui'; import { CoreStart, CoreSetup } from 'kibana/public'; +import { ExecutionContextSearch } from 'src/plugins/expressions'; import { ExpressionRendererEvent, ReactExpressionRendererType, @@ -129,7 +130,7 @@ export function InnerWorkspacePanel({ visualizationState, datasourceMap, datasourceStates, - framePublicAPI, + datasourceLayers: framePublicAPI.datasourceLayers, }); } catch (e) { // Most likely an error in the expression provided by a datasource or visualization @@ -173,6 +174,23 @@ export function InnerWorkspacePanel({ [plugins.data.query.timefilter.timefilter] ); + const context: ExecutionContextSearch = useMemo( + () => ({ + query: framePublicAPI.query, + timeRange: { + from: framePublicAPI.dateRange.fromDate, + to: framePublicAPI.dateRange.toDate, + }, + filters: framePublicAPI.filters, + }), + [ + framePublicAPI.query, + framePublicAPI.dateRange.fromDate, + framePublicAPI.dateRange.toDate, + framePublicAPI.filters, + ] + ); + useEffect(() => { // reset expression error if component attempts to run it again if (expression && localState.expressionBuildError) { @@ -264,6 +282,7 @@ export function InnerWorkspacePanel({ className="lnsExpressionRenderer__component" padding="m" expression={expression!} + searchContext={context} reload$={autoRefreshFetch$} onEvent={onEvent} renderError={(errorMessage?: string | null) => { diff --git a/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.test.tsx b/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.test.tsx index 69447b3b9a9b8..1e2df28cad7b1 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.test.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.test.tsx @@ -18,16 +18,13 @@ jest.mock('../../../../../../src/plugins/inspector/public/', () => ({ })); const savedVis: Document = { - expression: 'my | expression', state: { visualization: {}, datasourceStates: {}, - datasourceMetaData: { - filterableIndexPatterns: [], - }, query: { query: '', language: 'lucene' }, filters: [], }, + references: [], title: 'My title', visualizationType: '', }; @@ -59,13 +56,14 @@ describe('embeddable', () => { editUrl: '', editable: true, savedVis, + expression: 'my | expression', }, { id: '123' } ); embeddable.render(mountpoint); expect(expressionRenderer).toHaveBeenCalledTimes(1); - expect(expressionRenderer.mock.calls[0][0]!.expression).toEqual(savedVis.expression); + expect(expressionRenderer.mock.calls[0][0]!.expression).toEqual('my | expression'); }); it('should re-render if new input is pushed', () => { @@ -82,6 +80,7 @@ describe('embeddable', () => { editUrl: '', editable: true, savedVis, + expression: 'my | expression', }, { id: '123' } ); @@ -110,6 +109,7 @@ describe('embeddable', () => { editUrl: '', editable: true, savedVis, + expression: 'my | expression', }, { id: '123', timeRange, query, filters } ); @@ -117,11 +117,52 @@ describe('embeddable', () => { expect(expressionRenderer.mock.calls[0][0].searchContext).toEqual({ timeRange, - query, + query: [query, savedVis.state.query], filters, }); }); + it('should merge external context with query and filters of the saved object', () => { + const timeRange: TimeRange = { from: 'now-15d', to: 'now' }; + const query: Query = { language: 'kquery', query: 'external filter' }; + const filters: Filter[] = [{ meta: { alias: 'test', negate: false, disabled: false } }]; + + const embeddable = new Embeddable( + dataPluginMock.createSetupContract().query.timefilter.timefilter, + expressionRenderer, + getTrigger, + { + editPath: '', + editUrl: '', + editable: true, + savedVis: { + ...savedVis, + state: { + ...savedVis.state, + query: { language: 'kquery', query: 'saved filter' }, + filters: [ + { meta: { alias: 'test', negate: false, disabled: false, indexRefName: 'filter-0' } }, + ], + }, + references: [{ type: 'index-pattern', name: 'filter-0', id: 'my-index-pattern-id' }], + }, + expression: 'my | expression', + }, + { id: '123', timeRange, query, filters } + ); + embeddable.render(mountpoint); + + expect(expressionRenderer.mock.calls[0][0].searchContext).toEqual({ + timeRange, + query: [query, { language: 'kquery', query: 'saved filter' }], + filters: [ + filters[0], + // actual index pattern id gets injected + { meta: { alias: 'test', negate: false, disabled: false, index: 'my-index-pattern-id' } }, + ], + }); + }); + it('should execute trigger on event from expression renderer', () => { const embeddable = new Embeddable( dataPluginMock.createSetupContract().query.timefilter.timefilter, @@ -132,6 +173,7 @@ describe('embeddable', () => { editUrl: '', editable: true, savedVis, + expression: 'my | expression', }, { id: '123' } ); @@ -162,6 +204,7 @@ describe('embeddable', () => { editUrl: '', editable: true, savedVis, + expression: 'my | expression', }, { id: '123', timeRange, query, filters } ); @@ -195,6 +238,7 @@ describe('embeddable', () => { editUrl: '', editable: true, savedVis, + expression: 'my | expression', }, { id: '123', timeRange, query, filters } ); diff --git a/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.tsx b/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.tsx index bbd2b18907e9b..4df218a3e94e9 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.tsx @@ -14,6 +14,7 @@ import { TimefilterContract, TimeRange, } from 'src/plugins/data/public'; +import { ExecutionContextSearch } from 'src/plugins/expressions'; import { Subscription } from 'rxjs'; import { @@ -28,12 +29,13 @@ import { EmbeddableOutput, IContainer, } from '../../../../../../src/plugins/embeddable/public'; -import { DOC_TYPE, Document } from '../../persistence'; +import { DOC_TYPE, Document, injectFilterReferences } from '../../persistence'; import { ExpressionWrapper } from './expression_wrapper'; import { UiActionsStart } from '../../../../../../src/plugins/ui_actions/public'; import { isLensBrushEvent, isLensFilterEvent } from '../../types'; export interface LensEmbeddableConfiguration { + expression: string | null; savedVis: Document; editUrl: string; editPath: string; @@ -56,12 +58,13 @@ export class Embeddable extends AbstractEmbeddable this.onContainerStateChanged(input)); this.onContainerStateChanged(initialInput); @@ -122,14 +133,14 @@ export class Embeddable extends AbstractEmbeddable !filter.meta.disabled) : undefined; if ( - !_.isEqual(containerState.timeRange, this.currentContext.timeRange) || - !_.isEqual(containerState.query, this.currentContext.query) || - !_.isEqual(cleanedFilters, this.currentContext.filters) + !_.isEqual(containerState.timeRange, this.externalSearchContext.timeRange) || + !_.isEqual(containerState.query, this.externalSearchContext.query) || + !_.isEqual(cleanedFilters, this.externalSearchContext.filters) ) { - this.currentContext = { + this.externalSearchContext = { timeRange: containerState.timeRange, query: containerState.query, - lastReloadRequestTime: this.currentContext.lastReloadRequestTime, + lastReloadRequestTime: this.externalSearchContext.lastReloadRequestTime, filters: cleanedFilters, }; @@ -149,14 +160,37 @@ export class Embeddable extends AbstractEmbeddable, domNode ); } + /** + * Combines the embeddable context with the saved object context, and replaces + * any references to index patterns + */ + private getMergedSearchContext(): ExecutionContextSearch { + const output: ExecutionContextSearch = { + timeRange: this.externalSearchContext.timeRange, + }; + if (this.externalSearchContext.query) { + output.query = [this.externalSearchContext.query, this.savedVis.state.query]; + } else { + output.query = [this.savedVis.state.query]; + } + if (this.externalSearchContext.filters?.length) { + output.filters = [...this.externalSearchContext.filters, ...this.savedVis.state.filters]; + } else { + output.filters = [...this.savedVis.state.filters]; + } + + output.filters = injectFilterReferences(output.filters, this.savedVis.references); + return output; + } + handleEvent = (event: ExpressionRendererEvent) => { if (!this.getTrigger || this.input.disableTriggers) { return; @@ -188,9 +222,9 @@ export class Embeddable extends AbstractEmbeddable Promise; } export class EmbeddableFactory implements EmbeddableFactoryDefinition { @@ -72,13 +75,15 @@ export class EmbeddableFactory implements EmbeddableFactoryDefinition { indexPatternService, timefilter, expressionRenderer, + documentToExpression, uiActions, } = await this.getStartServices(); const store = new SavedObjectIndexStore(savedObjectsClient); const savedVis = await store.load(savedObjectId); - const promises = savedVis.state.datasourceMetaData.filterableIndexPatterns.map( - async ({ id }) => { + const promises = savedVis.references + .filter(({ type }) => type === 'index-pattern') + .map(async ({ id }) => { try { return await indexPatternService.get(id); } catch (error) { @@ -87,14 +92,15 @@ export class EmbeddableFactory implements EmbeddableFactoryDefinition { // to show. return null; } - } - ); + }); const indexPatterns = ( await Promise.all(promises) ).filter((indexPattern: IndexPattern | null): indexPattern is IndexPattern => Boolean(indexPattern) ); + const expression = await documentToExpression(savedVis); + return new Embeddable( timefilter, expressionRenderer, @@ -105,6 +111,7 @@ export class EmbeddableFactory implements EmbeddableFactoryDefinition { editUrl: coreHttp.basePath.prepend(`/app/lens${getEditPath(savedObjectId)}`), editable: await this.isEditable(), indexPatterns, + expression: expression ? toExpression(expression) : null, }, input, parent diff --git a/x-pack/plugins/lens/public/editor_frame_service/embeddable/expression_wrapper.tsx b/x-pack/plugins/lens/public/editor_frame_service/embeddable/expression_wrapper.tsx index 296dcef3e70b9..d0d2360ddc107 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/embeddable/expression_wrapper.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/embeddable/expression_wrapper.tsx @@ -8,28 +8,23 @@ import React from 'react'; import { I18nProvider } from '@kbn/i18n/react'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiFlexGroup, EuiFlexItem, EuiText, EuiIcon } from '@elastic/eui'; -import { TimeRange, Filter, Query } from 'src/plugins/data/public'; import { ExpressionRendererEvent, ReactExpressionRendererType, } from 'src/plugins/expressions/public'; +import { ExecutionContextSearch } from 'src/plugins/expressions'; export interface ExpressionWrapperProps { ExpressionRenderer: ReactExpressionRendererType; expression: string | null; - context: { - timeRange?: TimeRange; - query?: Query; - filters?: Filter[]; - lastReloadRequestTime?: number; - }; + searchContext: ExecutionContextSearch; handleEvent: (event: ExpressionRendererEvent) => void; } export function ExpressionWrapper({ ExpressionRenderer: ExpressionRendererComponent, expression, - context, + searchContext, handleEvent, }: ExpressionWrapperProps) { return ( @@ -54,7 +49,7 @@ export function ExpressionWrapper({ className="lnsExpressionRenderer__component" padding="m" expression={expression} - searchContext={{ ...context }} + searchContext={searchContext} renderError={(error) =>
{error}
} onEvent={handleEvent} /> diff --git a/x-pack/plugins/lens/public/editor_frame_service/mocks.tsx b/x-pack/plugins/lens/public/editor_frame_service/mocks.tsx index 9c0825b3c2d27..86b137851d9bd 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/mocks.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/mocks.tsx @@ -31,7 +31,6 @@ export function createMockVisualization(): jest.Mocked { getVisualizationTypeId: jest.fn((_state) => 'empty'), getDescription: jest.fn((_state) => ({ label: '' })), switchVisualizationType: jest.fn((_, x) => x), - getPersistableState: jest.fn((_state) => _state), getSuggestions: jest.fn((_options) => []), initialize: jest.fn((_frame, _state?) => ({})), getConfiguration: jest.fn((props) => ({ @@ -71,7 +70,7 @@ export function createMockDatasource(id: string): DatasourceMock { clearLayer: jest.fn((state, _layerId) => state), getDatasourceSuggestionsForField: jest.fn((_state, _item) => []), getDatasourceSuggestionsFromCurrentState: jest.fn((_state) => []), - getPersistableState: jest.fn(), + getPersistableState: jest.fn((x) => ({ state: x, savedObjectReferences: [] })), getPublicAPI: jest.fn().mockReturnValue(publicAPIMock), initialize: jest.fn((_state?) => Promise.resolve()), renderDataPanel: jest.fn(), @@ -81,7 +80,6 @@ export function createMockDatasource(id: string): DatasourceMock { removeLayer: jest.fn((_state, _layerId) => {}), removeColumn: jest.fn((props) => {}), getLayers: jest.fn((_state) => []), - getMetaData: jest.fn((_state) => ({ filterableIndexPatterns: [] })), renderDimensionTrigger: jest.fn(), renderDimensionEditor: jest.fn(), diff --git a/x-pack/plugins/lens/public/editor_frame_service/service.tsx b/x-pack/plugins/lens/public/editor_frame_service/service.tsx index 47339373b6d1a..5fc347179a032 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/service.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/service.tsx @@ -21,12 +21,14 @@ import { EditorFrameInstance, EditorFrameStart, } from '../types'; +import { Document } from '../persistence/saved_object_store'; import { EditorFrame } from './editor_frame'; import { mergeTables } from './merge_tables'; import { formatColumn } from './format_column'; import { EmbeddableFactory } from './embeddable/embeddable_factory'; import { getActiveDatasourceIdFromDoc } from './editor_frame/state_management'; import { UiActionsStart } from '../../../../../src/plugins/ui_actions/public'; +import { persistedStateToExpression } from './editor_frame/state_helpers'; export interface EditorFrameSetupPlugins { data: DataPublicPluginSetup; @@ -59,6 +61,21 @@ export class EditorFrameService { private readonly datasources: Array> = []; private readonly visualizations: Array> = []; + /** + * This method takes a Lens saved object as returned from the persistence helper, + * initializes datsources and visualization and creates the current expression. + * This is an asynchronous process and should only be triggered once for a saved object. + * @param doc parsed Lens saved object + */ + private async documentToExpression(doc: Document) { + const [resolvedDatasources, resolvedVisualizations] = await Promise.all([ + collectAsyncDefinitions(this.datasources), + collectAsyncDefinitions(this.visualizations), + ]); + + return await persistedStateToExpression(resolvedDatasources, resolvedVisualizations, doc); + } + public setup( core: CoreSetup, plugins: EditorFrameSetupPlugins @@ -74,6 +91,7 @@ export class EditorFrameService { coreHttp: coreStart.http, timefilter: deps.data.query.timefilter.timefilter, expressionRenderer: deps.expressions.ReactExpressionRenderer, + documentToExpression: this.documentToExpression.bind(this), indexPatternService: deps.data.indexPatterns, uiActions: deps.uiActions, }; @@ -88,7 +106,7 @@ export class EditorFrameService { this.datasources.push(datasource as Datasource); }, registerVisualization: (visualization) => { - this.visualizations.push(visualization as Visualization); + this.visualizations.push(visualization as Visualization); }, }; } diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/__mocks__/loader.ts b/x-pack/plugins/lens/public/indexpattern_datasource/__mocks__/loader.ts index ca5fe706985f8..c487e31f5a973 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/__mocks__/loader.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/__mocks__/loader.ts @@ -23,3 +23,7 @@ export function loadInitialState() { }; return result; } + +const originalLoader = jest.requireActual('../loader'); + +export const extractReferences = originalLoader.extractReferences; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.test.ts b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.test.ts index dc3938ce436e5..0ba7b7df97853 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.test.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.test.ts @@ -128,12 +128,15 @@ const expectedIndexPatterns = { }, }; -function stateFromPersistedState( - persistedState: IndexPatternPersistedState -): IndexPatternPrivateState { +type IndexPatternBaseState = Omit< + IndexPatternPrivateState, + 'indexPatternRefs' | 'indexPatterns' | 'existingFields' | 'isFirstExistenceFetch' +>; + +function enrichBaseState(baseState: IndexPatternBaseState): IndexPatternPrivateState { return { - currentIndexPatternId: persistedState.currentIndexPatternId, - layers: persistedState.layers, + currentIndexPatternId: baseState.currentIndexPatternId, + layers: baseState.layers, indexPatterns: expectedIndexPatterns, indexPatternRefs: [], existingFields: {}, @@ -142,7 +145,10 @@ function stateFromPersistedState( } describe('IndexPattern Data Source', () => { - let persistedState: IndexPatternPersistedState; + let baseState: Omit< + IndexPatternPrivateState, + 'indexPatternRefs' | 'indexPatterns' | 'existingFields' | 'isFirstExistenceFetch' + >; let indexPatternDatasource: Datasource; beforeEach(() => { @@ -153,7 +159,7 @@ describe('IndexPattern Data Source', () => { charts: chartPluginMock.createSetupContract(), }); - persistedState = { + baseState = { currentIndexPatternId: '1', layers: { first: { @@ -224,9 +230,37 @@ describe('IndexPattern Data Source', () => { describe('#getPersistedState', () => { it('should persist from saved state', async () => { - const state = stateFromPersistedState(persistedState); + const state = enrichBaseState(baseState); - expect(indexPatternDatasource.getPersistableState(state)).toEqual(persistedState); + expect(indexPatternDatasource.getPersistableState(state)).toEqual({ + state: { + layers: { + first: { + columnOrder: ['col1'], + columns: { + col1: { + label: 'My Op', + dataType: 'string', + isBucketed: true, + + // Private + operationType: 'terms', + sourceField: 'op', + params: { + size: 5, + orderBy: { type: 'alphabetical' }, + orderDirection: 'asc', + }, + }, + }, + }, + }, + }, + savedObjectReferences: [ + { name: 'indexpattern-datasource-current-indexpattern', type: 'index-pattern', id: '1' }, + { name: 'indexpattern-datasource-layer-first', type: 'index-pattern', id: '1' }, + ], + }); }); }); @@ -237,7 +271,7 @@ describe('IndexPattern Data Source', () => { }); it('should generate an expression for an aggregated query', async () => { - const queryPersistedState: IndexPatternPersistedState = { + const queryBaseState: IndexPatternBaseState = { currentIndexPatternId: '1', layers: { first: { @@ -266,7 +300,7 @@ describe('IndexPattern Data Source', () => { }, }; - const state = stateFromPersistedState(queryPersistedState); + const state = enrichBaseState(queryBaseState); expect(indexPatternDatasource.toExpression(state, 'first')).toMatchInlineSnapshot(` Object { @@ -311,7 +345,7 @@ describe('IndexPattern Data Source', () => { }); it('should put all time fields used in date_histograms to the esaggs timeFields parameter', async () => { - const queryPersistedState: IndexPatternPersistedState = { + const queryBaseState: IndexPatternBaseState = { currentIndexPatternId: '1', layers: { first: { @@ -350,14 +384,14 @@ describe('IndexPattern Data Source', () => { }, }; - const state = stateFromPersistedState(queryPersistedState); + const state = enrichBaseState(queryBaseState); const ast = indexPatternDatasource.toExpression(state, 'first') as Ast; expect(ast.chain[0].arguments.timeFields).toEqual(['timestamp', 'another_datefield']); }); it('should not put date fields used outside date_histograms to the esaggs timeFields parameter', async () => { - const queryPersistedState: IndexPatternPersistedState = { + const queryBaseState: IndexPatternBaseState = { currentIndexPatternId: '1', layers: { first: { @@ -386,7 +420,7 @@ describe('IndexPattern Data Source', () => { }, }; - const state = stateFromPersistedState(queryPersistedState); + const state = enrichBaseState(queryBaseState); const ast = indexPatternDatasource.toExpression(state, 'first') as Ast; expect(ast.chain[0].arguments.timeFields).toEqual(['timestamp']); @@ -489,55 +523,14 @@ describe('IndexPattern Data Source', () => { }); }); - describe('#getMetadata', () => { - it('should return the title of the index patterns', () => { - expect( - indexPatternDatasource.getMetaData({ - indexPatternRefs: [], - existingFields: {}, - isFirstExistenceFetch: false, - indexPatterns: expectedIndexPatterns, - layers: { - first: { - indexPatternId: '1', - columnOrder: [], - columns: {}, - }, - second: { - indexPatternId: '2', - columnOrder: [], - columns: {}, - }, - }, - currentIndexPatternId: '1', - }) - ).toEqual({ - filterableIndexPatterns: [ - { - id: '1', - title: 'my-fake-index-pattern', - }, - { - id: '2', - title: 'my-fake-restricted-pattern', - }, - ], - }); - }); - }); - describe('#getPublicAPI', () => { let publicAPI: DatasourcePublicAPI; beforeEach(async () => { - const initialState = stateFromPersistedState(persistedState); + const initialState = enrichBaseState(baseState); publicAPI = indexPatternDatasource.getPublicAPI({ state: initialState, layerId: 'first', - dateRange: { - fromDate: 'now-30d', - toDate: 'now', - }, }); }); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.tsx index 2fb8d7fe0e553..e2ca933504849 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.tsx @@ -8,7 +8,7 @@ import _ from 'lodash'; import React from 'react'; import { render } from 'react-dom'; import { I18nProvider } from '@kbn/i18n/react'; -import { CoreStart } from 'kibana/public'; +import { CoreStart, SavedObjectReference } from 'kibana/public'; import { i18n } from '@kbn/i18n'; import { IStorageWrapper } from 'src/plugins/kibana_utils/public'; import { @@ -19,7 +19,12 @@ import { DatasourceLayerPanelProps, PublicAPIProps, } from '../types'; -import { loadInitialState, changeIndexPattern, changeLayerIndexPattern } from './loader'; +import { + loadInitialState, + changeIndexPattern, + changeLayerIndexPattern, + extractReferences, +} from './loader'; import { toExpression } from './to_expression'; import { IndexPatternDimensionTrigger, @@ -125,9 +130,13 @@ export function getIndexPatternDatasource({ const indexPatternDatasource: Datasource = { id: 'indexpattern', - async initialize(state?: IndexPatternPersistedState) { + async initialize( + persistedState?: IndexPatternPersistedState, + references?: SavedObjectReference[] + ) { return loadInitialState({ - state, + persistedState, + references, savedObjectsClient: await savedObjectsClient, defaultIndexPatternId: core.uiSettings.get('defaultIndex'), storage, @@ -135,8 +144,8 @@ export function getIndexPatternDatasource({ }); }, - getPersistableState({ currentIndexPatternId, layers }: IndexPatternPrivateState) { - return { currentIndexPatternId, layers }; + getPersistableState(state: IndexPatternPrivateState) { + return extractReferences(state); }, insertLayer(state: IndexPatternPrivateState, newLayerId: string) { @@ -183,19 +192,6 @@ export function getIndexPatternDatasource({ toExpression, - getMetaData(state: IndexPatternPrivateState) { - return { - filterableIndexPatterns: _.uniq( - Object.values(state.layers) - .map((layer) => layer.indexPatternId) - .map((indexPatternId) => ({ - id: indexPatternId, - title: state.indexPatterns[indexPatternId].title, - })) - ), - }; - }, - renderDataPanel( domElement: Element, props: DatasourceDataPanelProps diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/loader.test.ts b/x-pack/plugins/lens/public/indexpattern_datasource/loader.test.ts index cfabcb4edcef7..d80bf779a5d17 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/loader.test.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/loader.test.ts @@ -12,6 +12,8 @@ import { changeIndexPattern, changeLayerIndexPattern, syncExistingFields, + extractReferences, + injectReferences, } from './loader'; import { IndexPatternsContract } from '../../../../../src/plugins/data/public'; import { @@ -378,10 +380,8 @@ describe('loader', () => { it('should initialize from saved state', async () => { const savedState: IndexPatternPersistedState = { - currentIndexPatternId: '2', layers: { layerb: { - indexPatternId: '2', columnOrder: ['col1', 'col2'], columns: { col1: { @@ -407,7 +407,12 @@ describe('loader', () => { }; const storage = createMockStorage({ indexPatternId: '1' }); const state = await loadInitialState({ - state: savedState, + persistedState: savedState, + references: [ + { name: 'indexpattern-datasource-current-indexpattern', id: '2', type: 'index-pattern' }, + { name: 'indexpattern-datasource-layer-layerb', id: '2', type: 'index-pattern' }, + { name: 'another-reference', id: 'c', type: 'index-pattern' }, + ], savedObjectsClient: mockClient(), indexPatternsService: mockIndexPatternsService(), storage, @@ -422,7 +427,7 @@ describe('loader', () => { indexPatterns: { '2': sampleIndexPatterns['2'], }, - layers: savedState.layers, + layers: { layerb: { ...savedState.layers.layerb, indexPatternId: '2' } }, }); expect(storage.set).toHaveBeenCalledWith('lens-settings', { @@ -431,6 +436,79 @@ describe('loader', () => { }); }); + describe('saved object references', () => { + const state: IndexPatternPrivateState = { + currentIndexPatternId: 'b', + indexPatternRefs: [], + indexPatterns: {}, + existingFields: {}, + layers: { + a: { + indexPatternId: 'id-index-pattern-a', + columnOrder: ['col1'], + columns: { + col1: { + dataType: 'number', + isBucketed: false, + label: '', + operationType: 'avg', + sourceField: 'myfield', + }, + }, + }, + b: { + indexPatternId: 'id-index-pattern-b', + columnOrder: ['col2'], + columns: { + col2: { + dataType: 'number', + isBucketed: false, + label: '', + operationType: 'avg', + sourceField: 'myfield2', + }, + }, + }, + }, + isFirstExistenceFetch: false, + }; + + it('should create a reference for each layer and for current index pattern', () => { + const { savedObjectReferences } = extractReferences(state); + expect(savedObjectReferences).toMatchInlineSnapshot(` + Array [ + Object { + "id": "b", + "name": "indexpattern-datasource-current-indexpattern", + "type": "index-pattern", + }, + Object { + "id": "id-index-pattern-a", + "name": "indexpattern-datasource-layer-a", + "type": "index-pattern", + }, + Object { + "id": "id-index-pattern-b", + "name": "indexpattern-datasource-layer-b", + "type": "index-pattern", + }, + ] + `); + }); + + it('should restore layers', () => { + const { savedObjectReferences, state: persistedState } = extractReferences(state); + expect(injectReferences(persistedState, savedObjectReferences).layers).toEqual(state.layers); + }); + + it('should restore current index pattern', () => { + const { savedObjectReferences, state: persistedState } = extractReferences(state); + expect(injectReferences(persistedState, savedObjectReferences).currentIndexPatternId).toEqual( + state.currentIndexPatternId + ); + }); + }); + describe('changeIndexPattern', () => { it('loads the index pattern and then sets it as current', async () => { const setState = jest.fn(); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/loader.ts b/x-pack/plugins/lens/public/indexpattern_datasource/loader.ts index 9c4a19e58a052..24906790a9fc9 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/loader.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/loader.ts @@ -6,7 +6,7 @@ import _ from 'lodash'; import { IStorageWrapper } from 'src/plugins/kibana_utils/public'; -import { SavedObjectsClientContract, HttpSetup } from 'kibana/public'; +import { SavedObjectsClientContract, HttpSetup, SavedObjectReference } from 'kibana/public'; import { StateSetter } from '../types'; import { IndexPattern, @@ -14,6 +14,7 @@ import { IndexPatternPersistedState, IndexPatternPrivateState, IndexPatternField, + IndexPatternLayer, } from './types'; import { updateLayerIndexPattern } from './state_helpers'; import { DateRange, ExistingFields } from '../../common/types'; @@ -115,14 +116,58 @@ const setLastUsedIndexPatternId = (storage: IStorageWrapper, value: string) => { writeToStorage(storage, 'indexPatternId', value); }; +const CURRENT_PATTERN_REFERENCE_NAME = 'indexpattern-datasource-current-indexpattern'; +function getLayerReferenceName(layerId: string) { + return `indexpattern-datasource-layer-${layerId}`; +} + +export function extractReferences({ currentIndexPatternId, layers }: IndexPatternPrivateState) { + const savedObjectReferences: SavedObjectReference[] = []; + savedObjectReferences.push({ + type: 'index-pattern', + id: currentIndexPatternId, + name: CURRENT_PATTERN_REFERENCE_NAME, + }); + const persistableLayers: Record> = {}; + Object.entries(layers).forEach(([layerId, { indexPatternId, ...persistableLayer }]) => { + savedObjectReferences.push({ + type: 'index-pattern', + id: indexPatternId, + name: getLayerReferenceName(layerId), + }); + persistableLayers[layerId] = persistableLayer; + }); + return { savedObjectReferences, state: { layers: persistableLayers } }; +} + +export function injectReferences( + state: IndexPatternPersistedState, + references: SavedObjectReference[] +) { + const layers: Record = {}; + Object.entries(state.layers).forEach(([layerId, persistedLayer]) => { + layers[layerId] = { + ...persistedLayer, + indexPatternId: references.find(({ name }) => name === getLayerReferenceName(layerId))!.id, + }; + }); + return { + currentIndexPatternId: references.find(({ name }) => name === CURRENT_PATTERN_REFERENCE_NAME)! + .id, + layers, + }; +} + export async function loadInitialState({ - state, + persistedState, + references, savedObjectsClient, defaultIndexPatternId, storage, indexPatternsService, }: { - state?: IndexPatternPersistedState; + persistedState?: IndexPatternPersistedState; + references?: SavedObjectReference[]; savedObjectsClient: SavedObjectsClient; defaultIndexPatternId?: string; storage: IStorageWrapper; @@ -131,6 +176,9 @@ export async function loadInitialState({ const indexPatternRefs = await loadIndexPatternRefs(savedObjectsClient); const lastUsedIndexPatternId = getLastUsedIndexPatternId(storage, indexPatternRefs); + const state = + persistedState && references ? injectReferences(persistedState, references) : undefined; + const requiredPatterns = _.uniq( state ? Object.values(state.layers) diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/types.ts b/x-pack/plugins/lens/public/indexpattern_datasource/types.ts index 8d0e82b176aa9..95cc47e68f8a1 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/types.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/types.ts @@ -40,11 +40,12 @@ export interface IndexPatternLayer { } export interface IndexPatternPersistedState { - currentIndexPatternId: string; - layers: Record; + layers: Record>; } -export type IndexPatternPrivateState = IndexPatternPersistedState & { +export interface IndexPatternPrivateState { + currentIndexPatternId: string; + layers: Record; indexPatternRefs: IndexPatternRef[]; indexPatterns: Record; @@ -54,7 +55,7 @@ export type IndexPatternPrivateState = IndexPatternPersistedState & { existingFields: Record>; isFirstExistenceFetch: boolean; existenceFetchFailed?: boolean; -}; +} export interface IndexPatternRef { id: string; diff --git a/x-pack/plugins/lens/public/metric_visualization/metric_visualization.test.ts b/x-pack/plugins/lens/public/metric_visualization/metric_visualization.test.ts index 62f47a21c85b0..f3c9a725ee2e2 100644 --- a/x-pack/plugins/lens/public/metric_visualization/metric_visualization.test.ts +++ b/x-pack/plugins/lens/public/metric_visualization/metric_visualization.test.ts @@ -66,12 +66,6 @@ describe('metric_visualization', () => { }); }); - describe('#getPersistableState', () => { - it('persists the state as given', () => { - expect(metricVisualization.getPersistableState(exampleState())).toEqual(exampleState()); - }); - }); - describe('#getConfiguration', () => { it('can add a metric when there is no accessor', () => { expect( @@ -168,7 +162,8 @@ describe('metric_visualization', () => { datasourceLayers: { l1: datasource }, }; - expect(metricVisualization.toExpression(exampleState(), frame)).toMatchInlineSnapshot(` + expect(metricVisualization.toExpression(exampleState(), frame.datasourceLayers)) + .toMatchInlineSnapshot(` Object { "chain": Array [ Object { diff --git a/x-pack/plugins/lens/public/metric_visualization/metric_visualization.tsx b/x-pack/plugins/lens/public/metric_visualization/metric_visualization.tsx index e565d2fa8b293..5f1ce5334dd36 100644 --- a/x-pack/plugins/lens/public/metric_visualization/metric_visualization.tsx +++ b/x-pack/plugins/lens/public/metric_visualization/metric_visualization.tsx @@ -7,20 +7,20 @@ import { i18n } from '@kbn/i18n'; import { Ast } from '@kbn/interpreter/target/common'; import { getSuggestions } from './metric_suggestions'; -import { Visualization, FramePublicAPI, OperationMetadata } from '../types'; -import { State, PersistableState } from './types'; +import { Visualization, OperationMetadata, DatasourcePublicAPI } from '../types'; +import { State } from './types'; import chartMetricSVG from '../assets/chart_metric.svg'; const toExpression = ( state: State, - frame: FramePublicAPI, + datasourceLayers: Record, mode: 'reduced' | 'full' = 'full' ): Ast | null => { if (!state.accessor) { return null; } - const [datasource] = Object.values(frame.datasourceLayers); + const [datasource] = Object.values(datasourceLayers); const operation = datasource && datasource.getOperationForColumnId(state.accessor); return { @@ -39,7 +39,7 @@ const toExpression = ( }; }; -export const metricVisualization: Visualization = { +export const metricVisualization: Visualization = { id: 'lnsMetric', visualizationTypes: [ @@ -88,8 +88,6 @@ export const metricVisualization: Visualization = { ); }, - getPersistableState: (state) => state, - getConfiguration(props) { return { groups: [ @@ -106,8 +104,8 @@ export const metricVisualization: Visualization = { }, toExpression, - toPreviewExpression: (state: State, frame: FramePublicAPI) => - toExpression(state, frame, 'reduced'), + toPreviewExpression: (state, datasourceLayers) => + toExpression(state, datasourceLayers, 'reduced'), setDimension({ prevState, columnId }) { return { ...prevState, accessor: columnId }; diff --git a/x-pack/plugins/lens/public/metric_visualization/types.ts b/x-pack/plugins/lens/public/metric_visualization/types.ts index 53fc103934255..86a781716b345 100644 --- a/x-pack/plugins/lens/public/metric_visualization/types.ts +++ b/x-pack/plugins/lens/public/metric_visualization/types.ts @@ -13,5 +13,3 @@ export interface MetricConfig extends State { title: string; mode: 'reduced' | 'full'; } - -export type PersistableState = State; diff --git a/x-pack/plugins/lens/public/persistence/filter_references.test.ts b/x-pack/plugins/lens/public/persistence/filter_references.test.ts new file mode 100644 index 0000000000000..23c0cd1d11f1b --- /dev/null +++ b/x-pack/plugins/lens/public/persistence/filter_references.test.ts @@ -0,0 +1,99 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { Filter } from 'src/plugins/data/public'; +import { extractFilterReferences, injectFilterReferences } from './filter_references'; +import { FilterStateStore } from 'src/plugins/data/common'; + +describe('filter saved object references', () => { + const filters: Filter[] = [ + { + $state: { store: FilterStateStore.APP_STATE }, + meta: { + alias: null, + disabled: false, + index: '90943e30-9a47-11e8-b64d-95841ca0b247', + key: 'geo.src', + negate: true, + params: { query: 'CN' }, + type: 'phrase', + }, + query: { match_phrase: { 'geo.src': 'CN' } }, + }, + { + $state: { store: FilterStateStore.APP_STATE }, + meta: { + alias: null, + disabled: false, + index: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', + key: 'geoip.country_iso_code', + negate: true, + params: { query: 'US' }, + type: 'phrase', + }, + query: { match_phrase: { 'geoip.country_iso_code': 'US' } }, + }, + ]; + + it('should create two index-pattern references', () => { + const { references } = extractFilterReferences(filters); + expect(references).toMatchInlineSnapshot(` + Array [ + Object { + "id": "90943e30-9a47-11e8-b64d-95841ca0b247", + "name": "filter-index-pattern-0", + "type": "index-pattern", + }, + Object { + "id": "ff959d40-b880-11e8-a6d9-e546fe2bba5f", + "name": "filter-index-pattern-1", + "type": "index-pattern", + }, + ] + `); + }); + + it('should restore the same filter after extracting and injecting', () => { + const { persistableFilters, references } = extractFilterReferences(filters); + expect(injectFilterReferences(persistableFilters, references)).toEqual(filters); + }); + + it('should ignore other references', () => { + const { persistableFilters, references } = extractFilterReferences(filters); + expect( + injectFilterReferences(persistableFilters, [ + { type: 'index-pattern', id: '1234', name: 'some other index pattern' }, + ...references, + ]) + ).toEqual(filters); + }); + + it('should inject other ids if references change', () => { + const { persistableFilters, references } = extractFilterReferences(filters); + + expect( + injectFilterReferences( + persistableFilters, + references.map((reference, index) => ({ ...reference, id: `overwritten-id-${index}` })) + ) + ).toEqual([ + { + ...filters[0], + meta: { + ...filters[0].meta, + index: 'overwritten-id-0', + }, + }, + { + ...filters[1], + meta: { + ...filters[1].meta, + index: 'overwritten-id-1', + }, + }, + ]); + }); +}); diff --git a/x-pack/plugins/lens/public/persistence/filter_references.ts b/x-pack/plugins/lens/public/persistence/filter_references.ts new file mode 100644 index 0000000000000..47564e510ce9c --- /dev/null +++ b/x-pack/plugins/lens/public/persistence/filter_references.ts @@ -0,0 +1,56 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { Filter } from 'src/plugins/data/public'; +import { SavedObjectReference } from 'kibana/public'; +import { PersistableFilter } from '../../common'; + +export function extractFilterReferences( + filters: Filter[] +): { persistableFilters: PersistableFilter[]; references: SavedObjectReference[] } { + const references: SavedObjectReference[] = []; + const persistableFilters = filters.map((filterRow, i) => { + if (!filterRow.meta || !filterRow.meta.index) { + return filterRow; + } + const refName = `filter-index-pattern-${i}`; + references.push({ + name: refName, + type: 'index-pattern', + id: filterRow.meta.index, + }); + return { + ...filterRow, + meta: { + ...filterRow.meta, + indexRefName: refName, + index: undefined, + }, + }; + }); + + return { persistableFilters, references }; +} + +export function injectFilterReferences( + filters: PersistableFilter[], + references: SavedObjectReference[] +) { + return filters.map((filterRow) => { + if (!filterRow.meta || !filterRow.meta.indexRefName) { + return filterRow as Filter; + } + const { indexRefName, ...metaRest } = filterRow.meta; + const reference = references.find((ref) => ref.name === indexRefName); + if (!reference) { + throw new Error(`Could not find reference for ${indexRefName}`); + } + return { + ...filterRow, + meta: { ...metaRest, index: reference.id }, + }; + }); +} diff --git a/x-pack/plugins/lens/public/persistence/index.ts b/x-pack/plugins/lens/public/persistence/index.ts index 1f823ff75c8c6..464bd46790422 100644 --- a/x-pack/plugins/lens/public/persistence/index.ts +++ b/x-pack/plugins/lens/public/persistence/index.ts @@ -5,3 +5,4 @@ */ export * from './saved_object_store'; +export * from './filter_references'; diff --git a/x-pack/plugins/lens/public/persistence/saved_object_store.test.ts b/x-pack/plugins/lens/public/persistence/saved_object_store.test.ts index f8f8d889233a7..ba7c0ee6ae786 100644 --- a/x-pack/plugins/lens/public/persistence/saved_object_store.test.ts +++ b/x-pack/plugins/lens/public/persistence/saved_object_store.test.ts @@ -30,11 +30,8 @@ describe('LensStore', () => { title: 'Hello', description: 'My doc', visualizationType: 'bar', - expression: '', + references: [], state: { - datasourceMetaData: { - filterableIndexPatterns: [], - }, datasourceStates: { indexpattern: { type: 'index_pattern', indexPattern: '.kibana_test' }, }, @@ -49,11 +46,8 @@ describe('LensStore', () => { title: 'Hello', description: 'My doc', visualizationType: 'bar', - expression: '', + references: [], state: { - datasourceMetaData: { - filterableIndexPatterns: [], - }, datasourceStates: { indexpattern: { type: 'index_pattern', indexPattern: '.kibana_test' }, }, @@ -64,21 +58,25 @@ describe('LensStore', () => { }); expect(client.create).toHaveBeenCalledTimes(1); - expect(client.create).toHaveBeenCalledWith('lens', { - title: 'Hello', - description: 'My doc', - visualizationType: 'bar', - expression: '', - state: { - datasourceMetaData: { filterableIndexPatterns: [] }, - datasourceStates: { - indexpattern: { type: 'index_pattern', indexPattern: '.kibana_test' }, + expect(client.create).toHaveBeenCalledWith( + 'lens', + { + title: 'Hello', + description: 'My doc', + visualizationType: 'bar', + state: { + datasourceStates: { + indexpattern: { type: 'index_pattern', indexPattern: '.kibana_test' }, + }, + visualization: { x: 'foo', y: 'baz' }, + query: { query: '', language: 'lucene' }, + filters: [], }, - visualization: { x: 'foo', y: 'baz' }, - query: { query: '', language: 'lucene' }, - filters: [], }, - }); + { + references: [], + } + ); }); test('updates and returns a visualization document', async () => { @@ -87,9 +85,8 @@ describe('LensStore', () => { id: 'Gandalf', title: 'Even the very wise cannot see all ends.', visualizationType: 'line', - expression: '', + references: [], state: { - datasourceMetaData: { filterableIndexPatterns: [] }, datasourceStates: { indexpattern: { type: 'index_pattern', indexPattern: 'lotr' } }, visualization: { gear: ['staff', 'pointy hat'] }, query: { query: '', language: 'lucene' }, @@ -101,9 +98,8 @@ describe('LensStore', () => { id: 'Gandalf', title: 'Even the very wise cannot see all ends.', visualizationType: 'line', - expression: '', + references: [], state: { - datasourceMetaData: { filterableIndexPatterns: [] }, datasourceStates: { indexpattern: { type: 'index_pattern', indexPattern: 'lotr' } }, visualization: { gear: ['staff', 'pointy hat'] }, query: { query: '', language: 'lucene' }, @@ -116,22 +112,21 @@ describe('LensStore', () => { { type: 'lens', id: 'Gandalf', + references: [], attributes: { title: null, visualizationType: null, - expression: null, state: null, }, }, { type: 'lens', id: 'Gandalf', + references: [], attributes: { title: 'Even the very wise cannot see all ends.', visualizationType: 'line', - expression: '', state: { - datasourceMetaData: { filterableIndexPatterns: [] }, datasourceStates: { indexpattern: { type: 'index_pattern', indexPattern: 'lotr' } }, visualization: { gear: ['staff', 'pointy hat'] }, query: { query: '', language: 'lucene' }, diff --git a/x-pack/plugins/lens/public/persistence/saved_object_store.ts b/x-pack/plugins/lens/public/persistence/saved_object_store.ts index 59ead53956a8d..e4609213ec792 100644 --- a/x-pack/plugins/lens/public/persistence/saved_object_store.ts +++ b/x-pack/plugins/lens/public/persistence/saved_object_store.ts @@ -4,8 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -import { SavedObjectAttributes, SavedObjectsClientContract } from 'kibana/public'; -import { Query, Filter } from '../../../../../src/plugins/data/public'; +import { + SavedObjectAttributes, + SavedObjectsClientContract, + SavedObjectReference, +} from 'kibana/public'; +import { Query } from '../../../../../src/plugins/data/public'; +import { PersistableFilter } from '../../common'; export interface Document { id?: string; @@ -13,16 +18,13 @@ export interface Document { visualizationType: string | null; title: string; description?: string; - expression: string | null; state: { - datasourceMetaData: { - filterableIndexPatterns: Array<{ id: string; title: string }>; - }; datasourceStates: Record; visualization: unknown; query: Query; - filters: Filter[]; + filters: PersistableFilter[]; }; + references: SavedObjectReference[]; } export const DOC_TYPE = 'lens'; @@ -45,14 +47,16 @@ export class SavedObjectIndexStore implements SavedObjectStore { } async save(vis: Document) { - const { id, type, ...rest } = vis; + const { id, type, references, ...rest } = vis; // TODO: SavedObjectAttributes should support this kind of object, // remove this workaround when SavedObjectAttributes is updated. const attributes = (rest as unknown) as SavedObjectAttributes; const result = await (id - ? this.safeUpdate(id, attributes) - : this.client.create(DOC_TYPE, attributes)); + ? this.safeUpdate(id, attributes, references) + : this.client.create(DOC_TYPE, attributes, { + references, + })); return { ...vis, id: result.id }; } @@ -63,21 +67,25 @@ export class SavedObjectIndexStore implements SavedObjectStore { // deleted subtrees make it back into the object after a load. // This function fixes this by doing two updates - one to empty out the document setting // every key to null, and a second one to load the new content. - private async safeUpdate(id: string, attributes: SavedObjectAttributes) { + private async safeUpdate( + id: string, + attributes: SavedObjectAttributes, + references: SavedObjectReference[] + ) { const resetAttributes: SavedObjectAttributes = {}; Object.keys(attributes).forEach((key) => { resetAttributes[key] = null; }); return ( await this.client.bulkUpdate([ - { type: DOC_TYPE, id, attributes: resetAttributes }, - { type: DOC_TYPE, id, attributes }, + { type: DOC_TYPE, id, attributes: resetAttributes, references }, + { type: DOC_TYPE, id, attributes, references }, ]) ).savedObjects[1]; } async load(id: string): Promise { - const { type, attributes, error } = await this.client.get(DOC_TYPE, id); + const { type, attributes, references, error } = await this.client.get(DOC_TYPE, id); if (error) { throw error; @@ -85,6 +93,7 @@ export class SavedObjectIndexStore implements SavedObjectStore { return { ...(attributes as SavedObjectAttributes), + references, id, type, } as Document; diff --git a/x-pack/plugins/lens/public/pie_visualization/pie_visualization.tsx b/x-pack/plugins/lens/public/pie_visualization/pie_visualization.tsx index 5a68516db6aa3..855bacd4f794c 100644 --- a/x-pack/plugins/lens/public/pie_visualization/pie_visualization.tsx +++ b/x-pack/plugins/lens/public/pie_visualization/pie_visualization.tsx @@ -31,7 +31,7 @@ const bucketedOperations = (op: OperationMetadata) => op.isBucketed; const numberMetricOperations = (op: OperationMetadata) => !op.isBucketed && op.dataType === 'number'; -export const pieVisualization: Visualization = { +export const pieVisualization: Visualization = { id: 'lnsPie', visualizationTypes: [ @@ -91,8 +91,6 @@ export const pieVisualization: Visualization state, - getSuggestions: suggestions, getConfiguration({ state, frame, layerId }) { diff --git a/x-pack/plugins/lens/public/pie_visualization/to_expression.ts b/x-pack/plugins/lens/public/pie_visualization/to_expression.ts index fbc47e8bfb00f..f36b9efb930a9 100644 --- a/x-pack/plugins/lens/public/pie_visualization/to_expression.ts +++ b/x-pack/plugins/lens/public/pie_visualization/to_expression.ts @@ -5,21 +5,24 @@ */ import { Ast } from '@kbn/interpreter/common'; -import { FramePublicAPI, Operation } from '../types'; +import { Operation, DatasourcePublicAPI } from '../types'; import { DEFAULT_PERCENT_DECIMALS } from './constants'; import { PieVisualizationState } from './types'; -export function toExpression(state: PieVisualizationState, frame: FramePublicAPI) { - return expressionHelper(state, frame, false); +export function toExpression( + state: PieVisualizationState, + datasourceLayers: Record +) { + return expressionHelper(state, datasourceLayers, false); } function expressionHelper( state: PieVisualizationState, - frame: FramePublicAPI, + datasourceLayers: Record, isPreview: boolean ): Ast | null { const layer = state.layers[0]; - const datasource = frame.datasourceLayers[layer.layerId]; + const datasource = datasourceLayers[layer.layerId]; const operations = layer.groups .map((columnId) => ({ columnId, operation: datasource.getOperationForColumnId(columnId) })) .filter((o): o is { columnId: string; operation: Operation } => !!o.operation); @@ -50,6 +53,9 @@ function expressionHelper( }; } -export function toPreviewExpression(state: PieVisualizationState, frame: FramePublicAPI) { - return expressionHelper(state, frame, true); +export function toPreviewExpression( + state: PieVisualizationState, + datasourceLayers: Record +) { + return expressionHelper(state, datasourceLayers, true); } diff --git a/x-pack/plugins/lens/public/types.ts b/x-pack/plugins/lens/public/types.ts index c7bda65cd1327..20f2ce6c56774 100644 --- a/x-pack/plugins/lens/public/types.ts +++ b/x-pack/plugins/lens/public/types.ts @@ -7,6 +7,7 @@ import { Ast } from '@kbn/interpreter/common'; import { IconType } from '@elastic/eui/src/components/icon/icon'; import { CoreSetup } from 'kibana/public'; +import { SavedObjectReference } from 'kibana/public'; import { ExpressionRendererEvent, IInterpreterRenderHandlers, @@ -30,7 +31,6 @@ export type FormatFactory = (mapping?: SerializedFieldFormat) => IFieldFormat; export interface PublicAPIProps { state: T; layerId: string; - dateRange: DateRange; } export interface EditorFrameProps { @@ -44,8 +44,9 @@ export interface EditorFrameProps { // Frame loader (app or embeddable) is expected to call this when it loads and updates // This should be replaced with a top-down state onChange: (newState: { - filterableIndexPatterns: DatasourceMetaData['filterableIndexPatterns']; + filterableIndexPatterns: string[]; doc: Document; + isSaveable: boolean; }) => void; showNoDataPopover: () => void; } @@ -57,9 +58,7 @@ export interface EditorFrameInstance { export interface EditorFrameSetup { // generic type on the API functions to pull the "unknown vs. specific type" error into the implementation registerDatasource: (datasource: Datasource | Promise>) => void; - registerVisualization: ( - visualization: Visualization | Promise> - ) => void; + registerVisualization: (visualization: Visualization | Promise>) => void; } export interface EditorFrameStart { @@ -131,10 +130,6 @@ export interface DatasourceSuggestion { keptLayerIds: string[]; } -export interface DatasourceMetaData { - filterableIndexPatterns: Array<{ id: string; title: string }>; -} - export type StateSetter = (newState: T | ((prevState: T) => T)) => void; /** @@ -146,10 +141,10 @@ export interface Datasource { // For initializing, either from an empty state or from persisted state // Because this will be called at runtime, state might have a type of `any` and // datasources should validate their arguments - initialize: (state?: P) => Promise; + initialize: (state?: P, savedObjectReferences?: SavedObjectReference[]) => Promise; // Given the current state, which parts should be saved? - getPersistableState: (state: T) => P; + getPersistableState: (state: T) => { state: P; savedObjectReferences: SavedObjectReference[] }; insertLayer: (state: T, newLayerId: string) => T; removeLayer: (state: T, layerId: string) => T; @@ -166,8 +161,6 @@ export interface Datasource { toExpression: (state: T, layerId: string) => Ast | string | null; - getMetaData: (state: T) => DatasourceMetaData; - getDatasourceSuggestionsForField: (state: T, field: unknown) => Array>; getDatasourceSuggestionsFromCurrentState: (state: T) => Array>; @@ -408,7 +401,7 @@ export interface VisualizationType { label: string; } -export interface Visualization { +export interface Visualization { /** Plugin ID, such as "lnsXY" */ id: string; @@ -418,11 +411,7 @@ export interface Visualization { * - Loadingn from a saved visualization * - When using suggestions, the suggested state is passed in */ - initialize: (frame: FramePublicAPI, state?: P) => T; - /** - * Can remove any state that should not be persisted to saved object, such as UI state - */ - getPersistableState: (state: T) => P; + initialize: (frame: FramePublicAPI, state?: T) => T; /** * Visualizations must provide at least one type for the chart switcher, @@ -504,12 +493,18 @@ export interface Visualization { */ getSuggestions: (context: SuggestionRequest) => Array>; - toExpression: (state: T, frame: FramePublicAPI) => Ast | string | null; + toExpression: ( + state: T, + datasourceLayers: Record + ) => Ast | string | null; /** * Expression to render a preview version of the chart in very constrained space. * If there is no expression provided, the preview icon is used. */ - toPreviewExpression?: (state: T, frame: FramePublicAPI) => Ast | string | null; + toPreviewExpression?: ( + state: T, + datasourceLayers: Record + ) => Ast | string | null; } export interface LensFilterEvent { diff --git a/x-pack/plugins/lens/public/xy_visualization/to_expression.test.ts b/x-pack/plugins/lens/public/xy_visualization/to_expression.test.ts index 876d1141740e1..f579085646f6f 100644 --- a/x-pack/plugins/lens/public/xy_visualization/to_expression.test.ts +++ b/x-pack/plugins/lens/public/xy_visualization/to_expression.test.ts @@ -53,7 +53,7 @@ describe('#toExpression', () => { }, ], }, - frame + frame.datasourceLayers ) ).toMatchSnapshot(); }); @@ -74,7 +74,7 @@ describe('#toExpression', () => { }, ], }, - frame + frame.datasourceLayers ) as Ast).chain[0].arguments.fittingFunction[0] ).toEqual('None'); }); @@ -94,7 +94,7 @@ describe('#toExpression', () => { }, ], }, - frame + frame.datasourceLayers ) as Ast; expect(expression.chain[0].arguments.showXAxisTitle[0]).toBe(true); expect(expression.chain[0].arguments.showYAxisTitle[0]).toBe(true); @@ -116,7 +116,7 @@ describe('#toExpression', () => { }, ], }, - frame + frame.datasourceLayers ) ).toBeNull(); }); @@ -137,7 +137,7 @@ describe('#toExpression', () => { }, ], }, - frame + frame.datasourceLayers ) ).toBeNull(); }); @@ -157,7 +157,7 @@ describe('#toExpression', () => { }, ], }, - frame + frame.datasourceLayers )! as Ast; expect(mockDatasource.publicAPIMock.getOperationForColumnId).toHaveBeenCalledWith('b'); @@ -191,7 +191,7 @@ describe('#toExpression', () => { }, ], }, - frame + frame.datasourceLayers ) as Ast; expect( (expression.chain[0].arguments.tickLabelsVisibilitySettings[0] as Ast).chain[0].arguments @@ -216,7 +216,7 @@ describe('#toExpression', () => { }, ], }, - frame + frame.datasourceLayers ) as Ast; expect( (expression.chain[0].arguments.gridlinesVisibilitySettings[0] as Ast).chain[0].arguments diff --git a/x-pack/plugins/lens/public/xy_visualization/to_expression.ts b/x-pack/plugins/lens/public/xy_visualization/to_expression.ts index 9b9c159af265e..cd32d4f94c3e5 100644 --- a/x-pack/plugins/lens/public/xy_visualization/to_expression.ts +++ b/x-pack/plugins/lens/public/xy_visualization/to_expression.ts @@ -7,13 +7,16 @@ import { Ast } from '@kbn/interpreter/common'; import { ScaleType } from '@elastic/charts'; import { State, LayerConfig } from './types'; -import { FramePublicAPI, OperationMetadata } from '../types'; +import { OperationMetadata, DatasourcePublicAPI } from '../types'; interface ValidLayer extends LayerConfig { xAccessor: NonNullable; } -export const toExpression = (state: State, frame: FramePublicAPI): Ast | null => { +export const toExpression = ( + state: State, + datasourceLayers: Record +): Ast | null => { if (!state || !state.layers.length) { return null; } @@ -21,19 +24,20 @@ export const toExpression = (state: State, frame: FramePublicAPI): Ast | null => const metadata: Record> = {}; state.layers.forEach((layer) => { metadata[layer.layerId] = {}; - const datasource = frame.datasourceLayers[layer.layerId]; + const datasource = datasourceLayers[layer.layerId]; datasource.getTableSpec().forEach((column) => { - const operation = frame.datasourceLayers[layer.layerId].getOperationForColumnId( - column.columnId - ); + const operation = datasourceLayers[layer.layerId].getOperationForColumnId(column.columnId); metadata[layer.layerId][column.columnId] = operation; }); }); - return buildExpression(state, metadata, frame); + return buildExpression(state, metadata, datasourceLayers); }; -export function toPreviewExpression(state: State, frame: FramePublicAPI) { +export function toPreviewExpression( + state: State, + datasourceLayers: Record +) { return toExpression( { ...state, @@ -44,7 +48,7 @@ export function toPreviewExpression(state: State, frame: FramePublicAPI) { isVisible: false, }, }, - frame + datasourceLayers ); } @@ -77,7 +81,7 @@ export function getScaleType(metadata: OperationMetadata | null, defaultScale: S export const buildExpression = ( state: State, metadata: Record>, - frame?: FramePublicAPI + datasourceLayers?: Record ): Ast | null => { const validLayers = state.layers.filter((layer): layer is ValidLayer => Boolean(layer.xAccessor && layer.accessors.length) @@ -149,8 +153,8 @@ export const buildExpression = ( layers: validLayers.map((layer) => { const columnToLabel: Record = {}; - if (frame) { - const datasource = frame.datasourceLayers[layer.layerId]; + if (datasourceLayers) { + const datasource = datasourceLayers[layer.layerId]; layer.accessors .concat(layer.splitAccessor ? [layer.splitAccessor] : []) .forEach((accessor) => { @@ -162,8 +166,8 @@ export const buildExpression = ( } const xAxisOperation = - frame && - frame.datasourceLayers[layer.layerId].getOperationForColumnId(layer.xAccessor); + datasourceLayers && + datasourceLayers[layer.layerId].getOperationForColumnId(layer.xAccessor); const isHistogramDimension = Boolean( xAxisOperation && diff --git a/x-pack/plugins/lens/public/xy_visualization/types.ts b/x-pack/plugins/lens/public/xy_visualization/types.ts index ab689ceb183be..2739ffe42f13f 100644 --- a/x-pack/plugins/lens/public/xy_visualization/types.ts +++ b/x-pack/plugins/lens/public/xy_visualization/types.ts @@ -339,7 +339,6 @@ export interface XYState { } export type State = XYState; -export type PersistableState = XYState; export const visualizationTypes: VisualizationType[] = [ { diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_visualization.test.ts b/x-pack/plugins/lens/public/xy_visualization/xy_visualization.test.ts index 0a8e8bbe0c46f..53f7a23dcae98 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_visualization.test.ts +++ b/x-pack/plugins/lens/public/xy_visualization/xy_visualization.test.ts @@ -157,12 +157,6 @@ describe('xy_visualization', () => { }); }); - describe('#getPersistableState', () => { - it('persists the state as given', () => { - expect(xyVisualization.getPersistableState(exampleState())).toEqual(exampleState()); - }); - }); - describe('#removeLayer', () => { it('removes the specified layer', () => { const prevState: State = { diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_visualization.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_visualization.tsx index f321e0962caa8..8c551c575764e 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_visualization.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_visualization.tsx @@ -13,7 +13,7 @@ import { i18n } from '@kbn/i18n'; import { getSuggestions } from './xy_suggestions'; import { LayerContextMenu, XyToolbar, DimensionEditor } from './xy_config_panel'; import { Visualization, OperationMetadata, VisualizationType } from '../types'; -import { State, PersistableState, SeriesType, visualizationTypes, LayerConfig } from './types'; +import { State, SeriesType, visualizationTypes, LayerConfig } from './types'; import chartBarStackedSVG from '../assets/chart_bar_stacked.svg'; import chartMixedSVG from '../assets/chart_mixed_xy.svg'; import { isHorizontalChart } from './state_helpers'; @@ -74,7 +74,7 @@ function getDescription(state?: State) { }; } -export const xyVisualization: Visualization = { +export const xyVisualization: Visualization = { id: 'lnsXY', visualizationTypes, @@ -159,8 +159,6 @@ export const xyVisualization: Visualization = { ); }, - getPersistableState: (state) => state, - getConfiguration(props) { const layer = props.state.layers.find((l) => l.layerId === props.layerId)!; return { diff --git a/x-pack/plugins/lens/server/__snapshots__/migrations.test.ts.snap b/x-pack/plugins/lens/server/__snapshots__/migrations.test.ts.snap new file mode 100644 index 0000000000000..4979438dbd3d0 --- /dev/null +++ b/x-pack/plugins/lens/server/__snapshots__/migrations.test.ts.snap @@ -0,0 +1,188 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Lens migrations 7.10.0 references should produce a valid document 1`] = ` +Object { + "attributes": Object { + "state": Object { + "datasourceStates": Object { + "indexpattern": Object { + "layers": Object { + "3b7791e9-326e-40d5-a787-b7594e48d906": Object { + "columnOrder": Array [ + "77d8383e-f66e-471e-ae50-c427feedb5ba", + "a5c1b82d-51de-4448-a99d-6391432c3a03", + ], + "columns": Object { + "77d8383e-f66e-471e-ae50-c427feedb5ba": Object { + "dataType": "string", + "isBucketed": true, + "label": "Top values of geoip.country_iso_code", + "operationType": "terms", + "params": Object { + "orderBy": Object { + "columnId": "a5c1b82d-51de-4448-a99d-6391432c3a03", + "type": "column", + }, + "orderDirection": "desc", + "size": 5, + }, + "scale": "ordinal", + "sourceField": "geoip.country_iso_code", + }, + "a5c1b82d-51de-4448-a99d-6391432c3a03": Object { + "dataType": "number", + "isBucketed": false, + "label": "Count of records", + "operationType": "count", + "scale": "ratio", + "sourceField": "Records", + }, + }, + }, + "9a27f85d-35a9-4246-81b2-48e7ee9b0707": Object { + "columnOrder": Array [ + "96352896-c508-4fca-90d8-66e9ebfce621", + "4ce9b4c7-2ebf-4d48-8669-0ea69d973353", + ], + "columns": Object { + "4ce9b4c7-2ebf-4d48-8669-0ea69d973353": Object { + "dataType": "number", + "isBucketed": false, + "label": "Count of records", + "operationType": "count", + "scale": "ratio", + "sourceField": "Records", + }, + "96352896-c508-4fca-90d8-66e9ebfce621": Object { + "dataType": "string", + "isBucketed": true, + "label": "Top values of geo.src", + "operationType": "terms", + "params": Object { + "orderBy": Object { + "columnId": "4ce9b4c7-2ebf-4d48-8669-0ea69d973353", + "type": "column", + }, + "orderDirection": "desc", + "size": 5, + }, + "scale": "ordinal", + "sourceField": "geo.src", + }, + }, + }, + }, + }, + }, + "filters": Array [ + Object { + "$state": Object { + "store": "appState", + }, + "meta": Object { + "alias": null, + "disabled": false, + "index": undefined, + "indexRefName": "filter-index-pattern-0", + "key": "geo.src", + "negate": true, + "params": Object { + "query": "CN", + }, + "type": "phrase", + }, + "query": Object { + "match_phrase": Object { + "geo.src": "CN", + }, + }, + }, + Object { + "$state": Object { + "store": "appState", + }, + "meta": Object { + "alias": null, + "disabled": false, + "index": undefined, + "indexRefName": "filter-index-pattern-1", + "key": "geoip.country_iso_code", + "negate": true, + "params": Object { + "query": "US", + }, + "type": "phrase", + }, + "query": Object { + "match_phrase": Object { + "geoip.country_iso_code": "US", + }, + }, + }, + ], + "query": Object { + "language": "kuery", + "query": "NOT bytes > 5000", + }, + "visualization": Object { + "fittingFunction": "None", + "layers": Array [ + Object { + "accessors": Array [ + "4ce9b4c7-2ebf-4d48-8669-0ea69d973353", + ], + "layerId": "9a27f85d-35a9-4246-81b2-48e7ee9b0707", + "position": "top", + "seriesType": "bar", + "showGridlines": false, + "xAccessor": "96352896-c508-4fca-90d8-66e9ebfce621", + }, + Object { + "accessors": Array [ + "a5c1b82d-51de-4448-a99d-6391432c3a03", + ], + "layerId": "3b7791e9-326e-40d5-a787-b7594e48d906", + "seriesType": "bar", + "xAccessor": "77d8383e-f66e-471e-ae50-c427feedb5ba", + }, + ], + "legend": Object { + "isVisible": true, + "position": "right", + }, + "preferredSeriesType": "bar", + }, + }, + "title": "mylens", + "visualizationType": "lnsXY", + }, + "references": Array [ + Object { + "id": "ff959d40-b880-11e8-a6d9-e546fe2bba5f", + "name": "indexpattern-datasource-current-indexpattern", + "type": "index-pattern", + }, + Object { + "id": "ff959d40-b880-11e8-a6d9-e546fe2bba5f", + "name": "indexpattern-datasource-layer-3b7791e9-326e-40d5-a787-b7594e48d906", + "type": "index-pattern", + }, + Object { + "id": "90943e30-9a47-11e8-b64d-95841ca0b247", + "name": "indexpattern-datasource-layer-9a27f85d-35a9-4246-81b2-48e7ee9b0707", + "type": "index-pattern", + }, + Object { + "id": "90943e30-9a47-11e8-b64d-95841ca0b247", + "name": "filter-index-pattern-0", + "type": "index-pattern", + }, + Object { + "id": "ff959d40-b880-11e8-a6d9-e546fe2bba5f", + "name": "filter-index-pattern-1", + "type": "index-pattern", + }, + ], + "type": "lens", +} +`; diff --git a/x-pack/plugins/lens/server/migrations.test.ts b/x-pack/plugins/lens/server/migrations.test.ts index 0541d9636577b..676494dcab619 100644 --- a/x-pack/plugins/lens/server/migrations.test.ts +++ b/x-pack/plugins/lens/server/migrations.test.ts @@ -278,4 +278,233 @@ describe('Lens migrations', () => { expect(result).toEqual(input); }); }); + + describe('7.10.0 references', () => { + const context = {} as SavedObjectMigrationContext; + + const example = { + attributes: { + description: '', + expression: + 'kibana\n| kibana_context query="{\\"query\\":\\"NOT bytes > 5000\\",\\"language\\":\\"kuery\\"}" \n filters="[{\\"meta\\":{\\"index\\":\\"90943e30-9a47-11e8-b64d-95841ca0b247\\",\\"alias\\":null,\\"negate\\":true,\\"disabled\\":false,\\"type\\":\\"phrase\\",\\"key\\":\\"geo.src\\",\\"params\\":{\\"query\\":\\"CN\\"}},\\"query\\":{\\"match_phrase\\":{\\"geo.src\\":\\"CN\\"}},\\"$state\\":{\\"store\\":\\"appState\\"}},{\\"meta\\":{\\"index\\":\\"ff959d40-b880-11e8-a6d9-e546fe2bba5f\\",\\"alias\\":null,\\"negate\\":true,\\"disabled\\":false,\\"type\\":\\"phrase\\",\\"key\\":\\"geoip.country_iso_code\\",\\"params\\":{\\"query\\":\\"US\\"}},\\"query\\":{\\"match_phrase\\":{\\"geoip.country_iso_code\\":\\"US\\"}},\\"$state\\":{\\"store\\":\\"appState\\"}}]"\n| lens_merge_tables layerIds="9a27f85d-35a9-4246-81b2-48e7ee9b0707"\n layerIds="3b7791e9-326e-40d5-a787-b7594e48d906" \n tables={esaggs index="90943e30-9a47-11e8-b64d-95841ca0b247" metricsAtAllLevels=true partialRows=true includeFormatHints=true aggConfigs="[{\\"id\\":\\"96352896-c508-4fca-90d8-66e9ebfce621\\",\\"enabled\\":true,\\"type\\":\\"terms\\",\\"schema\\":\\"segment\\",\\"params\\":{\\"field\\":\\"geo.src\\",\\"orderBy\\":\\"4ce9b4c7-2ebf-4d48-8669-0ea69d973353\\",\\"order\\":\\"desc\\",\\"size\\":5,\\"otherBucket\\":false,\\"otherBucketLabel\\":\\"Other\\",\\"missingBucket\\":false,\\"missingBucketLabel\\":\\"Missing\\"}},{\\"id\\":\\"4ce9b4c7-2ebf-4d48-8669-0ea69d973353\\",\\"enabled\\":true,\\"type\\":\\"count\\",\\"schema\\":\\"metric\\",\\"params\\":{}}]" | lens_rename_columns idMap="{\\"col-0-96352896-c508-4fca-90d8-66e9ebfce621\\":{\\"label\\":\\"Top values of geo.src\\",\\"dataType\\":\\"string\\",\\"operationType\\":\\"terms\\",\\"scale\\":\\"ordinal\\",\\"sourceField\\":\\"geo.src\\",\\"isBucketed\\":true,\\"params\\":{\\"size\\":5,\\"orderBy\\":{\\"type\\":\\"column\\",\\"columnId\\":\\"4ce9b4c7-2ebf-4d48-8669-0ea69d973353\\"},\\"orderDirection\\":\\"desc\\"},\\"id\\":\\"96352896-c508-4fca-90d8-66e9ebfce621\\"},\\"col-1-4ce9b4c7-2ebf-4d48-8669-0ea69d973353\\":{\\"label\\":\\"Count of records\\",\\"dataType\\":\\"number\\",\\"operationType\\":\\"count\\",\\"isBucketed\\":false,\\"scale\\":\\"ratio\\",\\"sourceField\\":\\"Records\\",\\"id\\":\\"4ce9b4c7-2ebf-4d48-8669-0ea69d973353\\"}}"}\n tables={esaggs index="ff959d40-b880-11e8-a6d9-e546fe2bba5f" metricsAtAllLevels=true partialRows=true includeFormatHints=true aggConfigs="[{\\"id\\":\\"77d8383e-f66e-471e-ae50-c427feedb5ba\\",\\"enabled\\":true,\\"type\\":\\"terms\\",\\"schema\\":\\"segment\\",\\"params\\":{\\"field\\":\\"geoip.country_iso_code\\",\\"orderBy\\":\\"a5c1b82d-51de-4448-a99d-6391432c3a03\\",\\"order\\":\\"desc\\",\\"size\\":5,\\"otherBucket\\":false,\\"otherBucketLabel\\":\\"Other\\",\\"missingBucket\\":false,\\"missingBucketLabel\\":\\"Missing\\"}},{\\"id\\":\\"a5c1b82d-51de-4448-a99d-6391432c3a03\\",\\"enabled\\":true,\\"type\\":\\"count\\",\\"schema\\":\\"metric\\",\\"params\\":{}}]" | lens_rename_columns idMap="{\\"col-0-77d8383e-f66e-471e-ae50-c427feedb5ba\\":{\\"label\\":\\"Top values of geoip.country_iso_code\\",\\"dataType\\":\\"string\\",\\"operationType\\":\\"terms\\",\\"scale\\":\\"ordinal\\",\\"sourceField\\":\\"geoip.country_iso_code\\",\\"isBucketed\\":true,\\"params\\":{\\"size\\":5,\\"orderBy\\":{\\"type\\":\\"column\\",\\"columnId\\":\\"a5c1b82d-51de-4448-a99d-6391432c3a03\\"},\\"orderDirection\\":\\"desc\\"},\\"id\\":\\"77d8383e-f66e-471e-ae50-c427feedb5ba\\"},\\"col-1-a5c1b82d-51de-4448-a99d-6391432c3a03\\":{\\"label\\":\\"Count of records\\",\\"dataType\\":\\"number\\",\\"operationType\\":\\"count\\",\\"isBucketed\\":false,\\"scale\\":\\"ratio\\",\\"sourceField\\":\\"Records\\",\\"id\\":\\"a5c1b82d-51de-4448-a99d-6391432c3a03\\"}}"}\n| lens_xy_chart xTitle="Top values of geo.src" yTitle="Count of records" legend={lens_xy_legendConfig isVisible=true position="right"} fittingFunction="None" \n layers={lens_xy_layer layerId="9a27f85d-35a9-4246-81b2-48e7ee9b0707" hide=false xAccessor="96352896-c508-4fca-90d8-66e9ebfce621" yScaleType="linear" xScaleType="ordinal" isHistogram=false seriesType="bar" accessors="4ce9b4c7-2ebf-4d48-8669-0ea69d973353" columnToLabel="{\\"4ce9b4c7-2ebf-4d48-8669-0ea69d973353\\":\\"Count of records\\"}"}\n layers={lens_xy_layer layerId="3b7791e9-326e-40d5-a787-b7594e48d906" hide=false xAccessor="77d8383e-f66e-471e-ae50-c427feedb5ba" yScaleType="linear" xScaleType="ordinal" isHistogram=false seriesType="bar" accessors="a5c1b82d-51de-4448-a99d-6391432c3a03" columnToLabel="{\\"a5c1b82d-51de-4448-a99d-6391432c3a03\\":\\"Count of records [1]\\"}"}', + state: { + datasourceMetaData: { + filterableIndexPatterns: [ + { id: '90943e30-9a47-11e8-b64d-95841ca0b247', title: 'kibana_sample_data_logs' }, + { id: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', title: 'kibana_sample_data_ecommerce' }, + ], + }, + datasourceStates: { + indexpattern: { + currentIndexPatternId: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', + layers: { + '3b7791e9-326e-40d5-a787-b7594e48d906': { + columnOrder: [ + '77d8383e-f66e-471e-ae50-c427feedb5ba', + 'a5c1b82d-51de-4448-a99d-6391432c3a03', + ], + columns: { + '77d8383e-f66e-471e-ae50-c427feedb5ba': { + dataType: 'string', + isBucketed: true, + label: 'Top values of geoip.country_iso_code', + operationType: 'terms', + params: { + orderBy: { + columnId: 'a5c1b82d-51de-4448-a99d-6391432c3a03', + type: 'column', + }, + orderDirection: 'desc', + size: 5, + }, + scale: 'ordinal', + sourceField: 'geoip.country_iso_code', + }, + 'a5c1b82d-51de-4448-a99d-6391432c3a03': { + dataType: 'number', + isBucketed: false, + label: 'Count of records', + operationType: 'count', + scale: 'ratio', + sourceField: 'Records', + }, + }, + indexPatternId: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', + }, + '9a27f85d-35a9-4246-81b2-48e7ee9b0707': { + columnOrder: [ + '96352896-c508-4fca-90d8-66e9ebfce621', + '4ce9b4c7-2ebf-4d48-8669-0ea69d973353', + ], + columns: { + '4ce9b4c7-2ebf-4d48-8669-0ea69d973353': { + dataType: 'number', + isBucketed: false, + label: 'Count of records', + operationType: 'count', + scale: 'ratio', + sourceField: 'Records', + }, + '96352896-c508-4fca-90d8-66e9ebfce621': { + dataType: 'string', + isBucketed: true, + label: 'Top values of geo.src', + operationType: 'terms', + params: { + orderBy: { + columnId: '4ce9b4c7-2ebf-4d48-8669-0ea69d973353', + type: 'column', + }, + orderDirection: 'desc', + size: 5, + }, + scale: 'ordinal', + sourceField: 'geo.src', + }, + }, + indexPatternId: '90943e30-9a47-11e8-b64d-95841ca0b247', + }, + }, + }, + }, + filters: [ + { + $state: { store: 'appState' }, + meta: { + alias: null, + disabled: false, + index: '90943e30-9a47-11e8-b64d-95841ca0b247', + key: 'geo.src', + negate: true, + params: { query: 'CN' }, + type: 'phrase', + }, + query: { match_phrase: { 'geo.src': 'CN' } }, + }, + { + $state: { store: 'appState' }, + meta: { + alias: null, + disabled: false, + index: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', + key: 'geoip.country_iso_code', + negate: true, + params: { query: 'US' }, + type: 'phrase', + }, + query: { match_phrase: { 'geoip.country_iso_code': 'US' } }, + }, + ], + query: { language: 'kuery', query: 'NOT bytes > 5000' }, + visualization: { + fittingFunction: 'None', + layers: [ + { + accessors: ['4ce9b4c7-2ebf-4d48-8669-0ea69d973353'], + layerId: '9a27f85d-35a9-4246-81b2-48e7ee9b0707', + position: 'top', + seriesType: 'bar', + showGridlines: false, + xAccessor: '96352896-c508-4fca-90d8-66e9ebfce621', + }, + { + accessors: ['a5c1b82d-51de-4448-a99d-6391432c3a03'], + layerId: '3b7791e9-326e-40d5-a787-b7594e48d906', + seriesType: 'bar', + xAccessor: '77d8383e-f66e-471e-ae50-c427feedb5ba', + }, + ], + legend: { isVisible: true, position: 'right' }, + preferredSeriesType: 'bar', + }, + }, + title: 'mylens', + visualizationType: 'lnsXY', + }, + type: 'lens', + }; + + it('should remove expression', () => { + const result = migrations['7.10.0'](example, context); + expect(result.attributes.expression).toBeUndefined(); + }); + + it('should list references for layers', () => { + const result = migrations['7.10.0'](example, context); + expect( + result.references?.find( + (ref) => ref.name === 'indexpattern-datasource-layer-3b7791e9-326e-40d5-a787-b7594e48d906' + )?.id + ).toEqual('ff959d40-b880-11e8-a6d9-e546fe2bba5f'); + expect( + result.references?.find( + (ref) => ref.name === 'indexpattern-datasource-layer-9a27f85d-35a9-4246-81b2-48e7ee9b0707' + )?.id + ).toEqual('90943e30-9a47-11e8-b64d-95841ca0b247'); + }); + + it('should remove index pattern ids from layers', () => { + const result = migrations['7.10.0'](example, context); + expect( + result.attributes.state.datasourceStates.indexpattern.layers[ + '3b7791e9-326e-40d5-a787-b7594e48d906' + ].indexPatternId + ).toBeUndefined(); + expect( + result.attributes.state.datasourceStates.indexpattern.layers[ + '9a27f85d-35a9-4246-81b2-48e7ee9b0707' + ].indexPatternId + ).toBeUndefined(); + }); + + it('should remove datsource meta data', () => { + const result = migrations['7.10.0'](example, context); + expect(result.attributes.state.datasourceMetaData).toBeUndefined(); + }); + + it('should list references for filters', () => { + const result = migrations['7.10.0'](example, context); + expect(result.references?.find((ref) => ref.name === 'filter-index-pattern-0')?.id).toEqual( + '90943e30-9a47-11e8-b64d-95841ca0b247' + ); + expect(result.references?.find((ref) => ref.name === 'filter-index-pattern-1')?.id).toEqual( + 'ff959d40-b880-11e8-a6d9-e546fe2bba5f' + ); + }); + + it('should remove index pattern ids from filters', () => { + const result = migrations['7.10.0'](example, context); + expect(result.attributes.state.filters[0].meta.index).toBeUndefined(); + expect(result.attributes.state.filters[0].meta.indexRefName).toEqual( + 'filter-index-pattern-0' + ); + expect(result.attributes.state.filters[1].meta.index).toBeUndefined(); + expect(result.attributes.state.filters[1].meta.indexRefName).toEqual( + 'filter-index-pattern-1' + ); + }); + + it('should list reference for current index pattern', () => { + const result = migrations['7.10.0'](example, context); + expect( + result.references?.find( + (ref) => ref.name === 'indexpattern-datasource-current-indexpattern' + )?.id + ).toEqual('ff959d40-b880-11e8-a6d9-e546fe2bba5f'); + }); + + it('should remove current index pattern id from datasource state', () => { + const result = migrations['7.10.0'](example, context); + expect( + result.attributes.state.datasourceStates.indexpattern.currentIndexPatternId + ).toBeUndefined(); + }); + + it('should produce a valid document', () => { + const result = migrations['7.10.0'](example, context); + // changes to the outcome of this are critical - this test is a safe guard to not introduce changes accidentally + // if this test fails, make extra sure it's expected + expect(result).toMatchSnapshot(); + }); + }); }); diff --git a/x-pack/plugins/lens/server/migrations.ts b/x-pack/plugins/lens/server/migrations.ts index d24a3e92cbd9c..fdbfa1e455f60 100644 --- a/x-pack/plugins/lens/server/migrations.ts +++ b/x-pack/plugins/lens/server/migrations.ts @@ -6,11 +6,16 @@ import { cloneDeep } from 'lodash'; import { fromExpression, toExpression, Ast, ExpressionFunctionAST } from '@kbn/interpreter/common'; -import { SavedObjectMigrationMap, SavedObjectMigrationFn } from 'src/core/server'; +import { + SavedObjectMigrationMap, + SavedObjectMigrationFn, + SavedObjectReference, + SavedObjectUnsanitizedDoc, +} from 'src/core/server'; +import { Query, Filter } from 'src/plugins/data/public'; +import { PersistableFilter } from '../common'; -interface LensDocShape { - id?: string; - type?: string; +interface LensDocShapePre710 { visualizationType: string | null; title: string; expression: string | null; @@ -21,18 +26,44 @@ interface LensDocShape { datasourceStates: { // This is hardcoded as our only datasource indexpattern: { + currentIndexPatternId: string; layers: Record< string, { columnOrder: string[]; columns: Record; + indexPatternId: string; } >; }; }; visualization: VisualizationState; - query: unknown; - filters: unknown[]; + query: Query; + filters: Filter[]; + }; +} + +interface LensDocShape { + id?: string; + type?: string; + visualizationType: string | null; + title: string; + state: { + datasourceStates: { + // This is hardcoded as our only datasource + indexpattern: { + layers: Record< + string, + { + columnOrder: string[]; + columns: Record; + } + >; + }; + }; + visualization: VisualizationState; + query: Query; + filters: PersistableFilter[]; }; } @@ -55,7 +86,10 @@ interface XYStatePost77 { * Removes the `lens_auto_date` subexpression from a stored expression * string. For example: aggConfigs={lens_auto_date aggConfigs="JSON string"} */ -const removeLensAutoDate: SavedObjectMigrationFn = (doc, context) => { +const removeLensAutoDate: SavedObjectMigrationFn = ( + doc, + context +) => { const expression = doc.attributes.expression; if (!expression) { return doc; @@ -112,7 +146,10 @@ const removeLensAutoDate: SavedObjectMigrationFn = ( /** * Adds missing timeField arguments to esaggs in the Lens expression */ -const addTimeFieldToEsaggs: SavedObjectMigrationFn = (doc, context) => { +const addTimeFieldToEsaggs: SavedObjectMigrationFn = ( + doc, + context +) => { const expression = doc.attributes.expression; if (!expression) { return doc; @@ -174,14 +211,14 @@ const addTimeFieldToEsaggs: SavedObjectMigrationFn = }; const removeInvalidAccessors: SavedObjectMigrationFn< - LensDocShape, - LensDocShape + LensDocShapePre710, + LensDocShapePre710 > = (doc) => { const newDoc = cloneDeep(doc); if (newDoc.attributes.visualizationType === 'lnsXY') { const datasourceLayers = newDoc.attributes.state.datasourceStates.indexpattern.layers || {}; const xyState = newDoc.attributes.state.visualization; - (newDoc.attributes as LensDocShape< + (newDoc.attributes as LensDocShapePre710< XYStatePost77 >).state.visualization.layers = xyState.layers.map((layer: XYLayerPre77) => { const layerId = layer.layerId; @@ -197,9 +234,86 @@ const removeInvalidAccessors: SavedObjectMigrationFn< return newDoc; }; +const extractReferences: SavedObjectMigrationFn = ({ + attributes, + references, + ...docMeta +}) => { + const savedObjectReferences: SavedObjectReference[] = []; + // add currently selected index pattern to reference list + savedObjectReferences.push({ + type: 'index-pattern', + id: attributes.state.datasourceStates.indexpattern.currentIndexPatternId, + name: 'indexpattern-datasource-current-indexpattern', + }); + + // add layer index patterns to list and remove index pattern ids from layers + const persistableLayers: Record< + string, + Omit< + LensDocShapePre710['state']['datasourceStates']['indexpattern']['layers'][string], + 'indexPatternId' + > + > = {}; + Object.entries(attributes.state.datasourceStates.indexpattern.layers).forEach( + ([layerId, { indexPatternId, ...persistableLayer }]) => { + savedObjectReferences.push({ + type: 'index-pattern', + id: indexPatternId, + name: `indexpattern-datasource-layer-${layerId}`, + }); + persistableLayers[layerId] = persistableLayer; + } + ); + + // add filter index patterns to reference list and remove index pattern ids from filter definitions + const persistableFilters = attributes.state.filters.map((filterRow, i) => { + if (!filterRow.meta || !filterRow.meta.index) { + return filterRow; + } + const refName = `filter-index-pattern-${i}`; + savedObjectReferences.push({ + name: refName, + type: 'index-pattern', + id: filterRow.meta.index, + }); + return { + ...filterRow, + meta: { + ...filterRow.meta, + indexRefName: refName, + index: undefined, + }, + }; + }); + + // put together new saved object format + const newDoc: SavedObjectUnsanitizedDoc = { + ...docMeta, + references: savedObjectReferences, + attributes: { + visualizationType: attributes.visualizationType, + title: attributes.title, + state: { + datasourceStates: { + indexpattern: { + layers: persistableLayers, + }, + }, + visualization: attributes.state.visualization, + query: attributes.state.query, + filters: persistableFilters, + }, + }, + }; + + return newDoc; +}; + export const migrations: SavedObjectMigrationMap = { '7.7.0': removeInvalidAccessors, // The order of these migrations matter, since the timefield migration relies on the aggConfigs // sitting directly on the esaggs as an argument and not a nested function (which lens_auto_date was). '7.8.0': (doc, context) => addTimeFieldToEsaggs(removeLensAutoDate(doc, context), context), + '7.10.0': extractReferences, }; From 3031e668060ad56124a0f191f1c03cea71532697 Mon Sep 17 00:00:00 2001 From: Jen Huang Date: Fri, 21 Aug 2020 09:16:17 -0700 Subject: [PATCH 28/45] Update datasets UI copy to data streams (#75618) --- x-pack/plugins/ingest_manager/dev_docs/definitions.md | 6 +++--- .../ingest_manager/constants/page_paths.ts | 4 ++-- .../ingest_manager/hooks/use_breadcrumbs.tsx | 2 +- .../applications/ingest_manager/layouts/default.tsx | 2 +- .../sections/data_stream/list_page/index.tsx | 10 +++++----- .../standalone_instructions.tsx | 2 +- .../overview/components/datastream_section.tsx | 8 ++++---- .../public/applications/ingest_manager/types/index.ts | 2 +- 8 files changed, 18 insertions(+), 18 deletions(-) diff --git a/x-pack/plugins/ingest_manager/dev_docs/definitions.md b/x-pack/plugins/ingest_manager/dev_docs/definitions.md index be5aeb923e903..d9ff597c5e84b 100644 --- a/x-pack/plugins/ingest_manager/dev_docs/definitions.md +++ b/x-pack/plugins/ingest_manager/dev_docs/definitions.md @@ -13,9 +13,9 @@ definitions for one or multiple inputs and each input can contain one or multipl With the example of the nginx Package policy, it contains two inputs: `logs` and `nginx/metrics`. Logs and metrics are collected differently. The `logs` input contains two streams, `access` and `error`, the `nginx/metrics` input contains the stubstatus stream. -## Data Stream +## Data stream -Data Streams are a [new concept](https://github.com/elastic/elasticsearch/issues/53100) in Elasticsearch which simplify +Data streams are a [new concept](https://github.com/elastic/elasticsearch/issues/53100) in Elasticsearch which simplify ingesting data and the setup of Elasticsearch. ## Elastic Agent @@ -35,7 +35,7 @@ Fleet is the part of the Ingest Manager UI in Kibana that handles the part of en Ingest Management + Elastic Agent follow a strict new indexing strategy: `{type}-{dataset}-{namespace}`. An example for this is `logs-nginx.access-default`. More details about it can be found in the Index Strategy below. All data of -the index strategy is sent to Data Streams. +the index strategy is sent to data streams. ## Input diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/constants/page_paths.ts b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/constants/page_paths.ts index 4a8dcfedc0936..c370f46b9f5a0 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/constants/page_paths.ts +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/constants/page_paths.ts @@ -53,7 +53,7 @@ export const PAGE_ROUTING_PATHS = { fleet_agent_details_events: '/fleet/agents/:agentId', fleet_agent_details_details: '/fleet/agents/:agentId/details', fleet_enrollment_tokens: '/fleet/enrollment-tokens', - data_streams: '/datasets', + data_streams: '/data-streams', }; export const pagePathGetters: { @@ -80,5 +80,5 @@ export const pagePathGetters: { fleet_agent_details: ({ agentId, tabId }) => `/fleet/agents/${agentId}${tabId ? `/${tabId}` : ''}`, fleet_enrollment_tokens: () => '/fleet/enrollment-tokens', - data_streams: () => '/datasets', + data_streams: () => '/data-streams', }; diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/hooks/use_breadcrumbs.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/hooks/use_breadcrumbs.tsx index 6ef1351dc5b60..1d80495d2b347 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/hooks/use_breadcrumbs.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/hooks/use_breadcrumbs.tsx @@ -207,7 +207,7 @@ const breadcrumbGetters: { BASE_BREADCRUMB, { text: i18n.translate('xpack.ingestManager.breadcrumbs.datastreamsPageTitle', { - defaultMessage: 'Datasets', + defaultMessage: 'Data streams', }), }, ], diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/layouts/default.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/layouts/default.tsx index 726da7a790b97..30294779d1a3d 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/layouts/default.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/layouts/default.tsx @@ -96,7 +96,7 @@ export const DefaultLayout: React.FunctionComponent = ({ diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/data_stream/list_page/index.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/data_stream/list_page/index.tsx index d8ab46fbf87f7..53fd6a713b523 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/data_stream/list_page/index.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/data_stream/list_page/index.tsx @@ -32,7 +32,7 @@ const DataStreamListPageLayout: React.FunctionComponent = ({ children }) => (

@@ -173,7 +173,7 @@ export const DataStreamListPage: React.FunctionComponent<{}> = () => {

} @@ -216,14 +216,14 @@ export const DataStreamListPage: React.FunctionComponent<{}> = () => { isLoading ? ( ) : dataStreamsData && !dataStreamsData.data_streams.length ? ( emptyPrompt ) : ( ) } @@ -253,7 +253,7 @@ export const DataStreamListPage: React.FunctionComponent<{}> = () => { placeholder: i18n.translate( 'xpack.ingestManager.dataStreamList.searchPlaceholderTitle', { - defaultMessage: 'Filter datasets', + defaultMessage: 'Filter data streams', } ), incremental: true, diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_enrollment_flyout/standalone_instructions.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_enrollment_flyout/standalone_instructions.tsx index abe834e7db19c..049ceca82b309 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_enrollment_flyout/standalone_instructions.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_enrollment_flyout/standalone_instructions.tsx @@ -157,7 +157,7 @@ export const StandaloneInstructions: React.FunctionComponent = ({ agentPo diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/overview/components/datastream_section.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/overview/components/datastream_section.tsx index 41c011de2da5c..bece6ec074b88 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/overview/components/datastream_section.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/overview/components/datastream_section.tsx @@ -47,14 +47,14 @@ export const OverviewDatastreamSection: React.FC = () => { @@ -65,7 +65,7 @@ export const OverviewDatastreamSection: React.FC = () => { diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/types/index.ts b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/types/index.ts index 80e27b7c4d0bf..30a6742af6ea6 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/types/index.ts +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/types/index.ts @@ -43,7 +43,7 @@ export { CreatePackagePolicyResponse, UpdatePackagePolicyRequest, UpdatePackagePolicyResponse, - // API schemas - Data Streams + // API schemas - Data streams GetDataStreamsResponse, // API schemas - Agents GetAgentsResponse, From 82e30f6effdecbc8d9c6a7d4a5f53fb267b60541 Mon Sep 17 00:00:00 2001 From: Greg Thompson Date: Fri, 21 Aug 2020 10:48:04 -0600 Subject: [PATCH 29/45] Upgrade EUI to v27.4.1 (#75240) * eui to 27.4.1 * src snapshot updates * x-pack snapshot updates * remove increased default timeout * revert date change * delete default_timeout file * reinstate storyshot Co-authored-by: Elastic Machine --- package.json | 2 +- packages/kbn-ui-shared-deps/package.json | 2 +- .../collapsible_nav.test.tsx.snap | 7748 +++++------------ .../header/__snapshots__/header.test.tsx.snap | 1281 ++- .../flyout_service.test.tsx.snap | 4 +- .../__snapshots__/modal_service.test.tsx.snap | 6 +- src/dev/jest/config.js | 1 - src/dev/jest/setup/default_timeout.js | 25 - .../__snapshots__/new_vis_modal.test.tsx.snap | 5080 +++-------- .../plugins/kbn_tp_run_pipeline/package.json | 2 +- .../kbn_sample_panel_action/package.json | 2 +- .../kbn_tp_custom_visualizations/package.json | 2 +- x-pack/dev-tools/jest/create_jest_config.js | 1 - x-pack/package.json | 2 +- .../TransactionActionMenu.test.tsx.snap | 5 +- .../asset_manager.stories.storyshot | 1052 +-- .../custom_element_modal.stories.storyshot | 1888 ++-- .../keyboard_shortcuts_doc.stories.storyshot | 2207 +++-- .../saved_elements_modal.stories.storyshot | 1362 ++- .../__snapshots__/settings.test.tsx.snap | 898 +- .../upload_license.test.tsx.snap | 989 +-- .../report_info_button.test.tsx.snap | 1236 +-- .../helpers/home.helpers.ts | 2 +- .../__snapshots__/ml_flyout.test.tsx.snap | 261 +- yarn.lock | 8 +- 25 files changed, 7978 insertions(+), 16088 deletions(-) delete mode 100644 src/dev/jest/setup/default_timeout.js diff --git a/package.json b/package.json index 23fc31f369b8d..46418e52d8548 100644 --- a/package.json +++ b/package.json @@ -128,7 +128,7 @@ "@elastic/datemath": "5.0.3", "@elastic/elasticsearch": "7.9.0-rc.2", "@elastic/ems-client": "7.9.3", - "@elastic/eui": "27.4.0", + "@elastic/eui": "27.4.1", "@elastic/filesaver": "1.1.2", "@elastic/good": "8.1.1-kibana2", "@elastic/numeral": "^2.5.0", diff --git a/packages/kbn-ui-shared-deps/package.json b/packages/kbn-ui-shared-deps/package.json index a37281cb2263f..531513481b1d4 100644 --- a/packages/kbn-ui-shared-deps/package.json +++ b/packages/kbn-ui-shared-deps/package.json @@ -10,7 +10,7 @@ }, "dependencies": { "@elastic/charts": "19.8.1", - "@elastic/eui": "27.4.0", + "@elastic/eui": "27.4.1", "@elastic/numeral": "^2.5.0", "@kbn/i18n": "1.0.0", "@kbn/monaco": "1.0.0", diff --git a/src/core/public/chrome/ui/header/__snapshots__/collapsible_nav.test.tsx.snap b/src/core/public/chrome/ui/header/__snapshots__/collapsible_nav.test.tsx.snap index 72d62730fa698..2cfe232bf5653 100644 --- a/src/core/public/chrome/ui/header/__snapshots__/collapsible_nav.test.tsx.snap +++ b/src/core/public/chrome/ui/header/__snapshots__/collapsible_nav.test.tsx.snap @@ -378,9 +378,7 @@ exports[`CollapsibleNav renders links grouped by category 1`] = ` + +
+
+ +
+ +
+
- +
- } - onActivation={[Function]} - onDeactivation={[Function]} - persistentFocus={false} - returnFocus={[Function]} - shards={Array []} - sideCar={ - Object { - "assignMedium": [Function], - "assignSyncMedium": [Function], - "options": Object { - "async": true, - "ssr": false, - }, - "read": [Function], - "useMedium": [Function], - } - } + + + + + +
+
+ +
+ + + + + - - -
- } - onActivation={[Function]} - onDeactivation={[Function]} - persistentFocus={false} - returnFocus={[Function]} - shards={Array []} +

- - + Recently viewed +

+
- } - onActivation={[Function]} - onDeactivation={[Function]} - persistentFocus={false} - returnFocus={[Function]} - shards={Array []} - /> - - - - + +
+ + + +
+ -
-
+
+ + + + + + +
+
+ +
+ + + + + + + -
- - + Kibana + +
+
+ + } + className="euiCollapsibleNavGroup euiCollapsibleNavGroup--withHeading" + data-test-subj="collapsibleNavGroup-kibana" + id="mockId" + initialIsOpen={true} + onToggle={[Function]} + paddingSize="none" + > +
+
+ +
+
+ +
+
-
- -
-
- -
-
+ visualize + + + + + +
  • -
    - - - -
    -
  • -
    -
    -
    + dashboard + + + + + +
    - - - +
    + +
    +
    + + + + + + + + + +

    + Observability +

    +
    +
    + + } + className="euiCollapsibleNavGroup euiCollapsibleNavGroup--withHeading" + data-test-subj="collapsibleNavGroup-observability" + id="mockId" + initialIsOpen={true} + onToggle={[Function]} + paddingSize="none" + > +
    +
    + -
    -
    + +
    + + +
    + - -
    -
    -
    - - - -
    -
    -
    -
    -
    + Observability + +
    -
    -
    - +
    + + + +
    +
    + +
    +
    +
    - - - - - - -

    - Observability -

    -
    -
    - + -
    -
    - -
    -
    + + + + - -
    -
    + -
    - - - -
    -
    -
    -
    -
    -
    -
    - - + + + + + +
    +
    +
    +
    +
    + + + + + + + + + + +

    + Security +

    +
    +
    + + } + className="euiCollapsibleNavGroup euiCollapsibleNavGroup--withHeading" + data-test-subj="collapsibleNavGroup-security" + id="mockId" + initialIsOpen={true} + onToggle={[Function]} + paddingSize="none" + > +
    +
    + -
    -
    + +
    + + +
    + - -
    -
    -
    - - - -
    -
    -
    -
    -
    + Security + +
    -
    -
    - + + + + + +
    + +
    +
    +
    - - - -

    - Management -

    -
    -
    - + -
    -
    - -
    -
    + + + + + +
    +
    +
    + +
    +
    + + + + + + +

    + Management +

    +
    +
    + + } + className="euiCollapsibleNavGroup euiCollapsibleNavGroup--withHeading" + data-test-subj="collapsibleNavGroup-management" + id="mockId" + initialIsOpen={true} + onToggle={[Function]} + paddingSize="none" + > +
    +
    + +
    +
    + +
    +
    +
    -
    -
    - - - -
    -
    - - + + + + + +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    + + + +
    +
    +
    + + +
    +
    + +
      +
      + - -
        - -
        - - Dock navigation - - , - } - } - color="subdued" - data-test-subj="collapsible-nav-lock" - iconType="lockOpen" - label="Dock navigation" - onClick={[Function]} - size="xs" - > -
      • - -
      • - -
      -
      -
      -
    - - -
    - - - + , } } + color="subdued" + data-test-subj="collapsible-nav-lock" + iconType="lockOpen" + label="Dock navigation" + onClick={[Function]} + size="xs" > - - - - + + + + +
    - -
    - - + + +
    +
    + + + + + + + @@ -5439,621 +2471,442 @@ exports[`CollapsibleNav renders the default nav 2`] = ` clickOutsideDisables={true} disabled={false} > - - -
    - - - +
    -
    - -
    -
    +
    + +
    + + + + + +

    + Recently viewed +

    +
    +
    + + } + className="euiCollapsibleNavGroup euiCollapsibleNavGroup--light euiCollapsibleNavGroup--withHeading" + data-test-subj="collapsibleNavGroup-recentlyViewed" + id="mockId" + initialIsOpen={true} + onToggle={[Function]} + paddingSize="none" + > +
    +
    + -
    -
    - -
    -
    -
    - -
    - -
    -

    - No recently viewed items -

    -
    -
    -
    -
    -
    -
    -
    -
    -
    + Recently viewed + +
    -
    -
    - -
    -
    - +
    + + + +
    +
    + +
    +
    +
    -
    - -
    -
    - -
      - -
      - - Dock navigation - - , - } - } - color="subdued" - data-test-subj="collapsible-nav-lock" - iconType="lockOpen" - label="Dock navigation" - onClick={[Function]} - size="xs" - > -
    • - -
    • - -
    -
    -
    +

    + No recently viewed items +

    -
    -
    -
    - - +
    + +
    +
    +
    + + + + + + +
    +
    + +
    + + +
    +
    + +
      - +
      + + Dock navigation + + , } } + color="subdued" + data-test-subj="collapsible-nav-lock" + iconType="lockOpen" + label="Dock navigation" + onClick={[Function]} + size="xs" > - - - - + + + +
    +
    - -
    - - + + +
    + + + +
    - - +
    + + + + close + + + + + + + + +
    @@ -6299,581 +3152,442 @@ exports[`CollapsibleNav renders the default nav 3`] = ` clickOutsideDisables={true} disabled={true} > - - -
    - - - +
    -
    + - + + +
    +
    + +
    + + + + + +

    + Recently viewed +

    +
    +
    + + } + className="euiCollapsibleNavGroup euiCollapsibleNavGroup--light euiCollapsibleNavGroup--withHeading" + data-test-subj="collapsibleNavGroup-recentlyViewed" + id="mockId" + initialIsOpen={true} + onToggle={[Function]} + paddingSize="none" + > +
    +
    + +
    +
    + +
    +
    +
    + - -
    - - - +

    + No recently viewed items +

    -
    -
    -
    - - +
    + +
    +
    +
    + +
    +
    + + + +
    +
    + +
    + + +
    +
    + +
      - - - -

      - Recently viewed -

      -
      -
      - - } - className="euiCollapsibleNavGroup euiCollapsibleNavGroup--light euiCollapsibleNavGroup--withHeading" - data-test-subj="collapsibleNavGroup-recentlyViewed" - id="mockId" - initialIsOpen={true} - onToggle={[Function]} - paddingSize="none" - > -
      -
      - -
      -
      - -
      -
      -
      - -
      - -
      -

      - No recently viewed items -

      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      - - -
      -
      - -
      - , } - > - -
      -
      - -
        - -
        - - Undock navigation - - , - } - } - color="subdued" - data-test-subj="collapsible-nav-lock" - iconType="lock" - label="Undock navigation" - onClick={[Function]} - size="xs" - > -
      • - -
      • - -
      -
      -
      -
      -
      -
      -
      -
      - - - - - - + + + +
    +
    - -
    + + +
    + + + +
    - - + } + > + + +
    + + + + close + + + + + + + + +
    diff --git a/src/core/public/chrome/ui/header/__snapshots__/header.test.tsx.snap b/src/core/public/chrome/ui/header/__snapshots__/header.test.tsx.snap index a1920154d9f71..c02a763c40101 100644 --- a/src/core/public/chrome/ui/header/__snapshots__/header.test.tsx.snap +++ b/src/core/public/chrome/ui/header/__snapshots__/header.test.tsx.snap @@ -8999,766 +8999,635 @@ exports[`Header renders 3`] = ` clickOutsideDisables={true} disabled={true} > - - -
    - - - +
    + +
      + +
    • + +
    • +
      +
    +
    +
    +
    + +
    + + +
    +
    + +
    + +
    + } + >
    - -
    -
    +
    + +
    + + + + + +

    + Recently viewed +

    +
    +
    + + } + className="euiCollapsibleNavGroup euiCollapsibleNavGroup--light euiCollapsibleNavGroup--withHeading" + data-test-subj="collapsibleNavGroup-recentlyViewed" + id="mockId" + initialIsOpen={true} + onToggle={[Function]} + paddingSize="none" + > +
    +
    + +
    +
    + +
    +
    +
    -
    - -
    -
    - - - -
    -
    -
    -
    - - + + + + + +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    + +
    + +
    +
    + +
      + - - - -

      - Recently viewed -

      -
      -
      - - } - className="euiCollapsibleNavGroup euiCollapsibleNavGroup--light euiCollapsibleNavGroup--withHeading" - data-test-subj="collapsibleNavGroup-recentlyViewed" - id="mockId" - initialIsOpen={true} - onToggle={[Function]} - paddingSize="none" +
    • -
      -
      - +
    • +
      +
    +
    +
    +
    +
    + + +
    +
    + +
      + +
      - -
      - - - - -
      - -
      - -

      - Recently viewed -

      -
      -
      -
      -
      -
      + Undock navigation
      - -
      -
      - -
      -
      -
      - - - -
      -
      -
      -
      -
      -
      - - - -
      -
      - -
      - -
      -
      - -
        - -
      • - -
      • -
        -
      -
      -
      -
      -
      - , } - > - -
      -
      - -
        - -
        - - Undock navigation - - , - } - } - color="subdued" - data-test-subj="collapsible-nav-lock" - iconType="lock" - label="Undock navigation" - onClick={[Function]} - size="xs" - > -
      • - -
      • - -
      -
      -
      -
      -
      -
      -
      -
      - - - - - - + + +
      +
    +
    - -
    + + +
    + + + +
    - - + } + > + + +
    + + + + close + + + + + + + + +
    diff --git a/src/core/public/overlays/flyout/__snapshots__/flyout_service.test.tsx.snap b/src/core/public/overlays/flyout/__snapshots__/flyout_service.test.tsx.snap index fa83b34e06b81..a5c1d46f74709 100644 --- a/src/core/public/overlays/flyout/__snapshots__/flyout_service.test.tsx.snap +++ b/src/core/public/overlays/flyout/__snapshots__/flyout_service.test.tsx.snap @@ -26,7 +26,7 @@ Array [ ] `; -exports[`FlyoutService openFlyout() renders a flyout to the DOM 2`] = `"
    Flyout content
    "`; +exports[`FlyoutService openFlyout() renders a flyout to the DOM 2`] = `"
    Flyout content
    "`; exports[`FlyoutService openFlyout() with a currently active flyout replaces the current flyout with a new one 1`] = ` Array [ @@ -59,4 +59,4 @@ Array [ ] `; -exports[`FlyoutService openFlyout() with a currently active flyout replaces the current flyout with a new one 2`] = `"
    Flyout content 2
    "`; +exports[`FlyoutService openFlyout() with a currently active flyout replaces the current flyout with a new one 2`] = `"
    Flyout content 2
    "`; diff --git a/src/core/public/overlays/modal/__snapshots__/modal_service.test.tsx.snap b/src/core/public/overlays/modal/__snapshots__/modal_service.test.tsx.snap index fb00ddc38c6dc..aea52eb8e7ab7 100644 --- a/src/core/public/overlays/modal/__snapshots__/modal_service.test.tsx.snap +++ b/src/core/public/overlays/modal/__snapshots__/modal_service.test.tsx.snap @@ -31,7 +31,7 @@ Array [ ] `; -exports[`ModalService openConfirm() renders a mountpoint confirm message 2`] = `"
    Modal content
    "`; +exports[`ModalService openConfirm() renders a mountpoint confirm message 2`] = `"
    Modal content
    "`; exports[`ModalService openConfirm() renders a string confirm message 1`] = ` Array [ @@ -53,7 +53,7 @@ Array [ ] `; -exports[`ModalService openConfirm() renders a string confirm message 2`] = `"

    Some message

    "`; +exports[`ModalService openConfirm() renders a string confirm message 2`] = `"

    Some message

    "`; exports[`ModalService openConfirm() with a currently active confirm replaces the current confirm with the new one 1`] = ` Array [ @@ -145,7 +145,7 @@ Array [ ] `; -exports[`ModalService openModal() renders a modal to the DOM 2`] = `"
    Modal content
    "`; +exports[`ModalService openModal() renders a modal to the DOM 2`] = `"
    Modal content
    "`; exports[`ModalService openModal() with a currently active confirm replaces the current confirm with the new one 1`] = ` Array [ diff --git a/src/dev/jest/config.js b/src/dev/jest/config.js index d46b955f6668d..74e1ec5e2b4ed 100644 --- a/src/dev/jest/config.js +++ b/src/dev/jest/config.js @@ -78,7 +78,6 @@ export default { setupFilesAfterEnv: [ '/src/dev/jest/setup/mocks.js', '/src/dev/jest/setup/react_testing_library.js', - '/src/dev/jest/setup/default_timeout.js', ], coverageDirectory: '/target/kibana-coverage/jest', coverageReporters: !!process.env.CODE_COVERAGE ? ['json'] : ['html', 'text'], diff --git a/src/dev/jest/setup/default_timeout.js b/src/dev/jest/setup/default_timeout.js deleted file mode 100644 index eea38e745b960..0000000000000 --- a/src/dev/jest/setup/default_timeout.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/* eslint-env jest */ - -/** - * Set the default timeout for the unit tests to 30 seconds, temporarily - */ -jest.setTimeout(30 * 1000); diff --git a/src/plugins/visualizations/public/wizard/__snapshots__/new_vis_modal.test.tsx.snap b/src/plugins/visualizations/public/wizard/__snapshots__/new_vis_modal.test.tsx.snap index a27dfa13e743e..6aed16e937713 100644 --- a/src/plugins/visualizations/public/wizard/__snapshots__/new_vis_modal.test.tsx.snap +++ b/src/plugins/visualizations/public/wizard/__snapshots__/new_vis_modal.test.tsx.snap @@ -142,21 +142,7 @@ exports[`NewVisModal filter for visualization types should render as expected 1` class="euiOverlayMask euiOverlayMask--aboveHeader" >