diff --git a/README.md b/README.md index de177ce..bba3f16 100644 --- a/README.md +++ b/README.md @@ -14,31 +14,31 @@ Every Sourcebit plugin must define the questions that should be asked and proces The list of plugins offered by the interactive setup process is pulled from the `plugins.json` file in the root of the repository. It's an array of objects with the following properties: -- `module` (String): The name of the plugin's npm module - - _Example_: `sourcebit-source-contentful` -- `description` (String): A human-friendly description of the plugin - - _Example_: `A Contentful source plugin for Sourcebit` -- `author` (String): The name/handle of the plugin's author - - _Example_: `John Doe ` -- `type` (enum: `source|target`): The type of plugin - - _Example_: `source` +- `module` (String): The name of the plugin's npm module + - _Example_: `sourcebit-source-contentful` +- `description` (String): A human-friendly description of the plugin + - _Example_: `A Contentful source plugin for Sourcebit` +- `author` (String): The name/handle of the plugin's author + - _Example_: `John Doe ` +- `type` (enum: `source|target`): The type of plugin + - _Example_: `source` _plugins.json_ ```json [ - { - "module": "/Users/eduardoboucas/Sites/sourcebit-source-contentful", - "description": "A Contentful source plugin for Sourcebit", - "author": "Stackbit", - "type": "source" - }, - { - "module": "/Users/eduardoboucas/Sites/sourcebit-target-jekyll", - "description": "A Sourcebit plugin for Jekyll", - "author": "Stackbit", - "type": "target" - } + { + "module": "/Users/eduardoboucas/Sites/sourcebit-source-contentful", + "description": "A Contentful source plugin for Sourcebit", + "author": "Stackbit", + "type": "source" + }, + { + "module": "/Users/eduardoboucas/Sites/sourcebit-target-jekyll", + "description": "A Sourcebit plugin for Jekyll", + "author": "Stackbit", + "type": "target" + } ] ``` diff --git a/index.js b/index.js index 3c5531d..512ced7 100644 --- a/index.js +++ b/index.js @@ -1,82 +1,86 @@ #!/usr/bin/env node -require("dotenv").config(); -const chalk = require("chalk"); -const fs = require("fs"); -const mri = require("mri"); -const ora = require("ora"); -const path = require("path"); -const util = require("util"); -const Wizard = require("./lib/wizard"); +require('dotenv').config(); +const chalk = require('chalk'); +const fs = require('fs'); +const mri = require('mri'); +const ora = require('ora'); +const path = require('path'); +const prettier = require('prettier'); +const util = require('util'); +const Wizard = require('./lib/wizard'); (async () => { - const configPath = path.join(process.cwd(), "sourcebit.js"); - - let currentConfig = {}; - - try { - currentConfig = require(configPath); - } catch (_) {} - - const parameters = mri(process.argv.slice(2)); - const wizard = new Wizard(parameters); - const { errors, plugins, envFileOptions } = await wizard.start({ - currentConfig - }); - const moduleExports = util.inspect( - { - plugins - }, - { compact: false, depth: null } - ); - const config = `module.exports = ${moduleExports}\n`; - - console.log(""); - - // Writing configuration file. - try { - fs.writeFileSync(configPath, config); - - const errorCount = Object.keys(errors).length; - - if (errorCount > 0) { - ora( - `Configuration saved to ${chalk.bold(configPath)}, but ${chalk.bold( - errorCount - )} ${errorCount > 1 ? "errors" : "error"} occurred.\n` - ).warn(); - } else { - ora(`Configuration saved to ${chalk.bold(configPath)}.\n`).succeed(); + const configPath = path.join(process.cwd(), 'sourcebit.js'); + + let currentConfig = {}; + + try { + currentConfig = require(configPath); + } catch (_) {} + + const parameters = mri(process.argv.slice(2)); + const wizard = new Wizard(parameters); + const { errors, plugins, envFileOptions } = await wizard.start({ + currentConfig + }); + const moduleExports = util.inspect( + { + plugins + }, + { compact: false, depth: null } + ); + + let config = `module.exports = ${moduleExports}\n`; + + try { + config = prettier.format(config, { parser: 'babel', trailingComma: 'none' }); + } catch (error) { + ora('Could not format configuration file.').warn(); } - } catch (error) { - console.log(error); - console.log("ERROR: Could not create configuration file."); - - process.exit(1); - } - - // Writing env file. - try { - const envFileData = Object.keys(envFileOptions) - .map(key => `${key}=${envFileOptions[key]}`) - .join("\n"); - - if (envFileData.length > 0) { - const envFilePath = path.join(process.cwd(), ".env"); - - fs.writeFileSync(envFilePath, envFileData + "\n"); - - ora(`Environment file saved to ${chalk.bold(envFilePath)}.`).succeed(); - ora( - `Make sure not to commit this file to version control. Perhaps you want to add it to ${chalk.bold( - ".gitignore" - )}?` - ).warn(); + + console.log(''); + + // Writing configuration file. + try { + fs.writeFileSync(configPath, config); + + const errorCount = Object.keys(errors).length; + + if (errorCount > 0) { + ora( + `Configuration saved to ${chalk.bold(configPath)}, but ${chalk.bold(errorCount)} ${ + errorCount > 1 ? 'errors' : 'error' + } occurred.\n` + ).warn(); + } else { + ora(`Configuration saved to ${chalk.bold(configPath)}.\n`).succeed(); + } + } catch (error) { + ora('ERROR: Could not create configuration file.').fail(); + console.log(error); + + process.exit(1); } - } catch (error) { - console.log(error); - ora("Could not create environment file.\n").fail(); + // Writing env file. + try { + const envFileData = Object.keys(envFileOptions) + .map((key) => `${key}=${envFileOptions[key]}`) + .join('\n'); + + if (envFileData.length > 0) { + const envFilePath = path.join(process.cwd(), '.env'); + + fs.writeFileSync(envFilePath, envFileData + '\n'); - process.exit(1); - } + ora(`Environment file saved to ${chalk.bold(envFilePath)}.`).succeed(); + ora(`Make sure not to commit this file to version control. Perhaps you want to add it to ${chalk.bold('.gitignore')}?`).warn(); + } + } catch (error) { + console.log(error); + + ora('Could not create environment file.\n').fail(); + + process.exit(1); + } })(); diff --git a/lib/wizard.js b/lib/wizard.js index c5b31ee..5e03eaf 100644 --- a/lib/wizard.js +++ b/lib/wizard.js @@ -1,49 +1,44 @@ -const chalk = require("chalk"); -const debug = require("debug"); -const { exec } = require("child_process"); -const inquirer = require("inquirer"); -const ora = require("ora"); -const path = require("path"); -const pkg = require("../package.json"); -const pluginRegistry = require("../plugins.json"); -const { Sourcebit } = require("sourcebit"); -const WrappedFunction = require("./wrapped-function"); +const chalk = require('chalk'); +const debug = require('debug'); +const { exec } = require('child_process'); +const inquirer = require('inquirer'); +const ora = require('ora'); +const path = require('path'); +const pkg = require('../package.json'); +const pluginRegistry = require('../plugins.json'); +const { Sourcebit } = require('sourcebit'); +const WrappedFunction = require('./wrapped-function'); class Wizard { - constructor(parameters) { - this.debug = debug("wizard"); + constructor(parameters) { + this.debug = debug('wizard'); - this.pluginRegistry = pluginRegistry; + this.pluginRegistry = pluginRegistry; - if (typeof parameters.plugins === "string") { - try { - const localPluginRegistry = require(path.resolve( - process.cwd(), - parameters.plugins - )); + if (typeof parameters.plugins === 'string') { + try { + const localPluginRegistry = require(path.resolve(process.cwd(), parameters.plugins)); - if (!Array.isArray(localPluginRegistry)) { - throw new Error("Plugin registry must be an array"); - } + if (!Array.isArray(localPluginRegistry)) { + throw new Error('Plugin registry must be an array'); + } - this.pluginRegistry = this.pluginRegistry.concat(localPluginRegistry); - } catch (error) { - ora( - "Could not load local plugin registry file. Is the path correct? Is it well-formatted?" - ).fail(); + this.pluginRegistry = this.pluginRegistry.concat(localPluginRegistry); + } catch (error) { + ora('Could not load local plugin registry file. Is the path correct? Is it well-formatted?').fail(); - this.debug(error); - } - } + this.debug(error); + } + } - this.parameters = parameters; - this.getSetupContext = this.getSetupContext.bind(this); - this.setSetupContext = this.setSetupContext.bind(this); - this.setupContext = {}; - } + this.parameters = parameters; + this.getSetupContext = this.getSetupContext.bind(this); + this.setSetupContext = this.setSetupContext.bind(this); + this.setupContext = {}; + } - getHeader() { - return ` + getHeader() { + return ` _____ ____ _ _ _____ _____ ______ ____ _____ _______ / ____|/ __ \\| | | | __ \\ / ____| ____| _ \\_ _|__ __| | (___ | | | | | | | |__) | | | |__ | |_) || | | | @@ -52,299 +47,265 @@ class Wizard { |_____/ \\____/ \\____/|_| \\_\\\\_____|______|____/_____| |_| ${chalk.dim(`v${pkg.version}`)} `; - } + } - getSetupContext() { - return this.setupContext; - } + getSetupContext() { + return this.setupContext; + } - initializePackage() { - return new Promise((resolve, reject) => { - exec(`npm init -y`, (error, stdout) => { - if (error !== null) { - reject(error); - } + initializePackage() { + return new Promise((resolve, reject) => { + exec(`npm init -y`, (error, stdout) => { + if (error !== null) { + reject(error); + } - resolve(stdout); - }); - }); - } - - installPlugins(pluginNames) { - const installablePluginNames = pluginNames.filter(pluginName => { - return pluginName && pluginName[0] !== path.sep && pluginName[0] !== "."; - }); - const modules = ["sourcebit"].concat(installablePluginNames).join(" "); - - return new Promise((resolve, reject) => { - exec(`npm install ${modules} --save`, (error, stdout) => { - if (error !== null) { - reject(error); - } + resolve(stdout); + }); + }); + } - resolve(stdout); - }); - }); - } - - loadPlugins(pluginNames) { - const plugins = {}; - - pluginNames.forEach(pluginName => { - // Ideally we would `require(pluginName)`, but that fails. Presumably - // because the module has just been installed in a child process, so - // the main process isn't able to resolve its name just yet. To get - // around that, we `require` the plugin by its path. The exception is - // when the plugin name is an absolute path, which may happen in a - // development environment. When that happens, we `require` directly. - const requirePath = - pluginName[0] === path.sep || pluginName[0] === "." - ? pluginName - : path.join(process.cwd(), "node_modules", pluginName); - const plugin = require(requirePath); - - plugins[pluginName] = plugin; - }); - - return plugins; - } - - log(message, messageType = "info") { - const oraMethod = ["succeed", "fail", "warn", "info"].includes(messageType) - ? messageType - : "info"; - - return ora(message)[oraMethod](); - } - - setSetupContext(newContext) { - this.setupContext = { ...this.setupContext, ...newContext }; - } - - async start({ currentConfig }) { - console.log(this.getHeader()); - - let activeSpinner = ora("Looking for plugins\n").start(); - - try { - const pluginsByType = this.pluginRegistry.reduce((result, item) => { - result[item.type] = result[item.type] || []; - result[item.type].push({ - name: `${item.module} (by ${item.author}): ${item.description}`, - value: item.module, - short: item.module + installPlugins(pluginNames) { + const installablePluginNames = pluginNames.filter((pluginName) => { + return pluginName && pluginName[0] !== path.sep && pluginName[0] !== '.'; }); + const modules = ['sourcebit'].concat(installablePluginNames).join(' '); - return result; - }, {}); - - activeSpinner.succeed( - "Welcome to Sourcebit! We'll now guide you through the process of selecting and configuring a set of plugins, which will allow you to fetch data from different sources and transform it into any format you need.\n" - ); - - const questions = [ - { - when: Boolean(pluginsByType.source), - type: "checkbox", - name: "stage1Plugins", - message: `Select the source plugins. ${chalk.reset.dim( - "They define the sources of your data." - )}`, - choices: pluginsByType.source || [], - validate: value => - value.length > 0 - ? true - : "You must select at least one source plugin." - }, - { - when: Boolean(pluginsByType.transform), - type: "checkbox", - name: "stage2Plugins", - message: `Select the transformation plugins. ${chalk.reset.dim( - "They perform different transformation operations on the data coming from the source plugins." - )}`, - choices: pluginsByType.transform || [] - }, - { - when: Boolean(pluginsByType.target), - type: "checkbox", - name: "stage3Plugins", - message: `Select the target plugins. ${chalk.reset.dim( - "They write data in a location and format expected by the software you're using." - )}`, - choices: pluginsByType.target || [] - } - ]; - - const { stage1Plugins } = await inquirer.prompt(questions[0]); - const { stage2Plugins } = await inquirer.prompt(questions[1]); - const { stage3Plugins } = await inquirer.prompt(questions[2]); - const allPlugins = stage1Plugins - .concat(stage2Plugins) - .concat(stage3Plugins) - .filter(Boolean); - - console.log(""); - activeSpinner = ora("Installing plugins\n").start(); - - await this.initializePackage(); - await this.installPlugins(allPlugins); - - activeSpinner.succeed(); - - const pluginModules = this.loadPlugins(allPlugins); - const pluginBlocks = allPlugins.map(pluginName => ({ - module: pluginModules[pluginName], - options: {} - })); - const sourcebit = new Sourcebit({ - runtimeParameters: { - quiet: true - } - }); - - sourcebit.loadPlugins(pluginBlocks); - - let setupData = Promise.resolve({ - envFileOptions: {}, - errors: {}, - plugins: [] - }); - - allPlugins.forEach((pluginName, pluginIndex, plugins) => { - setupData = setupData.then(async setupData => { - console.log( - `\nConfiguring plugin ${pluginIndex + 1} of ${ - plugins.length - }: ${chalk.bold(pluginName)}\n` - ); - - const data = await sourcebit.transform(); - const context = sourcebit.getContext(); - const { - getOptionsFromSetup, - getSetup, - options: optionsSchema = {} - } = pluginModules[pluginName]; - const pluginDebug = debug(`plugin:${pluginName}`); - - if ( - typeof getOptionsFromSetup !== "function" || - typeof getSetup !== "function" - ) { - return; - } - - const currentPluginBlock = (currentConfig.plugins || []).find( - plugin => - plugin.module && - plugin.module.name === pluginModules[pluginName].name - ); - const currentOptions = - (currentPluginBlock && currentPluginBlock.options) || {}; - - try { - const setup = getSetup({ - chalk, - context, - currentOptions, - data, - debug: pluginDebug, - getSetupContext: this.getSetupContext, - inquirer, - log: this.log, - ora, - setSetupContext: this.setSetupContext + return new Promise((resolve, reject) => { + exec(`npm install ${modules} --save`, (error, stdout) => { + if (error !== null) { + reject(error); + } + + resolve(stdout); }); + }); + } - let setupAnswers = {}; + loadPlugins(pluginNames) { + const plugins = {}; + + pluginNames.forEach((pluginName) => { + // Ideally we would `require(pluginName)`, but that fails. Presumably + // because the module has just been installed in a child process, so + // the main process isn't able to resolve its name just yet. To get + // around that, we `require` the plugin by its path. The exception is + // when the plugin name is an absolute path, which may happen in a + // development environment. When that happens, we `require` directly. + const requirePath = + pluginName[0] === path.sep || pluginName[0] === '.' ? pluginName : path.join(process.cwd(), 'node_modules', pluginName); + const plugin = require(requirePath); + + plugins[pluginName] = plugin; + }); - if (Array.isArray(setup)) { - setupAnswers = await inquirer.prompt(setup); - } else if (typeof setup === "function") { - setupAnswers = await setup(); - } + return plugins; + } - const pluginOptions = - (await getOptionsFromSetup({ - answers: setupAnswers, - debug: pluginDebug, - getSetupContext: this.getSetupContext, - log: this.log, - setSetupContext: this.setSetupContext - })) || {}; + log(message, messageType = 'info') { + const oraMethod = ['succeed', 'fail', 'warn', 'info'].includes(messageType) ? messageType : 'info'; - sourcebit.setOptionsForPluginAtIndex(pluginIndex, pluginOptions); + return ora(message)[oraMethod](); + } - await sourcebit.bootstrapPluginAtIndex(pluginIndex); + setSetupContext(newContext) { + this.setupContext = { ...this.setupContext, ...newContext }; + } - const publicOptions = {}; - const privateOptions = {}; + async start({ currentConfig }) { + console.log(this.getHeader()); + + let activeSpinner = ora('Looking for plugins\n').start(); + + try { + const pluginsByType = this.pluginRegistry.reduce((result, item) => { + result[item.type] = result[item.type] || []; + result[item.type].push({ + name: `${item.module} (by ${item.author}): ${item.description}`, + value: item.module, + short: item.module + }); + + return result; + }, {}); + + activeSpinner.succeed( + "Welcome to Sourcebit! We'll now guide you through the process of selecting and configuring a set of plugins, which will allow you to fetch data from different sources and transform it into any format you need.\n" + ); + + const questions = [ + { + when: Boolean(pluginsByType.source), + type: 'checkbox', + name: 'stage1Plugins', + message: `Select the source plugins. ${chalk.reset.dim('They define the sources of your data.')}`, + choices: pluginsByType.source || [], + validate: (value) => (value.length > 0 ? true : 'You must select at least one source plugin.') + }, + { + when: Boolean(pluginsByType.transform), + type: 'checkbox', + name: 'stage2Plugins', + message: `Select the transformation plugins. ${chalk.reset.dim( + 'They perform different transformation operations on the data coming from the source plugins.' + )}`, + choices: pluginsByType.transform || [] + }, + { + when: Boolean(pluginsByType.target), + type: 'checkbox', + name: 'stage3Plugins', + message: `Select the target plugins. ${chalk.reset.dim( + "They write data in a location and format expected by the software you're using." + )}`, + choices: pluginsByType.target || [] + } + ]; - // Finding private/public options and environment variables. - Object.keys(pluginOptions).forEach(key => { - const schema = optionsSchema[key] || {}; + const { stage1Plugins } = await inquirer.prompt(questions[0]); + const { stage2Plugins } = await inquirer.prompt(questions[1]); + const { stage3Plugins } = await inquirer.prompt(questions[2]); + const allPlugins = stage1Plugins.concat(stage2Plugins).concat(stage3Plugins).filter(Boolean); - if (schema.env) { - if (schema.private) { - privateOptions[schema.env] = pluginOptions[key]; - } + console.log(''); + activeSpinner = ora('Installing plugins\n').start(); - if (pluginOptions[key] === undefined || schema.private) { - publicOptions[key] = new WrappedFunction( - `process.env['${schema.env}']` - ); - } else { - publicOptions[key] = new WrappedFunction( - `process.env['${schema.env}'] || ${JSON.stringify( - pluginOptions[key] - )}` - ); - } - } else { - if (!schema.private) { - publicOptions[key] = pluginOptions[key]; + await this.initializePackage(); + await this.installPlugins(allPlugins); + + activeSpinner.succeed(); + + const pluginModules = this.loadPlugins(allPlugins); + const pluginBlocks = allPlugins.map((pluginName) => ({ + module: pluginModules[pluginName], + options: {} + })); + const sourcebit = new Sourcebit({ + runtimeParameters: { + quiet: true } - } }); - return { - ...setupData, - envFileOptions: { - ...setupData.envFileOptions, - ...privateOptions - }, - plugins: setupData.plugins.concat({ - module: new WrappedFunction(`require('${pluginName}')`), - options: publicOptions - }) - }; - } catch (error) { - ora( - `Plugin ${chalk.bold( - pluginName - )} could not be configured due to a fatal error.` - ).fail(); - - console.error(error); - - return { - ...setupData, - errors: { - ...setupData.errors, - [pluginName]: error - } - }; - } - }); - }); + sourcebit.loadPlugins(pluginBlocks); - return setupData; - } catch (error) { - activeSpinner.fail("An error occured. More details below\n"); - console.log(error); + let setupData = Promise.resolve({ + envFileOptions: {}, + errors: {}, + plugins: [] + }); + + allPlugins.forEach((pluginName, pluginIndex, plugins) => { + setupData = setupData.then(async (setupData) => { + console.log(`\nConfiguring plugin ${pluginIndex + 1} of ${plugins.length}: ${chalk.bold(pluginName)}\n`); + + const data = await sourcebit.transform(); + const context = sourcebit.getContext(); + const { getOptionsFromSetup, getSetup, options: optionsSchema = {} } = pluginModules[pluginName]; + const pluginDebug = debug(`plugin:${pluginName}`); + + if (typeof getOptionsFromSetup !== 'function' || typeof getSetup !== 'function') { + return; + } + + const currentPluginBlock = (currentConfig.plugins || []).find( + (plugin) => plugin.module && plugin.module.name === pluginModules[pluginName].name + ); + const currentOptions = (currentPluginBlock && currentPluginBlock.options) || {}; + + try { + const setup = getSetup({ + chalk, + context, + currentOptions, + data, + debug: pluginDebug, + getSetupContext: this.getSetupContext, + inquirer, + log: this.log, + ora, + setSetupContext: this.setSetupContext + }); + + let setupAnswers = {}; + + if (Array.isArray(setup)) { + setupAnswers = await inquirer.prompt(setup); + } else if (typeof setup === 'function') { + setupAnswers = await setup(); + } + + const pluginOptions = + (await getOptionsFromSetup({ + answers: setupAnswers, + debug: pluginDebug, + getSetupContext: this.getSetupContext, + log: this.log, + setSetupContext: this.setSetupContext + })) || {}; + + sourcebit.setOptionsForPluginAtIndex(pluginIndex, pluginOptions); + + await sourcebit.bootstrapPluginAtIndex(pluginIndex); + + const publicOptions = {}; + const privateOptions = {}; + + // Finding private/public options and environment variables. + Object.keys(pluginOptions).forEach((key) => { + const schema = optionsSchema[key] || {}; + + if (schema.env) { + if (schema.private) { + privateOptions[schema.env] = pluginOptions[key]; + } + + if (pluginOptions[key] === undefined || schema.private) { + publicOptions[key] = new WrappedFunction(`process.env['${schema.env}']`); + } else { + publicOptions[key] = new WrappedFunction( + `process.env['${schema.env}'] || ${JSON.stringify(pluginOptions[key])}` + ); + } + } else { + if (!schema.private) { + publicOptions[key] = pluginOptions[key]; + } + } + }); + + return { + ...setupData, + envFileOptions: { + ...setupData.envFileOptions, + ...privateOptions + }, + plugins: setupData.plugins.concat({ + module: new WrappedFunction(`require('${pluginName}')`), + options: publicOptions + }) + }; + } catch (error) { + ora(`Plugin ${chalk.bold(pluginName)} could not be configured due to a fatal error.`).fail(); + + console.error(error); + + return { + ...setupData, + errors: { + ...setupData.errors, + [pluginName]: error + } + }; + } + }); + }); + + return setupData; + } catch (error) { + activeSpinner.fail('An error occured. More details below\n'); + console.log(error); + } } - } } module.exports = Wizard; diff --git a/lib/wrapped-function.js b/lib/wrapped-function.js index fbc7430..ea113c5 100644 --- a/lib/wrapped-function.js +++ b/lib/wrapped-function.js @@ -1,39 +1,29 @@ -const util = require("util"); - -Function.prototype[util.inspect.custom] = function(_, { indentationLvl }) { - const fnSource = this.toString(); - const indentedSource = fnSource - .split("\n") - .map((line, index, lines) => { - // Oddly, the `toString` method adds a line break after the last - // parameter in the function signature. We get rid of it here. - if (index === 0) { - return (line + (lines[1] || "")).replace( - "function anonymous", - "function" - ); - } - - if (index === 1) return null; - - const isLastLine = index === lines.length - 1; - - return " ".repeat(indentationLvl + (isLastLine ? 0 : 2)) + line; - }) - .filter(Boolean) - .join("\n"); - - return indentedSource; +const util = require('util'); + +Function.prototype[util.inspect.custom] = function (_, { indentationLvl }) { + const fnSource = this.toString(); + const indentedSource = fnSource + .split('\n') + .map((line, index) => { + if (index === 0) { + return line.replace('function anonymous', 'function'); + } + + return line; + }) + .join('\n'); + + return indentedSource; }; class WrappedFunction { - constructor(fn) { - this.fn = fn; - } + constructor(fn) { + this.fn = fn; + } - [util.inspect.custom]() { - return this.fn.toString(); - } + [util.inspect.custom]() { + return this.fn.toString(); + } } module.exports = WrappedFunction; diff --git a/package-lock.json b/package-lock.json index 2dce4b3..f0984ad 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "create-sourcebit", - "version": "0.8.0", + "version": "0.10.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -120,6 +120,12 @@ "any-observable": "^0.3.0" } }, + "@stackbit/prettier-config": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@stackbit/prettier-config/-/prettier-config-1.0.0.tgz", + "integrity": "sha512-A4l7u+u7Lz91boS7W3INjGV59iWoA8ptkKqA0IZ8/6VmpvlRBkJ8oktIa9i4LIKFc3ldabaZ9BRDBH6GojkGew==", + "dev": true + }, "@types/color-name": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", @@ -1670,10 +1676,9 @@ } }, "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", - "dev": true + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.5.tgz", + "integrity": "sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==" }, "pump": { "version": "3.0.0", diff --git a/package.json b/package.json index b292b76..64b0dc2 100644 --- a/package.json +++ b/package.json @@ -1,54 +1,56 @@ { - "name": "create-sourcebit", - "version": "0.8.0", - "description": "Create and configure a Sourcebit installation", - "main": "index.js", - "bin": { - "create-sourcebit": "./index.js" - }, - "dependencies": { - "chalk": "^3.0.0", - "debug": "^4.1.1", - "dotenv": "^8.2.0", - "inquirer": "^7.0.3", - "mri": "^1.1.4", - "ora": "^4.0.3", - "sourcebit": "^0.2.2" - }, - "devDependencies": { - "husky": "^4.2.0", - "lint-staged": "^9.5.0", - "prettier": "^1.19.1" - }, - "scripts": { - "test": "npm run format", - "format": "prettier --write \"./**/*.{js,json,jsx,md,html}\"" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/stackbithq/sourcebit.git" - }, - "keywords": [ - "headless", - "headless-cms", - "jamstack", - "ssg" - ], - "author": "Stackbit", - "license": "MIT", - "bugs": { - "url": "https://github.com/stackbithq/sourcebit/issues" - }, - "homepage": "https://github.com/stackbithq/sourcebit#readme", - "husky": { - "hooks": { - "pre-commit": "lint-staged" - } - }, - "lint-staged": { - "*.{js,jsx,md,html}": [ - "npm run format", - "git add" - ] - } + "name": "create-sourcebit", + "version": "0.10.0", + "description": "Create and configure a Sourcebit installation", + "main": "index.js", + "bin": { + "create-sourcebit": "./index.js" + }, + "dependencies": { + "chalk": "^3.0.0", + "debug": "^4.1.1", + "dotenv": "^8.2.0", + "inquirer": "^7.0.3", + "mri": "^1.1.4", + "ora": "^4.0.3", + "prettier": "^2.0.5", + "sourcebit": "^0.2.2" + }, + "devDependencies": { + "@stackbit/prettier-config": "^1.0.0", + "husky": "^4.2.0", + "lint-staged": "^9.5.0" + }, + "scripts": { + "test": "npm run format", + "format": "prettier --write \"./**/*.{js,json,jsx,md,html}\"" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/stackbithq/sourcebit.git" + }, + "keywords": [ + "headless", + "headless-cms", + "jamstack", + "ssg" + ], + "author": "Stackbit", + "license": "MIT", + "bugs": { + "url": "https://github.com/stackbithq/sourcebit/issues" + }, + "homepage": "https://github.com/stackbithq/sourcebit#readme", + "husky": { + "hooks": { + "pre-commit": "lint-staged" + } + }, + "lint-staged": { + "*.{js,jsx,md,html}": [ + "npm run format", + "git add" + ] + }, + "prettier": "@stackbit/prettier-config" } diff --git a/plugins.json b/plugins.json index c75796b..ce473ea 100644 --- a/plugins.json +++ b/plugins.json @@ -1,44 +1,50 @@ [ - { - "module": "sourcebit-sample-plugin", - "description": "A sample source plugin with mock data", - "author": "Stackbit", - "type": "source" - }, - { - "module": "sourcebit-source-contentful", - "description": "A Contentful source plugin for Sourcebit", - "author": "Stackbit", - "type": "source" - }, - { - "module": "sourcebit-source-sanity", - "description": "A Sanity.io source plugin for Sourcebit", - "author": "Stackbit", - "type": "source" - }, - { - "module": "sourcebit-target-jekyll", - "description": "A Sourcebit plugin for Jekyll", - "author": "Stackbit", - "type": "target" - }, - { - "module": "sourcebit-transform-assets", - "description": "Downloads remote assets", - "author": "Stackbit", - "type": "transform" - }, - { - "module": "sourcebit-target-hugo", - "description": "A Sourcebit plugin for Hugo", - "author": "Stackbit", - "type": "target" - }, - { - "module": "sourcebit-target-next", - "description": "A Sourcebit plugin for Next.js", - "author": "Stackbit", - "type": "target" - } + { + "module": "sourcebit-sample-plugin", + "description": "A sample source plugin with mock data", + "author": "Stackbit", + "type": "source" + }, + { + "module": "sourcebit-source-contentful", + "description": "A Contentful source plugin for Sourcebit", + "author": "Stackbit", + "type": "source" + }, + { + "module": "sourcebit-source-sanity", + "description": "A Sanity.io source plugin for Sourcebit", + "author": "Stackbit", + "type": "source" + }, + { + "module": "@kentico/sourcebit-source-kontent", + "description": "A Kontent source plugin for Sourcebit", + "author": "Kentico", + "type": "source" + }, + { + "module": "sourcebit-target-jekyll", + "description": "A Sourcebit plugin for Jekyll", + "author": "Stackbit", + "type": "target" + }, + { + "module": "sourcebit-transform-assets", + "description": "Downloads remote assets", + "author": "Stackbit", + "type": "transform" + }, + { + "module": "sourcebit-target-hugo", + "description": "A Sourcebit plugin for Hugo", + "author": "Stackbit", + "type": "target" + }, + { + "module": "sourcebit-target-next", + "description": "A Sourcebit plugin for Next.js", + "author": "Stackbit", + "type": "target" + } ]