[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', '.eslintrc.js',
'**/webpackShims/**/*.js', '**/webpackShims/**/*.js',
'packages/kbn-plugin-generator/**/*.js', 'packages/kbn-plugin-generator/**/*.js',
'packages/kbn-plugin-helpers/**/*.js',
'packages/kbn-eslint-import-resolver-kibana/**/*.js', 'packages/kbn-eslint-import-resolver-kibana/**/*.js',
'packages/kbn-eslint-plugin-eslint/**/*', 'packages/kbn-eslint-plugin-eslint/**/*',
'x-pack/gulpfile.js', 'x-pack/gulpfile.js',

View file

@ -25,4 +25,4 @@ if (nodeMajorVersion < 6) {
process.exit(1); 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", "name": "@kbn/plugin-helpers",
"private": true,
"version": "9.0.2", "version": "9.0.2",
"private": true,
"description": "Just some helpers for kibana plugin devs.", "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": { "bin": {
"plugin-helpers": "bin/plugin-helpers.js" "plugin-helpers": "bin/plugin-helpers.js"
}, },
"author": "Spencer Alger <email@spalger.com>",
"license": "Apache-2.0",
"peerDependencies": {
"@kbn/babel-preset": "1.0.0"
},
"dependencies": { "dependencies": {
"@babel/core": "^7.9.0", "@babel/core": "^7.9.0",
"argv-split": "^2.0.1", "argv-split": "^2.0.1",
@ -27,6 +26,20 @@
"node-sass": "^4.13.1", "node-sass": "^4.13.1",
"through2": "^2.0.3", "through2": "^2.0.3",
"through2-map": "^3.0.0", "through2-map": "^3.0.0",
"vinyl": "^2.2.0",
"vinyl-fs": "^3.0.3" "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. * under the License.
*/ */
const program = require('commander'); import Fs from 'fs';
import Path from 'path';
const pkg = require('./package.json'); import program from 'commander';
const createCommanderAction = require('./lib/commander_action');
const docs = require('./lib/docs');
const enableCollectingUnknownOptions = require('./lib/enable_collecting_unknown_options');
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); program.version(pkg.version);
enableCollectingUnknownOptions( enableCollectingUnknownOptions(
@ -55,7 +58,7 @@ program
buildVersion: command.buildVersion, buildVersion: command.buildVersion,
kibanaVersion: command.kibanaVersion, kibanaVersion: command.kibanaVersion,
skipArchive: Boolean(command.skipArchive), skipArchive: Boolean(command.skipArchive),
files: files, files,
})) }))
); );
@ -84,7 +87,7 @@ program
.on('--help', docs('test/mocha')) .on('--help', docs('test/mocha'))
.action( .action(
createCommanderAction('testMocha', (command, files) => ({ createCommanderAction('testMocha', (command, files) => ({
files: files, files,
})) }))
); );

View file

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

View file

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

View file

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

View file

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

View file

@ -17,12 +17,14 @@
* under the License. * under the License.
*/ */
module.exports = function enableCollectingUnknownOptions(command) { import { Command } from 'commander';
export function enableCollectingUnknownOptions(command: Command) {
const origParse = command.parseOptions; const origParse = command.parseOptions;
command.allowUnknownOption(); command.allowUnknownOption();
command.parseOptions = function(argv) { command.parseOptions = function(argv: string[]) {
const opts = origParse.call(this, argv); const opts = origParse.call(this, argv);
this.unknownOptions = opts.unknown; this.unknownOptions = opts.unknown;
return opts; 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. * under the License.
*/ */
const resolve = require('path').resolve; import { resolve } from 'path';
const readFileSync = require('fs').readFileSync; import { readFileSync } from 'fs';
const configFile = require('./config_file');
module.exports = function(root) { import { configFile } from './config_file';
if (!root) root = process.cwd();
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 pluginPackageJsonPath = resolve(root, 'package.json');
const pkg = JSON.parse(readFileSync(pluginPackageJsonPath)); const pkg = JSON.parse(readFileSync(pluginPackageJsonPath, 'utf8'));
const config = configFile(root);
const buildSourcePatterns = [ const buildSourcePatterns = [
'yarn.lock', 'yarn.lock',
@ -42,6 +52,7 @@ module.exports = function(root) {
const isPluginXpack = pkg.name === 'x-pack'; const isPluginXpack = pkg.name === 'x-pack';
if (isPluginOnKibanaExtra && !isPluginXpack) { if (isPluginOnKibanaExtra && !isPluginXpack) {
// eslint-disable-next-line no-console
console.warn( 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}` `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; const kibanaRootWhenNotXpackPlugin = isPluginOnKibanaExtra ? kibanaExtraDir : kibanaPluginsDir;
return Object.assign( return {
{ root,
root: root, kibanaRoot: isPluginXpack ? resolve(root, '..') : kibanaRootWhenNotXpackPlugin,
kibanaRoot: isPluginXpack ? resolve(root, '..') : kibanaRootWhenNotXpackPlugin, serverTestPatterns: ['server/**/__tests__/**/*.js'],
serverTestPatterns: ['server/**/__tests__/**/*.js'], buildSourcePatterns,
buildSourcePatterns: buildSourcePatterns, skipInstallDependencies: false,
skipInstallDependencies: false, id: pkg.name as string,
id: pkg.name, version: pkg.version as string,
pkg: pkg, pkg,
version: pkg.version, ...configFile(root),
}, };
config }
);
};

View file

@ -17,15 +17,21 @@
* under the License. * under the License.
*/ */
const pluginConfig = require('./plugin_config'); import { pluginConfig, PluginConfig } from './plugin_config';
const tasks = require('./tasks'); 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]; const action = tasks[name];
if (!action) { if (!action) {
throw new Error('Invalid task: "' + name + '"'); throw new Error('Invalid task: "' + name + '"');
} }
const plugin = pluginConfig(); const plugin = pluginConfig();
return action(plugin, run, options); return action({ plugin, run, options });
}; }

View file

@ -17,13 +17,22 @@
* under the License. * under the License.
*/ */
const buildTask = require('../tasks/build'); import { buildTask } from '../tasks/build';
const startTask = require('../tasks/start'); import { startTask } from '../tasks/start';
const testAllTask = require('../tasks/test/all'); import { testAllTask } from '../tasks/test/all';
const testKarmaTask = require('../tasks/test/karma'); import { testKarmaTask } from '../tasks/test/karma';
const testMochaTask = require('../tasks/test/mocha'); 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, build: buildTask,
start: startTask, start: startTask,
testAll: testAllTask, testAll: testAllTask,

View file

@ -17,11 +17,11 @@
* under the License. * 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(); const plugin = pluginConfig();
try { try {
@ -36,18 +36,7 @@ function babelRegister() {
} }
} }
function resolveKibanaPath(path) { export function resolveKibanaPath(path: string) {
const plugin = pluginConfig(); const plugin = pluginConfig();
return resolve(plugin.kibanaRoot, path); 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. * under the License.
*/ */
const join = require('path').join; import { join, resolve } from 'path';
const resolve = require('path').resolve; import inquirer from 'inquirer';
const inquirer = require('inquirer');
const createBuild = require('./create_build'); import { TaskContext } from '../../lib';
const createPackage = require('./create_package'); import { createBuild } from './create_build';
import { createPackage } from './create_package';
module.exports = function(plugin, run, options) { export async function buildTask({ plugin, options = {} }: TaskContext) {
options = options || {};
let buildVersion = plugin.version; let buildVersion = plugin.version;
let kibanaVersion = (plugin.pkg.kibana && plugin.pkg.kibana.version) || plugin.pkg.version; let kibanaVersion = (plugin.pkg.kibana && plugin.pkg.kibana.version) || plugin.pkg.version;
let buildFiles = plugin.buildSourcePatterns; let buildFiles = plugin.buildSourcePatterns;
@ -41,31 +40,24 @@ module.exports = function(plugin, run, options) {
if (options.buildVersion) buildVersion = options.buildVersion; if (options.buildVersion) buildVersion = options.buildVersion;
if (options.kibanaVersion) kibanaVersion = options.kibanaVersion; if (options.kibanaVersion) kibanaVersion = options.kibanaVersion;
let buildStep; const chosenKibanaVersion =
if (kibanaVersion === 'kibana') { kibanaVersion === 'kibana' ? await askForKibanaVersion() : kibanaVersion;
buildStep = askForKibanaVersion().then(function(customKibanaVersion) {
return createBuild(plugin, buildTarget, buildVersion, customKibanaVersion, buildFiles); await createBuild(plugin, buildTarget, buildVersion, chosenKibanaVersion, buildFiles);
});
} else { if (!options.skipArchive) {
buildStep = createBuild(plugin, buildTarget, buildVersion, kibanaVersion, buildFiles); await createPackage(plugin, buildTarget, buildVersion);
} }
}
return buildStep.then(function() {
if (options.skipArchive) return; async function askForKibanaVersion() {
return createPackage(plugin, buildTarget, buildVersion); const answers = await inquirer.prompt([
}); {
}; type: 'input',
name: 'kibanaVersion',
function askForKibanaVersion() { message: 'What version of Kibana are you building for?',
return inquirer },
.prompt([ ]);
{
type: 'input', return answers.kibanaVersion;
name: 'kibanaVersion',
message: 'What version of Kibana are you building for?',
},
])
.then(function(answers) {
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. * under the License.
*/ */
const join = require('path').join; import { relative, join } from 'path';
const relative = require('path').relative;
const del = require('del');
const vfs = require('vinyl-fs');
const zip = require('gulp-zip');
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 buildId = `${plugin.id}-${buildVersion}`;
const buildRoot = join(buildTarget, 'kibana', plugin.id); const buildRoot = join(buildTarget, 'kibana', plugin.id);
const buildFiles = [relative(buildTarget, buildRoot) + '/**/*'];
// zip up the package // zip up the package
return new Promise(function(resolve, reject) { await pipeline(
const buildFiles = [relative(buildTarget, buildRoot) + '/**/*']; vfs.src(buildFiles, { cwd: buildTarget, base: buildTarget }),
zip(`${buildId}.zip`),
vfs.dest(buildTarget)
);
vfs // clean up the build path
.src(buildFiles, { cwd: buildTarget, base: buildTarget }) await del(join(buildTarget, 'kibana'));
.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'));
});
};

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -17,10 +17,12 @@
* under the License. * under the License.
*/ */
const execFileSync = require('child_process').execFileSync; import { execFileSync } from 'child_process';
const winCmd = require('../../../lib/win_cmd');
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 || {}; options = options || {};
const kbnServerArgs = ['--kbnServer.plugin-path=' + plugin.root]; const kbnServerArgs = ['--kbnServer.plugin-path=' + plugin.root];
@ -37,4 +39,4 @@ module.exports = function testKarmaAction(plugin, run, options) {
cwd: plugin.kibanaRoot, cwd: plugin.kibanaRoot,
stdio: ['ignore', 1, 2], 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. * under the License.
*/ */
const execFileSync = require('child_process').execFileSync; import { execFileSync } from 'child_process';
const globby = require('globby'); import globby from 'globby';
module.exports = function(plugin, run, options) { import { TaskContext } from '../../../lib';
export function testMochaTask({ plugin, options }: TaskContext) {
options = options || {}; options = options || {};
let testPatterns = plugin.serverTestPatterns; let testPatterns = plugin.serverTestPatterns;
@ -43,4 +45,4 @@ module.exports = function(plugin, run, options) {
stdio: ['ignore', 1, 2], 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", "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 // @ts-ignore not typed yet
export { setupUsers, DEFAULT_SUPERUSER_PASS } from './functional_tests/lib/auth'; 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'; export { readConfigFile } from './functional_test_runner/lib/config/read_config_file';
// @ts-ignore not typed yet
export { runFtrCli } from './functional_test_runner/cli'; export { runFtrCli } from './functional_test_runner/cli';
export { export {

View file

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

View file

@ -8,7 +8,7 @@ import execa from 'execa';
import { resolve } from 'path'; import { resolve } from 'path';
import { writeFileSync } from 'fs'; 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 { ToolingLog, REPO_ROOT } from '@kbn/dev-utils';
import gulp from 'gulp'; import gulp from 'gulp';
import del from 'del'; import del from 'del';

View file

@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License. * 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 gulp from 'gulp';
import { prepareTask } from './prepare'; import { prepareTask } from './prepare';

View file

@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License. * 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 gulp from 'gulp';
import { getEnabledPlugins } from './helpers/flags'; import { getEnabledPlugins } from './helpers/flags';

View file

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

View file

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

View file

@ -3980,6 +3980,11 @@
resolved "https://registry.yarnpkg.com/@types/events/-/events-1.2.0.tgz#81a6731ce4df43619e5c8c945383b3e62a89ea86" resolved "https://registry.yarnpkg.com/@types/events/-/events-1.2.0.tgz#81a6731ce4df43619e5c8c945383b3e62a89ea86"
integrity sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA== 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": "@types/fancy-log@^1.3.1":
version "1.3.1" version "1.3.1"
resolved "https://registry.yarnpkg.com/@types/fancy-log/-/fancy-log-1.3.1.tgz#dd94fbc8c2e2ab8ab402ca8d04bb8c34965f0696" 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" resolved "https://registry.yarnpkg.com/@types/graphql/-/graphql-0.13.4.tgz#55ae9c29f0fd6b85ee536f5c72b4769d5c5e06b1"
integrity sha512-B4yel4ro2nTb3v0pYO8vO6SjgvFJSrwUY+IO6TUSLdOSB+gQFslylrhRCHxvXMIhxB71mv5PEE9dAX+24S8sew== 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": "@types/gulp@^4.0.6":
version "4.0.6" version "4.0.6"
resolved "https://registry.yarnpkg.com/@types/gulp/-/gulp-4.0.6.tgz#68fe0e1f0ff3657cfca46fb564806b744a1bf899" resolved "https://registry.yarnpkg.com/@types/gulp/-/gulp-4.0.6.tgz#68fe0e1f0ff3657cfca46fb564806b744a1bf899"
@ -4172,6 +4191,14 @@
dependencies: dependencies:
"@types/hapi" "*" "@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": "@types/intl-relativeformat@^2.1.0":
version "2.1.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/@types/intl-relativeformat/-/intl-relativeformat-2.1.0.tgz#3a2b0043380388f39c666665ec517e11412f1358" resolved "https://registry.yarnpkg.com/@types/intl-relativeformat/-/intl-relativeformat-2.1.0.tgz#3a2b0043380388f39c666665ec517e11412f1358"
@ -4478,6 +4505,13 @@
dependencies: dependencies:
"@types/node" "*" "@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": "@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" version "10.17.17"
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.17.tgz#7a183163a9e6ff720d86502db23ba4aade5999b8" resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.17.tgz#7a183163a9e6ff720d86502db23ba4aade5999b8"
@ -4983,6 +5017,28 @@
"@types/react-dom" "*" "@types/react-dom" "*"
"@types/testing-library__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": "@types/tinycolor2@^1.4.0":
version "1.4.2" version "1.4.2"
resolved "https://registry.yarnpkg.com/@types/tinycolor2/-/tinycolor2-1.4.2.tgz#721ca5c5d1a2988b4a886e35c2ffc5735b6afbdf" resolved "https://registry.yarnpkg.com/@types/tinycolor2/-/tinycolor2-1.4.2.tgz#721ca5c5d1a2988b4a886e35c2ffc5735b6afbdf"
@ -5079,6 +5135,14 @@
dependencies: dependencies:
"@types/node" "*" "@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": "@types/watchpack@^1.1.5":
version "1.1.5" version "1.1.5"
resolved "https://registry.yarnpkg.com/@types/watchpack/-/watchpack-1.1.5.tgz#e5622eb2a49e2239d94d8882275fbc7893147e97" 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" clone-stats "^0.0.1"
replace-ext "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" version "2.2.0"
resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.2.0.tgz#d85b07da96e458d25b2ffe19fece9f2caa13ed86" resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.2.0.tgz#d85b07da96e458d25b2ffe19fece9f2caa13ed86"
integrity sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg== integrity sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==