Loading...
Loading...
Write JavaScript (Node.js v22) for Factorial Code processes and modules — the async main() entry point with module.exports = { main }, fcode.context.parameters, fcode.import(), datastore/storage/env helpers, auto-installed dependencies, and return-value formats. Use when creating or editing .js process or module code for Factorial Code (fcode).
npx skill4agent add factorialco/factorial-code-skills fcode-javascriptfcode-core-concepts| Aspect | Guideline |
|---|---|
| Runtime | Node.js v22 |
| Process entry file | |
| Entry point | |
| Export (required) | |
| Parameters | |
| Variables | |
| Import a module | |
mainmodule.exports = { main }main()fcode.import()fcode.import("shopify-client")fcode.import(name)fcode.i18nfcode.i18n("key")const t = fcode.i18nfcode-i18nJSON.stringifysetgettruesetfcode.datastore.set(key, token, true)getsetasync/awaittry/catchfcode-logsconstletvarprocess.envasync function main() {
const { parameters } = fcode.context;
// Your code here
return { message: "Success!" };
}
module.exports = { main };// Execution / process / schedule metadata
const { id, comment } = fcode.execution;
const { id: processId, name: processName } = fcode.execution.process;
const { id: scheduleId } = fcode.execution.schedule; // when run from a schedule
const timezone = fcode.execution.timezone;
// Workspace (team) metadata
const teamSlug = fcode.team.slug;
// Environment variables (secrets/config)
const apiKey = process.env.API_KEY; // or fcode.env.API_KEY
// Import a Factorial Code module (hardcoded name only)
const { myFunc } = fcode.import("module-name");
const { myFunc: v1 } = fcode.import("module-name", "v1.0.0"); // pinned version tag or alias
// Run another process
await fcode.processes.run("process-identifier", options);
// Translations (workspace locales — see fcode-i18n)
const greeting = fcode.i18n("greetings.hello", { name: "Ada" }); // %{name} filled in
fcode.i18n("greetings.hello", { name: "Ada" }, { locale: "es" }); // another locale, this lookup only (value may be dynamic)
const locale = fcode.i18n.locale; // the execution's localefcode-logsLOG_LEVELdebug | info | warn | errorinfoconsole.*consoleconst log = fcode.import("fcode-logs"); // import once; reuse `log` everywhere, including `catch`
log.info("sync started", { processSlug }); // console.log when LOG_LEVEL ≤ info
log.debug({ requestPayload }); // console.debug only when LOG_LEVEL=debug
log.warn("token missing — skipping"); // console.warn when LOG_LEVEL ≤ warn
log.error("sync failed", err.message); // console.error — always emittedinfodebugcatchfcode-core-conceptsLOG_LEVEL=debuginfofcode-core-conceptsrequire@add-package// @add-package axios
const axios = require("axios");fcode-core-concepts// Datastore (strings/numbers only)
await fcode.datastore.set("key", "value");
await fcode.datastore.set("key", JSON.stringify({ name: "John", age: 30 }));
const value = await fcode.datastore.get("key");
await fcode.datastore.del("key");
// Encrypted at rest with a key owned by the workspace — for tokens, credentials,
// personal data. The third argument must be a boolean; get() is transparent.
// Keys (entry names) are never encrypted.
await fcode.datastore.set("oauth.token", accessToken, true);
const token = await fcode.datastore.get("oauth.token");
// Storage (files)
const fs = require("node:fs");
const path = require("node:path");
const localPath = path.join(process.env.TMP_DATA_DIR, "localfile.txt");
await fcode.storage.upload("path/myfile.txt", fs.createReadStream(localPath));
const files = await fcode.storage.list();
const stream = await fcode.storage.download("path/myfile.txt");
stream.pipe(fs.createWriteStream(localPath));
// Form file params arrive as "fcode.storage://…" references — strip the
// prefix before download; see fcode-forms.
// Signed download URL — { url, expiresAt }. A real HTTPS link in the cloud,
// a file:// URL locally (same shape, no special-casing).
const signed = await fcode.storage.createSignedUrl("path/myfile.txt");
await fcode.storage.delete("path/myfile.txt");process.env.TMP_DATA_DIR// Team variables (config/secrets)
// Default is SENSITIVE: fcode.variables.set(key, value) creates a sensitive
// (masked, immutable-sensitivity) variable. Pass { sensitive: false } for
// plain config values.
await fcode.variables.set("API_KEY", "secret"); // sensitive by default
await fcode.variables.set("BASE_URL", "https://api.acme.com", {
sensitive: false, // required for non-secret config
});
const v = await fcode.variables.get("API_KEY"); // { key, value, resolvingTeamSlug, ... } or undefined
const all = await fcode.variables.list(); // includes variables inherited from parents
await fcode.variables.delete("API_KEY"); // no-op on an inherited variable
// Schedules (cron or one-off dateTime) for a process
const schedule = await fcode.schedule.create("my-process", {
cron: "0 0 6 * * SUN", // or: dateTime: "2026-04-24T12:30:00.000"
input: { parameters: { foo: "bar" } },
allowConcurrentExecutions: false, // optional
});
const schedules = await fcode.schedule.list({
processId: fcode.execution.process.id,
});
const current = await fcode.schedule.get(schedule.id);
await fcode.schedule.update(schedule.id, { cron: "0 0 7 * * SUN" });
await fcode.schedule.pause(schedule.id);
await fcode.schedule.resume(schedule.id);
await fcode.schedule.delete(schedule.id);
// delete every schedule for a process (pass the process UUID)
await fcode.schedule.deleteForProcess(fcode.execution.process.id);
// Start a third-party OAuth authorization. The platform holds the state, the PKCE
// verifier and the one redirect_uri registered with the provider, and invokes
// `onComplete` when the provider redirects back — so never build an authorization
// URL or a state by hand, and never expose a callback webhook.
const flow = await fcode.oauth.start({
authorizeUrl: "https://login.example.com/authorize",
clientId: fcode.env.PROVIDER_CLIENT_ID,
scope: ["openid", "offline_access"],
onComplete: "oauth-callback", // the process that receives the code
data: { companyId }, // carried back untouched; never a secret
extraParams: { nonce }, // optional, provider-specific
pkce: true, // default
});
flow.authorizationUrl; // hand this to the form's oauth widgetonCompletecodecodeVerifierredirectUridatastatefcode.context.parameterserrorerrorDescriptionredirectUrifcode-examplesreferences/oauth-connect.mdfcode.variables.set/deletefcode.envfcode.envlist()get()fcode-core-conceptsresolvingTeamSlugset()delete()resolvingTeamSlugfcode.env.setEnvVardelEnvVarfcode.sendMailfcode-core-conceptsconst info = await fcode.sendMail({
to: "user@example.com", // string or string[]
subject: "Report ready",
text: "Plain-text body", // provide text, html, or both
html: "<b>HTML body</b>",
});
// info => { messageId, accepted, rejected }Fromfromfcode runfcode-core-concepts// Standard
return { message: "Success!" };
// Custom HTTP status (webhooks)
return { status: 404, body: { message: "Not found" }, headers: { "Content-Type": "application/json" } };
// Transient (not persisted in execution results)
return { transient: true, data: sensitiveData };
// Synchronous UI trigger button inside Factorial (see fcode-ui-triggers).
// Returned unchanged to the page; signal a failure with an error, not in the body.
return { synced: 42 };fcode-core-concepts