Parse Platform Function Plugin
Parse Platform Function Plugin 🚀
This is a Webpack plugin designed to make development on top of the Parse Platform more seamless.
If you're familiar with Next.js, you know that the routes are built out based on the file structure of the project. This follows a similar methodology.
The default file structure looks like this:
- src
- functions
<serviceName>
- schema.json -- the schema of the
Parse.Object
-based service <hookName>
0.<hookName>.ts
- config.ts -- the configuration object to be passed to
Parse.Cloud.<hookName>(<className>, <handler>, <config>)
- functions
<functionName>.ts
- functions to be defined withParse.Cloud.define('<functionName>', <function>)
- jobs
<jobName>.ts
- jobs to be defined withParse.Cloud.job('<functionName>', <function>)
- triggers
<triggerName>.ts
- post-hook triggers that will conditionally runParse.Cloud.run('<triggerName>', payload)
, wherepayload
is the parameter of the running hook
- schema.json -- the schema of the
..<more services>...
- functions
The available hooks are:
- beforeSave
- afterSave
- beforeDelete
- afterDelete
- afterCreate
- afterUpdate
- beforeCreate
- beforeUpdate
These hooks targeted at cron jobs are defined and available to be run with Parse.Cloud.startJob('<ClassName>_<frequency>')
- hourly -- e.g.
Parse.Cloud.startJob('ActionItem_hourly')
- daily
- weekly
- monthly
- datetime
This is a special type of Parse.Object
that is used to trigger cascading actions conditionally when a hook is run.
There are 4 conditions that must be met before an ActionTrigger will take effect:
ActionTrigger.active
is trueActionTrigger.objectClass
matches the class of Parse.Object that is being run through the hookobject[ActionTrigger.property]
->ActionTrigger.condition
->ActionTrigger.value
. For example:user.email
->equalTo
->[email protected]
-- this trigger will run only when theUser
instance'semail
property is equal to[email protected]
ActionTrigger.handler
is equal to an extant trigger handler function name (i.e. in thesrc/functions/<serviceName>/triggers/<someTriggerHandler>.ts
)
If your project doesn't need to trigger cascading function calls, you won't need to worry about this.
This is a normal Webpack plugin and can be used like so:
// webpack.config.js
const path = require('path');
const ParseFunctionsPlugin = require('../dist/main').default;
const config = {
entry: './src/index.ts',
output: {
path: path.resolve(__dirname, 'dist'),
},
plugins: [
new ParseFunctionsPlugin(),
],
// ...and the rest
};
{
functionDirectory: 'src/functions', // the directory to watch & build Parse functions
moduleAlias: '@@functions', // the alias name used for importing the built files
// from, e.g. `import initialize, { ClassNames } from '@@functions';`
}
The default option should be preferred, but there may be times where the project requires that you diverge from these naming conventions.
When the plugin runs, it will aggregate the files (according to the file structure above) and transpile them into modules in a .build
folder that may then be accessed by importing members from the moduleAlias
(default @@functions
);
After building, the built modules can be accessed using the module alias (default: @@functions
), and will export the following.
export enum ClassNames {
[<ClassName>]: '<ClassName>'
}
export const ClassNamesList = Object.values(ClassNames);
export const TriggerHandlers: TriggerHandlersMap = {
<ClassName>: [
{
label: "<triggerHandlerName>",
value: "<triggerHandlerName>",
},
],
};
export const Schemas: SchemaMap = {
[<ClassName>]: { /* ...JSON object representation of Parse.Object<ClassName> schema */ }
}
export type SchemaMap = {
[prop in ClassNames]: ParseFunctionServiceSchema;
};
export type TriggerHandlerOption = {
label: string;
value: string;
};
export type TriggerHandlersMap = {
[prop in ClassNames]: TriggerHandlerOption[];
};
/* === INITIALIZER === */
const initialize = (Parse: ParseType) => {
<serviceName>(Parse);
/* ... more services here ... */
};
export default initialize;
- Create custom hook handlers for:
- beforeCreate -- fires before the initial creation of an object
- afterCreate -- fires after the initial creation of an object
- beforeUpdate -- fires before a previously created object is updated
- afterUpdate -- fires after a previously created object is updated
- hourly -- a cron job that fires hourly
- daily -- a cron job that fires daily
- weekly -- a cron job that fires weekly
- monthly -- a cron job that fires monthly
- datetime -- a cron job that fires on a specific datetime
- Make a
processActionTriggers
function to avoid duplicate code - Rework functions, jobs, and triggers to export a factory function that takes a
Parse
instance as the first parameter, a configuration or context parameter, and returns a function - Make helper types for hooks, functions, jobs, and triggers
- Make export for trigger handler parameter schema