[kbn/plugin-helpers] typescript-ify (#66513)

This commit is contained in:
Spencer 2020-05-15 10:35:44 -07:00 committed by GitHub
parent aca45a7fac
commit 4e0921d41e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
68 changed files with 660 additions and 586 deletions

View file

@ -493,7 +493,6 @@ module.exports = {
'.eslintrc.js',
'**/webpackShims/**/*.js',
'packages/kbn-plugin-generator/**/*.js',
'packages/kbn-plugin-helpers/**/*.js',
'packages/kbn-eslint-import-resolver-kibana/**/*.js',
'packages/kbn-eslint-plugin-eslint/**/*',
'x-pack/gulpfile.js',

View file

@ -25,4 +25,4 @@ if (nodeMajorVersion < 6) {
process.exit(1);
}
require('../cli');
require('../target/cli');

View file

@ -1,26 +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.
*/
export function babelRegister(): void;
export function resolveKibanaPath(path: string): string;
export function readFtrConfigFile(path: string): any;
export function run(
task: 'build' | 'start' | 'testAll' | 'testKarma' | 'testMocha' | 'postinstall',
options: any
): Promise<void>;

View file

@ -1,32 +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 run = require('./run');
const utils = require('./utils');
module.exports = function() {
console.error(
'running tasks with the default export of @kbn/plugin-helpers is deprecated.' +
"use `require('@kbn/plugin-helpers').run()` instead"
);
return run.apply(this, arguments);
};
Object.assign(module.exports, { run: run }, utils);

View file

@ -1,58 +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*/
jest.mock('./plugin_config', () => () => ({ id: 'testPlugin' }));
jest.mock('./tasks', () => {
return { testTask: jest.fn() };
});
const run = require('./run');
describe('lib/run', () => {
beforeEach(() => jest.resetAllMocks());
it('throw given an invalid task', function() {
const invalidTaskName = 'thisisnotavalidtasknameandneverwillbe';
const runner = () => run(invalidTaskName);
expect(runner).toThrow(/invalid task/i);
});
it('runs specified task with plugin and runner', function() {
run('testTask');
const { testTask } = require('./tasks');
const plugin = require('./plugin_config')();
const args = testTask.mock.calls[0];
expect(testTask.mock.calls).toHaveLength(1);
expect(args[0]).toEqual(plugin);
expect(args[1]).toBe(run);
});
it('returns value returned by task', function() {
const { testTask } = require('./tasks');
const symbol = Symbol('foo');
testTask.mockReturnValue(symbol);
expect(run('testTask')).toBe(symbol);
});
});

View file

@ -1,24 +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 platform = require('os').platform();
module.exports = function winCmd(cmd) {
return /^win/.test(platform) ? cmd + '.cmd' : cmd;
};

View file

@ -1,17 +1,16 @@
{
"name": "@kbn/plugin-helpers",
"private": true,
"version": "9.0.2",
"private": true,
"description": "Just some helpers for kibana plugin devs.",
"main": "lib/index.js",
"license": "Apache-2.0",
"main": "target/lib/index.js",
"scripts": {
"kbn:bootstrap": "tsc"
},
"bin": {
"plugin-helpers": "bin/plugin-helpers.js"
},
"author": "Spencer Alger <email@spalger.com>",
"license": "Apache-2.0",
"peerDependencies": {
"@kbn/babel-preset": "1.0.0"
},
"dependencies": {
"@babel/core": "^7.9.0",
"argv-split": "^2.0.1",
@ -27,6 +26,20 @@
"node-sass": "^4.13.1",
"through2": "^2.0.3",
"through2-map": "^3.0.0",
"vinyl": "^2.2.0",
"vinyl-fs": "^3.0.3"
},
"devDependencies": {
"@types/gulp-rename": "^0.0.33",
"@types/gulp-zip": "^4.0.1",
"@types/inquirer": "^6.5.0",
"@types/node-sass": "^4.11.0",
"@types/through2": "^2.0.35",
"@types/through2-map": "^3.0.0",
"@types/vinyl": "^2.0.4",
"typescript": "3.7.2"
},
"peerDependencies": {
"@kbn/babel-preset": "1.0.0"
}
}

View file

@ -17,13 +17,16 @@
* under the License.
*/
const program = require('commander');
import Fs from 'fs';
import Path from 'path';
const pkg = require('./package.json');
const createCommanderAction = require('./lib/commander_action');
const docs = require('./lib/docs');
const enableCollectingUnknownOptions = require('./lib/enable_collecting_unknown_options');
import program from 'commander';
import { createCommanderAction } from './lib/commander_action';
import { docs } from './lib/docs';
import { enableCollectingUnknownOptions } from './lib/enable_collecting_unknown_options';
const pkg = JSON.parse(Fs.readFileSync(Path.resolve(__dirname, '../package.json'), 'utf8'));
program.version(pkg.version);
enableCollectingUnknownOptions(
@ -55,7 +58,7 @@ program
buildVersion: command.buildVersion,
kibanaVersion: command.kibanaVersion,
skipArchive: Boolean(command.skipArchive),
files: files,
files,
}))
);
@ -84,7 +87,7 @@ program
.on('--help', docs('test/mocha'))
.action(
createCommanderAction('testMocha', (command, files) => ({
files: files,
files,
}))
);

View file

@ -17,12 +17,10 @@
* under the License.
*/
/*eslint-env jest*/
import { createCommanderAction } from './commander_action';
import { run } from './run';
const createCommanderAction = require('./commander_action');
const run = require('./run');
jest.mock('./run', () => jest.fn());
jest.mock('./run');
const STACK_TRACE_RE = /\n(?:\s+at .+(?:\n|$))+/g;
expect.addSnapshotSerializer({

View file

@ -17,10 +17,13 @@
* under the License.
*/
const run = require('./run');
import { run } from './run';
import { Tasks } from './tasks';
module.exports = function createCommanderAction(taskName, getOptions = () => {}) {
return async (...args) => {
type GetOptions = (command: any, ...args: string[]) => any;
export function createCommanderAction(taskName: keyof Tasks, getOptions: GetOptions = () => {}) {
return async (...args: string[]) => {
try {
// command is the last arg passed by commander, but we move it to the front of the list
const command = args.pop();
@ -30,4 +33,4 @@ module.exports = function createCommanderAction(taskName, getOptions = () => {})
process.exit(1);
}
};
};
}

View file

@ -17,33 +17,34 @@
* under the License.
*/
const resolve = require('path').resolve;
const readFileSync = require('fs').readFileSync;
import { resolve } from 'path';
import { readFileSync } from 'fs';
const configFiles = ['.kibana-plugin-helpers.json', '.kibana-plugin-helpers.dev.json'];
const configCache = {};
const configFileNames = ['.kibana-plugin-helpers.json', '.kibana-plugin-helpers.dev.json'];
module.exports = function(root) {
if (!root) root = process.cwd();
interface Config {
[key: string]: unknown;
}
if (configCache[root]) {
return configCache[root];
const configCache = new Map<string, Config>();
export function configFile(root: string = process.cwd()) {
if (configCache.has(root)) {
return configCache.get(root)!;
}
// config files to read from, in the order they are merged together
let config = (configCache[root] = {});
configFiles.forEach(function(configFile) {
let config: Config = {};
for (const name of configFileNames) {
try {
const content = JSON.parse(readFileSync(resolve(root, configFile)));
config = Object.assign(config, content);
config = JSON.parse(readFileSync(resolve(root, name), 'utf8'));
} catch (e) {
// rethrow error unless it's complaining about file not existing
if (e.code !== 'ENOENT') {
throw e;
}
}
});
}
const deprecationMsg =
'has been removed from `@kbn/plugin-helpers`. ' +
@ -59,8 +60,10 @@ module.exports = function(root) {
}
// use resolve to ensure correct resolution of paths
const { includePlugins } = config;
if (includePlugins) config.includePlugins = includePlugins.map(path => resolve(root, path));
if (Array.isArray(config.includePlugins)) {
config.includePlugins = config.includePlugins.map((path: string) => resolve(root, path));
}
configCache.set(root, config);
return config;
};
}

View file

@ -17,21 +17,19 @@
* under the License.
*/
const resolve = require('path').resolve;
const readFileSync = require('fs').readFileSync;
import { resolve } from 'path';
import { readFileSync } from 'fs';
function indent(txt, n) {
function indent(txt: string, n: number) {
const space = new Array(n + 1).join(' ');
return space + txt.split('\n').join('\n' + space);
}
module.exports = function docs(name) {
const md = readFileSync(resolve(__dirname, '../tasks', name, 'README.md'), 'utf8');
export function docs(name: string) {
const md = readFileSync(resolve(__dirname, '../../src/tasks', name, 'README.md'), 'utf8');
return function() {
console.log('\n Docs:');
console.log('');
console.log(indent(md, 4));
console.log('');
/* eslint-disable-next-line no-console */
console.log(`\n Docs:\n\n${indent(md, 4)}\n\n`);
};
};
}

View file

@ -17,12 +17,14 @@
* under the License.
*/
module.exports = function enableCollectingUnknownOptions(command) {
import { Command } from 'commander';
export function enableCollectingUnknownOptions(command: Command) {
const origParse = command.parseOptions;
command.allowUnknownOption();
command.parseOptions = function(argv) {
command.parseOptions = function(argv: string[]) {
const opts = origParse.call(this, argv);
this.unknownOptions = opts.unknown;
return opts;
};
};
}

View file

@ -0,0 +1,24 @@
/*
* 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 * from './run';
export * from './utils';
export * from './win_cmd';
export * from './plugin_config';
export * from './pipeline';

View file

@ -0,0 +1,23 @@
/*
* 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 Stream from 'stream';
import Util from 'util';
export const pipeline = Util.promisify(Stream.pipeline);

View file

@ -17,16 +17,26 @@
* under the License.
*/
const resolve = require('path').resolve;
const readFileSync = require('fs').readFileSync;
const configFile = require('./config_file');
import { resolve } from 'path';
import { readFileSync } from 'fs';
module.exports = function(root) {
if (!root) root = process.cwd();
import { configFile } from './config_file';
export interface PluginConfig {
root: string;
kibanaRoot: string;
serverTestPatterns: string[];
buildSourcePatterns: string[];
skipInstallDependencies: boolean;
id: string;
version: string;
pkg: any;
[k: string]: unknown;
}
export function pluginConfig(root: string = process.cwd()): PluginConfig {
const pluginPackageJsonPath = resolve(root, 'package.json');
const pkg = JSON.parse(readFileSync(pluginPackageJsonPath));
const config = configFile(root);
const pkg = JSON.parse(readFileSync(pluginPackageJsonPath, 'utf8'));
const buildSourcePatterns = [
'yarn.lock',
@ -42,6 +52,7 @@ module.exports = function(root) {
const isPluginXpack = pkg.name === 'x-pack';
if (isPluginOnKibanaExtra && !isPluginXpack) {
// eslint-disable-next-line no-console
console.warn(
`In the future we will disable ../kibana-extra/{pluginName}. You should move your plugin ${pkg.name} as soon as possible to ./plugins/{pluginName}`
);
@ -49,17 +60,15 @@ module.exports = function(root) {
const kibanaRootWhenNotXpackPlugin = isPluginOnKibanaExtra ? kibanaExtraDir : kibanaPluginsDir;
return Object.assign(
{
root: root,
kibanaRoot: isPluginXpack ? resolve(root, '..') : kibanaRootWhenNotXpackPlugin,
serverTestPatterns: ['server/**/__tests__/**/*.js'],
buildSourcePatterns: buildSourcePatterns,
skipInstallDependencies: false,
id: pkg.name,
pkg: pkg,
version: pkg.version,
},
config
);
};
return {
root,
kibanaRoot: isPluginXpack ? resolve(root, '..') : kibanaRootWhenNotXpackPlugin,
serverTestPatterns: ['server/**/__tests__/**/*.js'],
buildSourcePatterns,
skipInstallDependencies: false,
id: pkg.name as string,
version: pkg.version as string,
pkg,
...configFile(root),
};
}

View file

@ -17,15 +17,21 @@
* under the License.
*/
const pluginConfig = require('./plugin_config');
const tasks = require('./tasks');
import { pluginConfig, PluginConfig } from './plugin_config';
import { tasks, Tasks } from './tasks';
module.exports = function run(name, options) {
export interface TaskContext {
plugin: PluginConfig;
run: typeof run;
options?: any;
}
export function run(name: keyof Tasks, options?: any) {
const action = tasks[name];
if (!action) {
throw new Error('Invalid task: "' + name + '"');
}
const plugin = pluginConfig();
return action(plugin, run, options);
};
return action({ plugin, run, options });
}

View file

@ -17,13 +17,22 @@
* under the License.
*/
const buildTask = require('../tasks/build');
const startTask = require('../tasks/start');
const testAllTask = require('../tasks/test/all');
const testKarmaTask = require('../tasks/test/karma');
const testMochaTask = require('../tasks/test/mocha');
import { buildTask } from '../tasks/build';
import { startTask } from '../tasks/start';
import { testAllTask } from '../tasks/test/all';
import { testKarmaTask } from '../tasks/test/karma';
import { testMochaTask } from '../tasks/test/mocha';
module.exports = {
// define a tasks interface that we can extend in the tests
export interface Tasks {
build: typeof buildTask;
start: typeof startTask;
testAll: typeof testAllTask;
testKarma: typeof testKarmaTask;
testMocha: typeof testMochaTask;
}
export const tasks: Tasks = {
build: buildTask,
start: startTask,
testAll: testAllTask,

View file

@ -17,11 +17,11 @@
* under the License.
*/
const resolve = require('path').resolve;
import { resolve } from 'path';
const pluginConfig = require('./plugin_config');
import { pluginConfig } from './plugin_config';
function babelRegister() {
export function babelRegister() {
const plugin = pluginConfig();
try {
@ -36,18 +36,7 @@ function babelRegister() {
}
}
function resolveKibanaPath(path) {
export function resolveKibanaPath(path: string) {
const plugin = pluginConfig();
return resolve(plugin.kibanaRoot, path);
}
function readFtrConfigFile(log, path, settingOverrides) {
return require('@kbn/test') // eslint-disable-line import/no-dynamic-require
.readConfigFile(log, path, settingOverrides);
}
module.exports = {
babelRegister: babelRegister,
resolveKibanaPath: resolveKibanaPath,
readFtrConfigFile: readFtrConfigFile,
};

View file

@ -0,0 +1,24 @@
/*
* 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 Os from 'os';
export function winCmd(cmd: string) {
return /^win/.test(Os.platform()) ? cmd + '.cmd' : cmd;
}

View file

@ -17,15 +17,14 @@
* under the License.
*/
const join = require('path').join;
const resolve = require('path').resolve;
const inquirer = require('inquirer');
import { join, resolve } from 'path';
import inquirer from 'inquirer';
const createBuild = require('./create_build');
const createPackage = require('./create_package');
import { TaskContext } from '../../lib';
import { createBuild } from './create_build';
import { createPackage } from './create_package';
module.exports = function(plugin, run, options) {
options = options || {};
export async function buildTask({ plugin, options = {} }: TaskContext) {
let buildVersion = plugin.version;
let kibanaVersion = (plugin.pkg.kibana && plugin.pkg.kibana.version) || plugin.pkg.version;
let buildFiles = plugin.buildSourcePatterns;
@ -41,31 +40,24 @@ module.exports = function(plugin, run, options) {
if (options.buildVersion) buildVersion = options.buildVersion;
if (options.kibanaVersion) kibanaVersion = options.kibanaVersion;
let buildStep;
if (kibanaVersion === 'kibana') {
buildStep = askForKibanaVersion().then(function(customKibanaVersion) {
return createBuild(plugin, buildTarget, buildVersion, customKibanaVersion, buildFiles);
});
} else {
buildStep = createBuild(plugin, buildTarget, buildVersion, kibanaVersion, buildFiles);
const chosenKibanaVersion =
kibanaVersion === 'kibana' ? await askForKibanaVersion() : kibanaVersion;
await createBuild(plugin, buildTarget, buildVersion, chosenKibanaVersion, buildFiles);
if (!options.skipArchive) {
await createPackage(plugin, buildTarget, buildVersion);
}
return buildStep.then(function() {
if (options.skipArchive) return;
return createPackage(plugin, buildTarget, buildVersion);
});
};
function askForKibanaVersion() {
return inquirer
.prompt([
{
type: 'input',
name: 'kibanaVersion',
message: 'What version of Kibana are you building for?',
},
])
.then(function(answers) {
return answers.kibanaVersion;
});
}
async function askForKibanaVersion() {
const answers = await inquirer.prompt([
{
type: 'input',
name: 'kibanaVersion',
message: 'What version of Kibana are you building for?',
},
]);
return answers.kibanaVersion;
}

View file

@ -0,0 +1,196 @@
/*
* 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 { relative } from 'path';
import path from 'path';
import { readFileSync, writeFileSync, unlinkSync, existsSync } from 'fs';
import execa from 'execa';
import sass from 'node-sass';
import del from 'del';
import File from 'vinyl';
import vfs from 'vinyl-fs';
import rename from 'gulp-rename';
import through from 'through2';
import minimatch from 'minimatch';
// @ts-ignore
import gulpBabel from 'gulp-babel';
import { PluginConfig, winCmd, pipeline } from '../../lib';
import { rewritePackageJson } from './rewrite_package_json';
// `link:` dependencies create symlinks, but we don't want to include symlinks
// in the built zip file. Therefore we remove all symlinked dependencies, so we
// can re-create them when installing the plugin.
function removeSymlinkDependencies(root: string) {
const nodeModulesPattern = path.join(root, '**', 'node_modules', '**');
return through.obj((file: File, _, cb) => {
const isSymlink = file.symlink != null;
const isDependency = minimatch(file.path, nodeModulesPattern);
if (isSymlink && isDependency) {
unlinkSync(file.path);
}
cb();
});
}
// parse a ts config file
function parseTsconfig(pluginSourcePath: string, configPath: string) {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const ts = require(path.join(pluginSourcePath, 'node_modules', 'typescript'));
const { error, config } = ts.parseConfigFileTextToJson(
configPath,
readFileSync(configPath, 'utf8')
);
if (error) {
throw error;
}
return config;
}
// transpile with babel
async function transpileWithBabel(srcGlobs: string[], buildRoot: string, presets: string[]) {
await pipeline(
vfs.src(
srcGlobs.concat([
'!**/*.d.ts',
'!**/*.{test,test.mocks,mock,mocks}.{ts,tsx}',
'!**/node_modules/**',
'!**/bower_components/**',
'!**/__tests__/**',
]),
{
cwd: buildRoot,
}
),
gulpBabel({
babelrc: false,
presets,
}),
vfs.dest(buildRoot)
);
}
export async function createBuild(
plugin: PluginConfig,
buildTarget: string,
buildVersion: string,
kibanaVersion: string,
files: string[]
) {
const buildSource = plugin.root;
const buildRoot = path.join(buildTarget, 'kibana', plugin.id);
await del(buildTarget);
// copy source files and apply some transformations in the process
await pipeline(
vfs.src(files, {
cwd: buildSource,
base: buildSource,
allowEmpty: true,
}),
// modify the package.json file
rewritePackageJson(buildSource, buildVersion, kibanaVersion),
// put all files inside the correct directories
rename(function nestFileInDir(filePath) {
const nonRelativeDirname = filePath.dirname!.replace(/^(\.\.\/?)+/g, '');
filePath.dirname = path.join(relative(buildTarget, buildRoot), nonRelativeDirname);
}),
// write files back to disk
vfs.dest(buildTarget)
);
// install packages in build
if (!plugin.skipInstallDependencies) {
execa.sync(winCmd('yarn'), ['install', '--production', '--pure-lockfile'], {
cwd: buildRoot,
});
}
// compile stylesheet
if (typeof plugin.styleSheetToCompile === 'string') {
const file = path.resolve(plugin.root, plugin.styleSheetToCompile);
if (!existsSync(file)) {
throw new Error(`Path provided for styleSheetToCompile does not exist: ${file}`);
}
const outputFileName = path.basename(file, path.extname(file)) + '.css';
const output = path.join(buildRoot, path.dirname(plugin.styleSheetToCompile), outputFileName);
const rendered = sass.renderSync({ file, output });
writeFileSync(output, rendered.css);
del.sync([path.join(buildRoot, '**', '*.s{a,c}ss')]);
}
// transform typescript to js and clean out typescript
const tsConfigPath = path.join(buildRoot, 'tsconfig.json');
if (existsSync(tsConfigPath)) {
// attempt to patch the extends path in the tsconfig file
const buildConfig = parseTsconfig(buildSource, tsConfigPath);
if (buildConfig.extends) {
buildConfig.extends = path.join(relative(buildRoot, buildSource), buildConfig.extends);
writeFileSync(tsConfigPath, JSON.stringify(buildConfig));
}
// Transpile ts server code
//
// Include everything except content from public folders
await transpileWithBabel(['**/*.{ts,tsx}', '!**/public/**'], buildRoot, [
require.resolve('@kbn/babel-preset/node_preset'),
]);
// Transpile ts client code
//
// Include everything inside a public directory
await transpileWithBabel(['**/public/**/*.{ts,tsx}'], buildRoot, [
require.resolve('@kbn/babel-preset/webpack_preset'),
]);
del.sync([
path.join(buildRoot, '**', '*.{ts,tsx,d.ts}'),
path.join(buildRoot, 'tsconfig.json'),
]);
}
// remove symlinked dependencies
await pipeline(
vfs.src([relative(buildTarget, buildRoot) + '/**/*'], {
cwd: buildTarget,
base: buildTarget,
resolveSymlinks: false,
}),
removeSymlinkDependencies(buildRoot)
);
}

View file

@ -17,28 +17,30 @@
* under the License.
*/
const join = require('path').join;
const relative = require('path').relative;
const del = require('del');
const vfs = require('vinyl-fs');
const zip = require('gulp-zip');
import { relative, join } from 'path';
module.exports = function createPackage(plugin, buildTarget, buildVersion) {
import del from 'del';
import vfs from 'vinyl-fs';
import zip from 'gulp-zip';
import { pipeline, PluginConfig } from '../../lib';
export async function createPackage(
plugin: PluginConfig,
buildTarget: string,
buildVersion: string
) {
const buildId = `${plugin.id}-${buildVersion}`;
const buildRoot = join(buildTarget, 'kibana', plugin.id);
const buildFiles = [relative(buildTarget, buildRoot) + '/**/*'];
// zip up the package
return new Promise(function(resolve, reject) {
const buildFiles = [relative(buildTarget, buildRoot) + '/**/*'];
await pipeline(
vfs.src(buildFiles, { cwd: buildTarget, base: buildTarget }),
zip(`${buildId}.zip`),
vfs.dest(buildTarget)
);
vfs
.src(buildFiles, { cwd: buildTarget, base: buildTarget })
.pipe(zip(`${buildId}.zip`))
.pipe(vfs.dest(buildTarget))
.on('end', resolve)
.on('error', reject);
}).then(function() {
// clean up the build path
return del(join(buildTarget, 'kibana'));
});
};
// clean up the build path
await del(join(buildTarget, 'kibana'));
}

View file

@ -17,16 +17,18 @@
* under the License.
*/
const execFileSync = require('child_process').execFileSync;
import { execFileSync } from 'child_process';
module.exports = function gitInfo(rootPath) {
export function gitInfo(rootPath: string) {
try {
const LOG_SEPARATOR = '||';
const commitCount = execFileSync('git', ['rev-list', '--count', 'HEAD'], {
cwd: rootPath,
stdio: ['ignore', 'pipe', 'ignore'],
encoding: 'utf8',
});
const logLine = execFileSync('git', ['log', '--pretty=%h' + LOG_SEPARATOR + '%cD', '-n', '1'], {
cwd: rootPath,
stdio: ['ignore', 'pipe', 'ignore'],
@ -41,4 +43,4 @@ module.exports = function gitInfo(rootPath) {
} catch (e) {
return {};
}
};
}

View file

@ -17,4 +17,4 @@
* under the License.
*/
module.exports = require('./start_action');
export * from './build_task';

View file

@ -17,34 +17,34 @@
* under the License.
*/
const resolve = require('path').resolve;
const fs = require('fs');
const del = require('del');
import { resolve } from 'path';
import fs from 'fs';
import del from 'del';
import { pluginConfig } from '../../../lib';
const PLUGIN_FIXTURE = resolve(__dirname, '__fixtures__/build_action_test_plugin');
const PLUGIN_BUILD_DIR = resolve(PLUGIN_FIXTURE, 'build');
const PLUGIN = require('../../../lib/plugin_config')(PLUGIN_FIXTURE);
const noop = () => {};
const plugin = pluginConfig(PLUGIN_FIXTURE);
describe('creating build zip', () => {
const buildAction = require('../build_action');
const { buildTask } = require('../build_task');
beforeEach(() => del(PLUGIN_BUILD_DIR));
afterEach(() => del(PLUGIN_BUILD_DIR));
it('creates a zip in the build directory', async () => {
await buildAction(PLUGIN);
await buildTask({ plugin });
const buildFile = resolve(PLUGIN_BUILD_DIR, PLUGIN.id + '-' + PLUGIN.version + '.zip');
const buildFile = resolve(PLUGIN_BUILD_DIR, plugin.id + '-' + plugin.version + '.zip');
if (!fs.existsSync(buildFile)) {
throw new Error('Build file not found: ' + buildFile);
}
});
it('skips zip creation based on flag', async () => {
await buildAction(PLUGIN, noop, { skipArchive: true });
await buildTask({ plugin, options: { skipArchive: true } });
const buildFile = resolve(PLUGIN_BUILD_DIR, PLUGIN.id + '-' + PLUGIN.version + '.zip');
const buildFile = resolve(PLUGIN_BUILD_DIR, plugin.id + '-' + plugin.version + '.zip');
if (fs.existsSync(buildFile)) {
throw new Error('Build file not found: ' + buildFile);
}
@ -53,13 +53,13 @@ describe('creating build zip', () => {
describe('calling create_build', () => {
let mockBuild;
let buildAction;
let buildTask;
beforeEach(() => {
jest.resetModules();
mockBuild = jest.fn(() => Promise.resolve());
jest.mock('../create_build', () => mockBuild);
buildAction = require('../build_action');
jest.mock('../create_build');
({ createBuild: mockBuild } = require('../create_build'));
({ buildTask } = require('../build_task'));
});
const nameArgs = ([plugin, buildTarget, buildVersion, kibanaVersion, files]) => ({
@ -76,7 +76,7 @@ describe('calling create_build', () => {
kibanaVersion: '4.5.6',
};
await buildAction(PLUGIN, noop, options);
await buildTask({ plugin, options });
expect(mockBuild.mock.calls).toHaveLength(1);
@ -86,12 +86,12 @@ describe('calling create_build', () => {
});
it('uses default file list without files option', async () => {
await buildAction(PLUGIN);
await buildTask({ plugin });
expect(mockBuild.mock.calls).toHaveLength(1);
const { files } = nameArgs(mockBuild.mock.calls[0]);
PLUGIN.buildSourcePatterns.forEach(file => expect(files).toContain(file));
plugin.buildSourcePatterns.forEach(file => expect(files).toContain(file));
});
it('uses only files passed in', async () => {
@ -99,7 +99,7 @@ describe('calling create_build', () => {
files: ['index.js', 'LICENSE.txt', 'plugins/**/*', '{server,public}/**/*'],
};
await buildAction(PLUGIN, noop, options);
await buildTask({ plugin, options });
expect(mockBuild.mock.calls).toHaveLength(1);
@ -112,6 +112,6 @@ describe('calling create_build', () => {
throw new Error('foo bar');
});
await expect(buildAction(PLUGIN, noop)).rejects.toThrowErrorMatchingSnapshot();
await expect(buildTask({ plugin })).rejects.toThrowErrorMatchingSnapshot();
});
});

View file

@ -17,13 +17,14 @@
* under the License.
*/
const { resolve } = require('path');
const { readdirSync, existsSync, unlinkSync } = require('fs');
const del = require('del');
const createBuild = require('../create_build');
import { resolve } from 'path';
import { readdirSync, existsSync, unlinkSync } from 'fs';
import del from 'del';
import { createBuild } from '../create_build';
import { pluginConfig } from '../../../lib';
const PLUGIN_FIXTURE = resolve(__dirname, '__fixtures__/create_build_test_plugin');
const PLUGIN = require('../../../lib/plugin_config')(PLUGIN_FIXTURE);
const PLUGIN = pluginConfig(PLUGIN_FIXTURE);
const PLUGIN_BUILD_DIR = resolve(PLUGIN_FIXTURE, 'build');
const PLUGIN_BUILD_TARGET = resolve(PLUGIN_BUILD_DIR, 'kibana', PLUGIN.id);

View file

@ -17,14 +17,15 @@
* under the License.
*/
const { resolve } = require('path');
const { statSync } = require('fs');
const del = require('del');
const createBuild = require('../create_build');
const createPackage = require('../create_package');
import { resolve } from 'path';
import { statSync } from 'fs';
import del from 'del';
import { createBuild } from '../create_build';
import { createPackage } from '../create_package';
import { pluginConfig } from '../../../lib';
const PLUGIN_FIXTURE = resolve(__dirname, '__fixtures__/create_package_test_plugin');
const PLUGIN = require('../../../lib/plugin_config')(PLUGIN_FIXTURE);
const PLUGIN = pluginConfig(PLUGIN_FIXTURE);
const PLUGIN_BUILD_DIR = resolve(PLUGIN_FIXTURE, 'build-custom');
const buildVersion = PLUGIN.version;

View file

@ -17,13 +17,18 @@
* under the License.
*/
const map = require('through2-map').obj;
const gitInfo = require('./git_info');
import Through2Map from 'through2-map';
import File from 'vinyl';
import { gitInfo } from './git_info';
module.exports = function rewritePackage(buildSource, buildVersion, kibanaVersion) {
return map(function(file) {
export function rewritePackageJson(
buildSource: string,
buildVersion: string,
kibanaVersion: string
) {
return Through2Map.obj(function(file: File) {
if (file.basename === 'package.json' && file.dirname === buildSource) {
const pkg = JSON.parse(file.contents.toString('utf8'));
const pkg = JSON.parse(file.contents!.toString('utf8'));
// rewrite the target kibana version while the
// file is on it's way to the archive
@ -46,4 +51,4 @@ module.exports = function rewritePackage(buildSource, buildVersion, kibanaVersio
return file;
});
};
}

View file

@ -17,4 +17,4 @@
* under the License.
*/
module.exports = require('./build_action');
export * from './start_task';

View file

@ -17,11 +17,15 @@
* under the License.
*/
const execFileSync = require('child_process').execFileSync;
const { join } = require('path');
const split = require('argv-split');
import { execFileSync } from 'child_process';
import { join } from 'path';
module.exports = function(plugin, run, options) {
// @ts-ignore
import split from 'argv-split';
import { TaskContext } from '../../lib';
export function startTask({ plugin, options }: TaskContext) {
options = options || {};
const cmd = 'node';
@ -44,4 +48,4 @@ module.exports = function(plugin, run, options) {
cwd: plugin.kibanaRoot,
stdio: ['ignore', 1, 2],
});
};
}

View file

@ -17,4 +17,4 @@
* under the License.
*/
module.exports = require('./test_all_action');
export * from './test_all_task';

View file

@ -17,7 +17,9 @@
* under the License.
*/
module.exports = function testAllAction(plugin, run) {
import { TaskContext } from '../../../lib';
export function testAllTask({ run }: TaskContext) {
run('testMocha');
run('testKarma');
};
}

View file

@ -17,4 +17,4 @@
* under the License.
*/
module.exports = require('./test_karma_action');
export * from './test_karma_task';

View file

@ -17,10 +17,12 @@
* under the License.
*/
const execFileSync = require('child_process').execFileSync;
const winCmd = require('../../../lib/win_cmd');
import { execFileSync } from 'child_process';
module.exports = function testKarmaAction(plugin, run, options) {
import { TaskContext } from '../../../lib';
import { winCmd } from '../../../lib/win_cmd';
export function testKarmaTask({ plugin, options }: TaskContext) {
options = options || {};
const kbnServerArgs = ['--kbnServer.plugin-path=' + plugin.root];
@ -37,4 +39,4 @@ module.exports = function testKarmaAction(plugin, run, options) {
cwd: plugin.kibanaRoot,
stdio: ['ignore', 1, 2],
});
};
}

View file

@ -0,0 +1,20 @@
/*
* 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 * from './test_mocha_task';

View file

@ -17,10 +17,12 @@
* under the License.
*/
const execFileSync = require('child_process').execFileSync;
const globby = require('globby');
import { execFileSync } from 'child_process';
import globby from 'globby';
module.exports = function(plugin, run, options) {
import { TaskContext } from '../../../lib';
export function testMochaTask({ plugin, options }: TaskContext) {
options = options || {};
let testPatterns = plugin.serverTestPatterns;
@ -43,4 +45,4 @@ module.exports = function(plugin, run, options) {
stdio: ['ignore', 1, 2],
}
);
};
}

View file

@ -1,205 +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 path = require('path');
const relative = require('path').relative;
const { readFileSync, writeFileSync, unlinkSync, existsSync } = require('fs');
const execa = require('execa');
const sass = require('node-sass');
const del = require('del');
const vfs = require('vinyl-fs');
const rename = require('gulp-rename');
const through = require('through2');
const minimatch = require('minimatch');
const gulpBabel = require('gulp-babel');
const { promisify } = require('util');
const { pipeline } = require('stream');
const rewritePackageJson = require('./rewrite_package_json');
const winCmd = require('../../lib/win_cmd');
const asyncPipeline = promisify(pipeline);
// `link:` dependencies create symlinks, but we don't want to include symlinks
// in the built zip file. Therefore we remove all symlinked dependencies, so we
// can re-create them when installing the plugin.
function removeSymlinkDependencies(root) {
const nodeModulesPattern = path.join(root, '**', 'node_modules', '**');
return through.obj((file, enc, cb) => {
const isSymlink = file.symlink != null;
const isDependency = minimatch(file.path, nodeModulesPattern);
if (isSymlink && isDependency) {
unlinkSync(file.path);
}
cb();
});
}
// parse a ts config file
function parseTsconfig(pluginSourcePath, configPath) {
const ts = require(path.join(pluginSourcePath, 'node_modules', 'typescript')); // eslint-disable-line import/no-dynamic-require
const { error, config } = ts.parseConfigFileTextToJson(
configPath,
readFileSync(configPath, 'utf8')
);
if (error) {
throw error;
}
return config;
}
// transpile with babel
async function transpileWithBabel(srcGlobs, buildRoot, presets) {
await asyncPipeline(
vfs.src(
srcGlobs.concat([
'!**/*.d.ts',
'!**/*.{test,test.mocks,mock,mocks}.{ts,tsx}',
'!**/node_modules/**',
'!**/bower_components/**',
'!**/__tests__/**',
]),
{
cwd: buildRoot,
}
),
gulpBabel({
babelrc: false,
presets,
}),
vfs.dest(buildRoot)
);
}
module.exports = function createBuild(plugin, buildTarget, buildVersion, kibanaVersion, files) {
const buildSource = plugin.root;
const buildRoot = path.join(buildTarget, 'kibana', plugin.id);
return del(buildTarget)
.then(function() {
return new Promise(function(resolve, reject) {
vfs
.src(files, {
cwd: buildSource,
base: buildSource,
allowEmpty: true,
})
// modify the package.json file
.pipe(rewritePackageJson(buildSource, buildVersion, kibanaVersion))
// put all files inside the correct directories
.pipe(
rename(function nestFileInDir(filePath) {
const nonRelativeDirname = filePath.dirname.replace(/^(\.\.\/?)+/g, '');
filePath.dirname = path.join(relative(buildTarget, buildRoot), nonRelativeDirname);
})
)
.pipe(vfs.dest(buildTarget))
.on('end', resolve)
.on('error', reject);
});
})
.then(function() {
if (plugin.skipInstallDependencies) {
return;
}
// install packages in build
execa.sync(winCmd('yarn'), ['install', '--production', '--pure-lockfile'], {
cwd: buildRoot,
});
})
.then(function() {
if (!plugin.styleSheetToCompile) {
return;
}
const file = path.resolve(plugin.root, plugin.styleSheetToCompile);
if (!existsSync(file)) {
throw new Error(`Path provided for styleSheetToCompile does not exist: ${file}`);
}
const outputFileName = path.basename(file, path.extname(file)) + '.css';
const output = path.join(buildRoot, path.dirname(plugin.styleSheetToCompile), outputFileName);
const rendered = sass.renderSync({ file, output });
writeFileSync(output, rendered.css);
del.sync([path.join(buildRoot, '**', '*.s{a,c}ss')]);
})
.then(async function() {
const buildConfigPath = path.join(buildRoot, 'tsconfig.json');
if (!existsSync(buildConfigPath)) {
return;
}
// attempt to patch the extends path in the tsconfig file
const buildConfig = parseTsconfig(buildSource, buildConfigPath);
if (buildConfig.extends) {
buildConfig.extends = path.join(relative(buildRoot, buildSource), buildConfig.extends);
writeFileSync(buildConfigPath, JSON.stringify(buildConfig));
}
// Transpile ts server code
//
// Include everything except content from public folders
await transpileWithBabel(['**/*.{ts,tsx}', '!**/public/**'], buildRoot, [
require.resolve('@kbn/babel-preset/node_preset'),
]);
// Transpile ts client code
//
// Include everything inside a public directory
await transpileWithBabel(['**/public/**/*.{ts,tsx}'], buildRoot, [
require.resolve('@kbn/babel-preset/webpack_preset'),
]);
del.sync([
path.join(buildRoot, '**', '*.{ts,tsx,d.ts}'),
path.join(buildRoot, 'tsconfig.json'),
]);
})
.then(function() {
const buildFiles = [relative(buildTarget, buildRoot) + '/**/*'];
return new Promise((resolve, reject) => {
vfs
.src(buildFiles, {
cwd: buildTarget,
base: buildTarget,
resolveSymlinks: false,
})
.pipe(removeSymlinkDependencies(buildRoot))
.on('finish', resolve)
.on('error', reject);
});
});
};

View file

@ -1,20 +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.
*/
module.exports = require('./test_mocha_action');

View file

@ -1,4 +1,11 @@
{
"extends": "../../tsconfig.json",
"include": ["lib/index.d.ts"]
"compilerOptions": {
"outDir": "target",
"declaration": true,
"sourceMap": true
},
"include": [
"src/**/*.ts"
]
}

View file

@ -42,10 +42,8 @@ export { kbnTestConfig, kibanaServerTestUser, kibanaTestUser, adminTestUser } fr
// @ts-ignore not typed yet
export { setupUsers, DEFAULT_SUPERUSER_PASS } from './functional_tests/lib/auth';
// @ts-ignore not typed yet
export { readConfigFile } from './functional_test_runner/lib/config/read_config_file';
// @ts-ignore not typed yet
export { runFtrCli } from './functional_test_runner/cli';
export {

View file

@ -426,6 +426,14 @@
'@types/indent-string',
],
},
{
groupSlug: 'inquirer',
groupName: 'inquirer related packages',
packageNames: [
'inquirer',
'@types/inquirer',
],
},
{
groupSlug: 'intl-relativeformat',
groupName: 'intl-relativeformat related packages',
@ -683,6 +691,14 @@
'@types/node-forge',
],
},
{
groupSlug: 'node-sass',
groupName: 'node-sass related packages',
packageNames: [
'node-sass',
'@types/node-sass',
],
},
{
groupSlug: 'nodemailer',
groupName: 'nodemailer related packages',
@ -951,6 +967,22 @@
'@types/tempy',
],
},
{
groupSlug: 'through2',
groupName: 'through2 related packages',
packageNames: [
'through2',
'@types/through2',
],
},
{
groupSlug: 'through2-map',
groupName: 'through2-map related packages',
packageNames: [
'through2-map',
'@types/through2-map',
],
},
{
groupSlug: 'tinycolor2',
groupName: 'tinycolor2 related packages',
@ -1003,6 +1035,14 @@
],
enabled: false,
},
{
groupSlug: 'vinyl',
groupName: 'vinyl related packages',
packageNames: [
'vinyl',
'@types/vinyl',
],
},
{
groupSlug: 'vinyl-fs',
groupName: 'vinyl-fs related packages',

View file

@ -8,7 +8,7 @@ import execa from 'execa';
import { resolve } from 'path';
import { writeFileSync } from 'fs';
import pluginHelpers from '@kbn/plugin-helpers';
import * as pluginHelpers from '@kbn/plugin-helpers';
import { ToolingLog, REPO_ROOT } from '@kbn/dev-utils';
import gulp from 'gulp';
import del from 'del';

View file

@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import pluginHelpers from '@kbn/plugin-helpers';
import * as pluginHelpers from '@kbn/plugin-helpers';
import gulp from 'gulp';
import { prepareTask } from './prepare';

View file

@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import pluginHelpers from '@kbn/plugin-helpers';
import * as pluginHelpers from '@kbn/plugin-helpers';
import gulp from 'gulp';
import { getEnabledPlugins } from './helpers/flags';

View file

@ -4,7 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/
// @ts-ignore
import { resolveKibanaPath } from '@kbn/plugin-helpers';
import { FtrConfigProviderContext } from '@kbn/test/types/ftr';
import path from 'path';

View file

@ -4,7 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/
// @ts-ignore
import { resolveKibanaPath } from '@kbn/plugin-helpers';
import path from 'path';
import { TestInvoker } from './lib/types';

View file

@ -3980,6 +3980,11 @@
resolved "https://registry.yarnpkg.com/@types/events/-/events-1.2.0.tgz#81a6731ce4df43619e5c8c945383b3e62a89ea86"
integrity sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA==
"@types/expect@^1.20.4":
version "1.20.4"
resolved "https://registry.yarnpkg.com/@types/expect/-/expect-1.20.4.tgz#8288e51737bf7e3ab5d7c77bfa695883745264e5"
integrity sha512-Q5Vn3yjTDyCMV50TB6VRIbQNxSE4OmZR86VSbGaNpfUolm0iePBB4KdEEHmxoY5sT2+2DIvXW0rvMDP2nHZ4Mg==
"@types/fancy-log@^1.3.1":
version "1.3.1"
resolved "https://registry.yarnpkg.com/@types/fancy-log/-/fancy-log-1.3.1.tgz#dd94fbc8c2e2ab8ab402ca8d04bb8c34965f0696"
@ -4075,6 +4080,20 @@
resolved "https://registry.yarnpkg.com/@types/graphql/-/graphql-0.13.4.tgz#55ae9c29f0fd6b85ee536f5c72b4769d5c5e06b1"
integrity sha512-B4yel4ro2nTb3v0pYO8vO6SjgvFJSrwUY+IO6TUSLdOSB+gQFslylrhRCHxvXMIhxB71mv5PEE9dAX+24S8sew==
"@types/gulp-rename@^0.0.33":
version "0.0.33"
resolved "https://registry.yarnpkg.com/@types/gulp-rename/-/gulp-rename-0.0.33.tgz#38d146e97786569f74f5391a1b1f9b5198674b6c"
integrity sha512-FIZQvbZJj6V1gHPTzO+g/BCWpDur7fJrroae4gwV3LaoHBQ+MrR9sB+2HssK8fHv4WdY6hVNxkcft9bYatuPIA==
dependencies:
"@types/node" "*"
"@types/gulp-zip@^4.0.1":
version "4.0.1"
resolved "https://registry.yarnpkg.com/@types/gulp-zip/-/gulp-zip-4.0.1.tgz#96cd0b994219f9ae3bbbec7ec3baa043fba9d9ef"
integrity sha512-dYwGsHmwv4pnMD+jtyuIdZchJ0CIivnl8PIApHC+rYN7FMj01tJSAiQb+YN4T/pOn10pmmucBLEB9wXEhQX2Ug==
dependencies:
"@types/node" "*"
"@types/gulp@^4.0.6":
version "4.0.6"
resolved "https://registry.yarnpkg.com/@types/gulp/-/gulp-4.0.6.tgz#68fe0e1f0ff3657cfca46fb564806b744a1bf899"
@ -4172,6 +4191,14 @@
dependencies:
"@types/hapi" "*"
"@types/inquirer@^6.5.0":
version "6.5.0"
resolved "https://registry.yarnpkg.com/@types/inquirer/-/inquirer-6.5.0.tgz#b83b0bf30b88b8be7246d40e51d32fe9d10e09be"
integrity sha512-rjaYQ9b9y/VFGOpqBEXRavc3jh0a+e6evAbI31tMda8VlPaSy0AZJfXsvmIe3wklc7W6C3zCSfleuMXR7NOyXw==
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"
@ -4478,6 +4505,13 @@
dependencies:
"@types/node" "*"
"@types/node-sass@^4.11.0":
version "4.11.0"
resolved "https://registry.yarnpkg.com/@types/node-sass/-/node-sass-4.11.0.tgz#b0372075546e83f39df52bd37359eab00165a04d"
integrity sha512-uNpVWhwVmbB5luE7b8vxcJwu5np75YkVTBJS0O3ar+hrxqLfyhOKXg9NYBwJ6mMQX/V6/8d6mMZTB7x2r5x9Bw==
dependencies:
"@types/node" "*"
"@types/node@*", "@types/node@8.10.54", "@types/node@>=10.17.17 <10.20.0", "@types/node@>=8.9.0", "@types/node@^12.0.2":
version "10.17.17"
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.17.tgz#7a183163a9e6ff720d86502db23ba4aade5999b8"
@ -4983,6 +5017,28 @@
"@types/react-dom" "*"
"@types/testing-library__dom" "*"
"@types/through2-map@^3.0.0":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@types/through2-map/-/through2-map-3.0.0.tgz#2fda6049bf0ec16fd75394fc64536d73024d3189"
integrity sha512-r2m4v3Lggg30dCt7nG9uDl93LhImYRsAutECYNU7JenHTM3MdwMHudcC3sOqk/rEUEpN9CDNOIuOxRGzJUP1pg==
dependencies:
"@types/node" "*"
"@types/through2" "*"
"@types/through2@*", "@types/through2@^2.0.35":
version "2.0.35"
resolved "https://registry.yarnpkg.com/@types/through2/-/through2-2.0.35.tgz#9add1643da9f936ecf0622311759b33e881047e8"
integrity sha512-5puhsegK8DdiZkVL71+iL67KxKd92l7kzzzeclc+idlp5L6PbjxDDQX9JCIA6jOUS9aNHgcmONyW5CRtZUvKFw==
dependencies:
"@types/node" "*"
"@types/through@*":
version "0.0.30"
resolved "https://registry.yarnpkg.com/@types/through/-/through-0.0.30.tgz#e0e42ce77e897bd6aead6f6ea62aeb135b8a3895"
integrity sha512-FvnCJljyxhPM3gkRgWmxmDZyAQSiBQQWLI0A0VFL0K7W1oRUrPJSqNO0NvTnLkBcotdlp3lKvaT0JrnyRDkzOg==
dependencies:
"@types/node" "*"
"@types/tinycolor2@^1.4.0":
version "1.4.2"
resolved "https://registry.yarnpkg.com/@types/tinycolor2/-/tinycolor2-1.4.2.tgz#721ca5c5d1a2988b4a886e35c2ffc5735b6afbdf"
@ -5079,6 +5135,14 @@
dependencies:
"@types/node" "*"
"@types/vinyl@^2.0.4":
version "2.0.4"
resolved "https://registry.yarnpkg.com/@types/vinyl/-/vinyl-2.0.4.tgz#9a7a8071c8d14d3a95d41ebe7135babe4ad5995a"
integrity sha512-2o6a2ixaVI2EbwBPg1QYLGQoHK56p/8X/sGfKbFC8N6sY9lfjsMf/GprtkQkSya0D4uRiutRZ2BWj7k3JvLsAQ==
dependencies:
"@types/expect" "^1.20.4"
"@types/node" "*"
"@types/watchpack@^1.1.5":
version "1.1.5"
resolved "https://registry.yarnpkg.com/@types/watchpack/-/watchpack-1.1.5.tgz#e5622eb2a49e2239d94d8882275fbc7893147e97"
@ -31231,7 +31295,7 @@ vinyl@^1.1.0:
clone-stats "^0.0.1"
replace-ext "0.0.1"
vinyl@^2.0.0, vinyl@^2.0.1, vinyl@^2.1.0:
vinyl@^2.0.0, vinyl@^2.0.1, vinyl@^2.1.0, vinyl@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.2.0.tgz#d85b07da96e458d25b2ffe19fece9f2caa13ed86"
integrity sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==