Skip to content

PropicSignifi/Pack.apex

Repository files navigation

Pack.apex

Pack.apex is a tool to help you generate Func wrappers for existing Apex classes.

Why Pack.apex?

Sometimes when we want to convert an existing Apex API into a Func, we have to manually create a custom Func to implement that. With Pack.apex, you can easily generate Func wrappers according to your selected Apex APIs.

Dependencies

Pack.apex has a dependency over R.apex

Please include it before including Pack.apex.

Getting Started

Installation

You can include the necessary Apex class files located in the 'src/classes'.

Or you can make customizations and generate the Apex class files before including them.

Introduction

Pack.apex is actually a node-js CLI application that generates the Func wrapper Apex class for you. What you need is the generated Apex class, Pack.cls, which can be further imported to your Org, and used like this:

String userId = (String)Pack.UserInfoCls.getUserId.run();
String userName = (String)Pack.UserInfoCls.getUserName.run();

Here UserInfo.getUserId() is wrapped into a Func Pack.UserInfo.Cls.getUserId, and invoked by calling run. So is it with UserInfo.getUserName().

By default, Pack.apex has already converted most of Salesforce Apex APIs in the namespace of System.

Naming Conventions

If you want to use a Func of TypeName.MethodName, you can refer to Pack.TypeNameCls.MethodName. If the MethodName is a reserved word, use Pack.TypeNameCls.MethodNameFn instead. For example,

List<Object> mList = new List<Object>{ 3, 2, 1};
Pack.ListCls.sortFn.run(mList);

Generate Pack.cls

We can run the CLI application to generate Pack.cls at any time.

First we need to initialize our project. Run the code at the root of the project after you have installed node and npm.

npm install

Run this, which will start to generate Pack.cls.

node generator.js

By default, Pack.apex will read from src/packs and write generated Apex files into src/classes.

Pack Files

The Pack.cls is generated from the source pack files. Here is a sample pack file.

constructor List<Object> :: ()

add :: Object -> void

Each method is specified in one line.

The first word before :: is the method name. If it is a static method, static is appended before its name. If it is a constructor, constructor is appended before its name and the name is the concrete type name.

The string after :: is the functionally annotated method signature. Generally speaking, a -> b -> c represents a function that takes (a, b) and returns c.

Pack.apex will load the source pack files and generate corresponding Funcs.

Hack Files

Sometimes what Pack.apex generates is not what we want, and we can override the generated code by providing our own version, which is placed in hack files.

Here is a hacking code from List_getSObjectType.hack, which hacks the getSObjectType method of List into this.

           else if(funcName == 'getSObjectType' && nthArg(args, 1) instanceof List<Object>) {
                List<SObject> mList = (List<SObject>)R.toSObjectList.run(nthArg(args, 1));
                return mList.getSObjectType();
            }

Configuration

You can customize how to generate Pack.cls by providing your own configuration in config.json in the root of the project.

The default configuration looks like this:

{
    "srcDir": "src/packs",
    "destDir": "src/classes",

    "packFileSuffix": ".pack",
    "hackFileSuffix": ".hack",
    "constructorPrefix": "constructor ",
    "staticPrefix": "static ",

    "apexClassName": "Pack",

    "reservedWords": [ ... ],

    "comment": "// Generated by Pack.apex. Please do not modify this file.",
    "metaFile": "meta.xml",

    "generateFuncPackage": true,
    "generateTestClass": true,

    "skipTestCases": [ ... ]
}

Here are the details about the configuration items.

Key Description
srcDir The source directory where .pack/.hack files are located
destDir The destination directory where Pack.cls is generated to
packFileSuffix The suffix of the pack file, '.pack' by default
hackFileSuffix The suffix of the hack file, '.hack' by default
constructorPrefix The prefix used to indicate the constructor, 'constructor ' by default
staticPrefix The prefix used to indicate the static method, 'static ' by default
apexClassName The generated main Apex class name, 'Pack' by default
reservedWords The reserved key words from Salesforce apex
comment The comment in the generated files
metaFile The path of the meta data xml file
generateFuncPackage Whether to generate Func Package, true by default
generateTestClass Whether to generate test classes, true by default
skipTestCases The list of apex class names whose test cases will be skipped

Releases

No releases published

Packages

No packages published