5.5 PSL (Pop Script Language)
In most visual workflow cases, you can achieve your goals using drag‑and‑drop nodes + parameter configuration.
However, in certain scenarios, you may still need:
- More fine‑grained data processing (filtering, aggregation, mapping, renaming fields)
- Combining outputs from multiple nodes using complex rules
- Flexible control of global variables
- Writing custom “if … then …” logic
To handle these cases, Pop provides PSL (Pop Script Language):
A lightweight scripting “glue language” that runs inside workflows.
Its syntax resembles TypeScript/JavaScript,
but with special runtime injections such asinput,nodes, andglobals— designed specifically for workflow data operations.
1. Overview of the Script Runtime Environment
Inside nodes that support scripting (e.g., Script Node, Custom Expression, Conditional Script), PSL injects these common objects during execution:
| Identifier | Type / Meaning | Typical Usage |
|---|---|---|
input |
Current node’s input set (list of NodeOutput) | Read upstream outputs, aggregate multiple inputs |
nodes |
Snapshot index of all other nodes in workflow | Read outputs from any node |
globals |
Global variable object, readable/writable | Store counters, settings, shared states |
output |
The node’s final output (return value) |
Determines the output of the script node |
Conceptually, PSL behaves like:
function script({ input, nodes, globals }) {
// Write PSL code here
return ...; // Final output
}
PSL does not provide a full browser environment:
- No
window,document, or DOM - No direct network requests (use HTTP Node instead)
- No direct file access (use file‑related nodes)
Its purpose is workflow data processing & logic orchestration.
2. The input Object: Accessing Node Inputs
input represents all inputs received by the current node and is one of the most frequently used PSL objects.
2.1 Quick Access to the First Input
input.value; // value of the first input item
input.type; // type: "text", "json", etc.
input.meta; // metadata of first input item
input.output; // full output structure
Useful when there is only one upstream input and you simply want to post‑process it.
2.2 Access All Inputs: input[index] / input.all
input[0].value; // value of input #1
input[0].type; // data type
input[0].meta; // metadata
input.all[0].output?.value;
input.all[1].meta;
Both input[index] and input.all[index] support .output / .value / .type / .meta.
2.3 Aggregation Helpers: length / first / byPort / from / flatValues / ofType
input.length;
input.first();
input.byPort("default");
input.from("node_12");
// Collect all values
input.flatValues();
// Filter by data type
input.ofType("text");
input.ofType("text").map((o) => o.value);
Example:
// Combine all text inputs into a paragraph
const text = input
.ofType("text")
.map((o) => o.value)
.join("\n");
return text;
3. The nodes Object: Access Output of Any Node
nodes is a global index mapping for accessing outputs of any workflow node.
3.1 Basic Usage
nodes[1].output.value; // output of node #2
nodes[8].outputs[0].type; // type of node #9's first output
nodes.sn(2).output; // sn(2) = node #3
nodes[3].outputs[1].value; // node #4's second output
nodes[n].output is shorthand for nodes[n].outputs[0].
Example:
const a = nodes[2].output.value;
const b = nodes[5].output.value;
return { equal: a === b, a, b };
4. The globals Object: Global State
globals stores workflow‑level state:
- Counters
- Configuration
- Cached values from previous actions
4.1 Read Globals
globals.name;
globals.config;
4.2 Write Globals (Recommended: globals.set)
globals.set("name", "lisi");
globals.set("counter", (globals.counter || 0) + 1);
return globals.counter;
Always prefer globals.set(key, value) for maintainability.
5. Common Helpers & Snippets
5.1 ofType()
const texts = input.ofType("text");
return texts.map((o) => o.value);
5.2 flatValues()
const values = input.flatValues();
const nodeValues = nodes[1].outputs.flatValues();
6. Common Script Examples
Example 1 — Join All Text Inputs
return input
.ofType("text")
.map((o) => o.value)
.join(" ");
Example 2 — Standard Response Structure
return {
ok: !!input.value,
values: input.flatValues(),
};
Example 3 — Multi‑Type Outputs
return [
{ type: "boolean", value: input.value === "ok" },
{ type: "text", value: String(nodes[1].type) },
];
Example 4 — Conditional Output
if (input.length > 0) {
return input.flatValues().join("\n");
} else {
return "No data";
}
7. Notes & Best Practices
- Keep scripts pure (same input → same output).
- Avoid heavy computation; use dedicated nodes instead.
- Store only state/config in globals.
- Use the in‑editor Script Help Panel for instant references.
8. Summary
PSL is Pop’s built‑in scripting layer that enables:
- Reading workflow‑wide data (
input,nodes,globals) - Flexible logic and branching
- Lightweight data transformation
Recommended usage philosophy:
- Use nodes to build workflows.
- Use PSL only when you need precise logic glue.
- Reuse PSL snippets across workflows for productivity.