Unverified Commit 120e193a authored by Bradley Hilton's avatar Bradley Hilton Committed by GitHub
Browse files

Add the submit command (#25)

parent c6d526e0
This diff is collapsed.
import { Command, flags } from '@oclif/command';
import chalk from 'chalk';
import cli from 'cli-ux';
import * as FormData from 'form-data';
import * as fs from 'fs';
import * as fuzzy from 'fuzzy';
import * as inquirer from 'inquirer';
import fetch from 'node-fetch';
import { Response } from 'node-fetch';
import { AppCompiler, AppPackager, FolderDetails, VariousUtils } from '../misc';
export default class Submit extends Command {
public static description = 'submits an App to the Marketplace for review';
public static flags = {
help: flags.help({ char: 'h' }),
// In the future, we will allow people to have their own marketplace instances
// url: flags.string({ description: 'which marketplace should be used' }),
email: flags.string({ char: 'e', description: 'the email of the publisher account' }),
categories: flags.string({
char: 'c',
dependsOn: ['email'],
description: 'a comma separated list of the categories for the App',
}),
};
public async run() {
inquirer.registerPrompt('checkbox-plus', require('inquirer-checkbox-plus-prompt'));
const { flags } = this.parse(Submit);
//#region app packaging
cli.action.start(`${ chalk.green('packaging') } your app`);
const fd = new FolderDetails(this);
try {
await fd.readInfoFile();
} catch (e) {
this.error(e.message);
return;
}
const compiler = new AppCompiler(this, fd);
const report = compiler.logDiagnostics();
if (!report.isValid) {
this.error('TypeScript compiler error(s) occured');
this.exit(1);
return;
}
const packager = new AppPackager(this, fd);
const zipName = await packager.zipItUp();
cli.action.stop('packaged!');
//#endregion
//#region fetching categories
cli.action.start(`${ chalk.green('fetching') } the available categories`);
const categories = await VariousUtils.fetchCategories();
cli.action.stop('fetched!');
//#endregion
//#region asking for information
if (!flags.email) {
const result = await inquirer.prompt([{
type: 'input',
name: 'email',
message: 'What is the publisher\'s email address?',
validate: (answer: string) => {
const regex = /^[^@\s]+@[^@\s]+\.[^@\s]+$/g;
return regex.test(answer);
},
}]);
flags.email = (result as any).email;
}
let selectedCategories = new Array<string>();
if (flags.categories) {
selectedCategories = flags.categories.split(',');
} else {
const result = await inquirer.prompt([{
type: 'checkbox-plus',
name: 'categories',
message: 'Please select the categories which apply to this App?',
pageSize: 10,
highlight: true,
searchable: true,
validate: (answer: Array<string>) => {
if (answer.length === 0) {
return 'You must choose at least one color.';
}
return true;
},
// tslint:disable:promise-function-async
source: (answersSoFar: object, input: string) => {
input = input || '';
return new Promise((resolve) => {
const fuzzyResult = fuzzy.filter(input, categories, {
extract: (item) => item.name,
});
const data = fuzzyResult.map((element) => {
return element.original;
});
resolve(data);
});
},
}] as any);
selectedCategories = (result as any).categories;
}
const confirmSubmitting = await inquirer.prompt([{
type: 'confirm',
name: 'submit',
message: 'Are you ready to submit?',
default: false,
}]);
if (!(confirmSubmitting as any).submit) {
return;
}
//#endregion
cli.action.start(`${ chalk.green('submitting') } your app`);
const data = new FormData();
data.append('app', fs.createReadStream(fd.mergeWithFolder(zipName)));
data.append('email', flags.email);
data.append('categories', JSON.stringify(selectedCategories));
await this.asyncSubmitData(data, flags, fd);
cli.action.stop('submitted!');
}
// tslint:disable:promise-function-async
private async asyncSubmitData(data: FormData, flags: { [key: string]: any }, fd: FolderDetails): Promise<any> {
const res: Response = await fetch('https://marketplace.rocket.chat/v1/apps', {
method: 'POST',
body: data,
});
if (res.status !== 200) {
const result = await res.json();
throw new Error(`Failed to submit the App: ${ result.error } (code: ${ result.code })`);
} else {
return res.json();
}
}
}
export interface IAppCategory {
title: string;
description: string;
name: string;
value: string;
}
import { IAppCategory } from './appCategory';
import { AppCompiler } from './appCompiler';
import { AppCreator } from './appCreator';
import { appJsonSchema } from './appJsonSchema';
......@@ -8,6 +9,7 @@ import { FolderDetails } from './folderDetails';
import { VariousUtils } from './variousUtils';
export {
IAppCategory,
appJsonSchema,
AppCreator,
AppPackager,
......
import * as fs from 'fs';
import fetch from 'node-fetch';
import { IAppCategory } from './appCategory';
export class VariousUtils {
public static slugify = function _slugify(text: string): string {
......@@ -20,4 +23,20 @@ export class VariousUtils {
return '^0.9.13';
};
// tslint:disable:promise-function-async
public static async fetchCategories(): Promise<Array<IAppCategory>> {
const cats = await fetch('https://marketplace.rocket.chat/v1/categories').then((res) => res.json());
const categories: Array<IAppCategory> = cats.map((c: any) => {
return {
title: c.title,
description: c.description,
name: c.title,
value: c.title,
};
});
return categories;
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment