| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Plugins are CommonJS modules with the following exports:
🚨 Required
The name of the plugin. Should match the name property of the module's package.json.
✏️ Exampleconst pkg = require('./package.json')
module.exports.name = pkg.nameThe options expected by the plugin. Each key represents an option. Values are objects with one or more of the following keys:
module.exports.options = {
mySecret: {
// 👉 The value will be read from `process.env.MY_SECRET`.
env: "MY_SECRET",
// 👉 When running the interactive setup process, this
// option will be stored in an `.env` file instead of the
// main configuration file.
private: true
},
watch: {
// 👉 By default, the value of this option will be `false`.
default: false,
// 👉 The value for this option will be read from the `watch`
// runtime parameter, which means that if the user starts
// Sourcebit with `sourcebit fetch --watch`, then the value
// of this option will be set to `true`, regardless of any
// other value defined in the configuration file.
runtimeParameter: "watch"
},
titleCase: {
default: false
}
};A function to be executed when the plugin starts.
It receives a single parameter, which is an object with the following properties:
In source plugins, this method typically contains any asynchronous logic required to fetch data from remote APIs, and then add it to the plugin's context object (using the setPluginContext method) to be used and manipulated later.
Also, if the plugin is expected to poll for changes (e.g. when the --watch flag is used), this is where the polling mechanism should be initialized. Whenever the plugin detects a change, it should call the refresh method to inform the core application and the other plugins that there is new content.
✏️ Examplemodule.exports.bootstrap = async ({
debug,
getPluginContext,
log,
options,
refresh,
setPluginContext
}) => {
// 👉 Get the plugin's context object. This is useful for the
// plugin to share any data between its various methods during
// its runtime lifecycle.
// Additionally, it leverages Sourcebit's caching layer, which
// means that whatever a plugin stores in its context will be
// persisted to disk and loaded automatically on the next run.
const context = getPluginContext();
// 👉 If there are entries in the cache, there's nothing that
// needs to be done right now.
if (context && context.entries) {
log(`Loaded ${context.entries.length} entries from cache`);
} else {
const { data: entries } = await axios.get(
"https://jsonplaceholder.typicode.com/posts"
);
log(`Loaded ${entries.length} entries`);
debug("Initial entries: %O", entries);
// 👉 Adding the newly-generated entries to the plugin's
// context object.
setPluginContext({
entries
});
}
// 👉 If the `watch` option is enabled, we set up a polling routine
// that checks for changes in the data source. In a real-world plugin,
// you'd be doing things like making regular calls to an API to check
// whenever something changes.
if (options.watch) {
setInterval(() => {
const { entries } = getPluginContext();
const entryIndex = Math.floor(Math.random() * entries.length);
entries[entryIndex].body = entries[entryIndex].body + " (updated)";
log(`Updated entry #${entryIndex}`);
debug("Updated entries: %O", entries);
// 👉 We take the new entries array and update the plugin context.
setPluginContext({ entries });
// 👉 After updating the context, we must communicate the change and
// the need for all plugins to re-run in order to act on the new data.
refresh();
}, 3000);
}
};A function to be executed when the plugin starts (after bootstrap() is called) and whenever one of the plugins triggers an update.
Its purpose is to receive and transform an object that contains data buckets, which are arrays of entries. Therefore, the return value of this method must be a new data object.
It receives a single parameter, which is an object with the following properties:
In source plugins, this method typically retrieves the objects and models from the plugin's context (using the getPluginContext method), which have previously been populated by the bootstrap method, and normalizes them to a standard format.
In target plugins, this method can be used to write files. This can be done by appending objects to the files data bucket.
✏️ Examplemodule.exports.transform = ({
data,
debug,
getPluginContext,
log,
options
}) => {
// 👉 Let's retrieve from the plugin's context object the
// entries that we've created in the bootstrap method.
const { entries } = getPluginContext();
// Source plugins are encouraged to add information about their
// models to the `models` data bucket.
const model = {
source: pkg.name,
modelName: "sample-data",
modelLabel: "Mock data",
projectId: "12345",
projectEnvironment: "master",
fieldNames: ["firstName", "lastName", "points"]
};
// 👉 The main purpose of this method is to normalize the
// entries, so that they conform to a standardized format
// used by all source plugins.
const normalizedEntries = entries.map(entry => {
const title = options.titleCase
? entry.title
.split(" ")
.map(word => word[0].toUpperCase() + word.substring(1))
.join(" ")
: entry.title;
return {
...entry,
title,
__metadata: model
};
});
// 👉 The method must return the updated data object, which
// in our case means appending our entries to the `objects`
// property.
return {
...data,
models: data.models.concat(model),
objects: data.objects.concat(normalizedEntries)
};
};A function to be executed aas part of the interactive setup process.
It receives a single parameter, which is an object with the following properties:
module.exports.getSetup = ({
chalk,
context,
currentOptions,
data,
debug,
getSetupContext,
inquirer,
ora,
setSetupContext
}) => {
const questions = [
{
type: "confirm",
name: "titleCase",
message: "Do you want to convert the title field to title-case?",
default: currentOptions.pointsForJane || false
}
];
// 👉 For simple setup processes, this method can simply return
// an array of questions in the format expected by `inquirer`.
// Alternatively, it can run its own setup instance, display
// messages, make external calls, etc. For this, it should return
// a function which, when executed, must return a Promise with
// an answers object.
return async () => {
const spinner = ora("Crunching some numbers...").start();
// ⏳ await runSomeAsyncTask();
spinner.succeed();
const answers = await inquirer.prompt(questions);
return answers;
};
};A function to be executed after the interactive setup process has finished.
The return value must be the object that is to be set as the options block of the plugin configuration in sourcebit.js.
It receives a single parameter, which is an object with the following properties:
module.exports.getOptionsFromSetup = ({
answers,
debug,
getSetupContext,
setSetupContext
}) => {
// 👉 This is a good place to make some transformation to the
// values generated in the setup process before they're added
// to the configuration file.
return {
titleCase: answers.titleCase
};
};| Back | FazBrowse Home | New Git URL |