ApexBlueprint API reference: SBlueprint

Apex Stem Docs
Apex StemApexBlueprintSBlueprintAPI Reference
Complete API reference for the SBlueprint method chain. Covers static factory, set/template, alias, use, times, withChildren, parentIdField, and the {#} / {A} / {a} / {P0}~{Pn} placeholder semantics.

SBlueprint is the method-chain class used in ApexBlueprint to declare a blueprint for a single record. You start from of(...), then stack values, identifiers, parent-child relationships, bulk generation, and references via the chain, and finally hand it to SOrchestrator to execute.

For usage and typical scenarios, see Declaring a Single Record with SBlueprint and Relations, Bulk Generation, and Reference Patterns.

Static Factory

MethodPurpose
SBlueprint.of(System.Type recordType)The starting point of an SBlueprint. Declare the target SObject type, in the form SBlueprint.of(Account.class)

Passing null or a non-SObject type to recordType raises an exception.

Value Setters (Set & Template)

MethodPurpose
set(String fieldName, Object value)Set a value on a single field. Subsequent calls to the same field follow "last wins". Can override values set by template
set(String fieldName, Object value, Integer startAt, Integer interval)Specify the start and step of the {#} placeholder. set('Name', 'Acc-{#}', 10, 2)'Acc-10' / 'Acc-12' / 'Acc-14'
template(Map<String, Object> templateMap)Apply a Map of default values all at once. Recommended in combination with the practice of consolidating shared settings (RecordType, required fields) into Blueprints.cls

Passing a negative value to startAt / interval raises an exception.

APEX
SBlueprint accountBp = SBlueprint.of(Account.class)
    .template(Blueprints.accBasic())     // shared defaults
    .set('Name', 'CustomName')              // individual override
    .set('Index', 'No.{#}', 1, 1);          // {#} sequence

Identifier (Alias)

MethodPurpose
alias(String aliasName)Attach a unique reference name to this blueprint. Later, it can be referenced via .use(alias, ...) or SOrchestrator.getByAlias(alias)
alias(String aliasName, Integer startAt)For aliases containing {#}, specify the start of expansion
alias(String aliasName, Integer startAt, Integer interval)Specify the start and step

Aliases must be unique within SOrchestrator; duplicates raise Duplicate alias detected at runtime. When combining with .times(n), use {#}-bearing aliases like 'con_{#}' so that unique values are issued after expansion.

APEX
SBlueprint.of(Contact.class)
    .alias('con_{#}')        // con_1 / con_2 / con_3
    .times(3);

Reference (Use)

A multi-purpose API for mapping a value from another blueprint into a field on this one. Usable both for "copying an Id into a child's lookup (creating a relationship)" and "copying an arbitrary field value".

MethodPurpose
use(String aliasName, String fromField, String toField)The basic form. Copy fromField from the blueprint named aliasName into this blueprint's toField
use(String aliasName, String fromField, String toField, Integer startAt)When referencing a {#}-bearing alias, specify the start of expansion
use(String aliasName, String fromField, String toField, Integer startAt, Integer interval)Specify the start and step

Passing a negative value to startAt / interval raises an exception. For detailed usage and "uneven mapping" patterns, see Relations, Bulk Generation, and Reference Patterns.

APEX
SBlueprint.of(Contact.class)
    .use('acc_{#}', 'Id', 'AccountId', 6)   // reference acc_6 to acc_10
    .alias('con_{#}', 6)                    // children also start from 6
    .times(5);

Bulk Generation (Times)

MethodPurpose
times(Integer n)Generate n copies of the same blueprint. Passing n <= 0 raises an exception

Using .times(n) inside nested .withChildren(...) causes record counts to multiply across hierarchies (parent 2 × child 2 = 4 children). See Relations, Bulk Generation, and Reference Patterns > Multiplication.

Ordering-Only Dependency (After)

MethodPurpose
after(String alias)Declares only "insert this in a later layer than that alias", with no value copied
after(String alias, Integer startAt)Sets the starting number when referencing an alias containing {#}
after(String alias, Integer startAt, Integer interval)Sets the starting number and step

use() exists to build a reference, so it always carries a value. Use after() when you don't want the value but do need the order — for example when a trigger requires that A already exists before B lands.

APEX
SOrchestrator.start()
  .add(SBlueprint.of(Account.class).template(Blueprints.accBasic()).alias('acc'))
  .add(
    SBlueprint.of(Contact.class)
      .set('LastName', 'Yamada')
      .after('acc')   // just place it in a later layer than acc; copy nothing
  );

Owner & Sharing (Owner & Share)

MethodPurpose
owner(User user)Sets the record owner. Sugar for set('OwnerId', user.Id)
sharedWith(User user, String accessLevel)Declares a manual share as a final state. accessLevel is 'Read' or 'Edit'

Writing sharedWith makes create() auto-generate a sibling blueprint (Foo__Share / AccountShare) that is inserted one layer after the record itself. The parent Id wiring is automatic too.

These live on the blueprint because "who owns this record, and who can see it" is part of the declared final state, exactly like a field value.

APEX
// Owned by an admin, rep gets Read only — the "hostile data" of a runAs audit test
SOrchestrator.start()
  .add(
    SBlueprint.of(Invoice__c.class).alias('inv')
      .owner(admin)
      .sharedWith(rep, 'Read')
  );

It composes with times / nesting / {Pn} (a child's share multiplies along with the child). An object whose OWD is Public, a share aimed at the owner itself, and an invalid accessLevel are all rejected fail-fast.

Parent-Child Relationships

MethodPurpose
withChildren(SBlueprint child)Nest children inside the parent blueprint. The parent Id is automatically copied into the child's lookup. To place children of different SObject types under the same parent, call multiple times: .withChildren(...).withChildren(...)
parentIdField(String fieldName)When the child has multiple lookups, specify which one receives the parent Id. Not needed when the lookup is unambiguous
APEX
SBlueprint.of(Account.class)
    .alias('acc')
    .withChildren(
        SBlueprint.of(Contact.class)
            .parentIdField('AccountId')      // specify when multiple lookups exist
            .set('LastName', 'TestContact')
    );

Placeholders

Special placeholders that can be used inside string arguments to .set / .alias / .use.

PlaceholderExpansion Rule
{#}Numeric sequence 1, 2, 3, .... Expanded for n copies via .times(n). startAt / interval change the start and step
{A}Uppercase alphabetic sequence 'A', 'B', 'C', ...
{a}Lowercase alphabetic sequence 'a', 'b', 'c', ...
{P0} / {P1} / {P2} / ...Hierarchically resolves "the true parent for me" using absolute depth from the root. Mostly used as the first argument to .use('{P1}', ...) to reference the true parent

{P0} ~ {Pn} are the structural solution to the problem where, in nested structures with .times(...) at each tier, the {#} expansion of an alias alone cannot identify "the true parent for me". For motivation and mechanics, see Relations, Bulk Generation, and Reference Patterns > {P0} / {P1} / ....

Common Exceptions

Errors the framework detects are thrown as ApexBlueprintException.

SituationException type / message (excerpt)
of(...) with null or a non-SObject typeApexBlueprintException: invalid type
times(0) or belowApexBlueprintException: Times must be greater than 0
Negative value for startAt / interval on set / alias / useApexBlueprintException: negative value not allowed
Duplicate alias (at create() time)ApexBlueprintException: Duplicate alias detected
Reference to a non-existent alias (typo in use, at create() time)ApexBlueprintException: Circular or invalid reference detected
Ambiguity with multiple lookups (no parentIdField, at create() time)ApexBlueprintException: multiple parent relationships with the same parent object
Field application failure (non-existent / formula / auto-number / non-createable / type mismatch)ApexBlueprintException: with diagnostics (Reason: for the cause, Provided: for the value)
Missing required field or validation-rule violationA plain DmlException, unchanged

The exception type tells you where to look

When create() fails, the type of the exception is itself the diagnosis.

  • ApexBlueprintException = a mistake in the declaration. Fix the test code
  • DmlException = the org refused the insert. Fix the template or the org configuration

Field-application errors are diagnosed all the way down to "which blueprint (alias), through which path (set / template / use), and why (non-existent / formula / auto-number / non-createable / type mismatch)".

⚠️ This is a breaking change in v2.0.0. Previously a plain DmlException was thrown, so existing catch (DmlException) blocks will no longer catch these. Review your catch clauses when migrating.