Zum Inhalt springen
Farbschema wählenSprache wählen

Ein Skript schreiben und ausführen

Ein Skript ist ein benanntes Stück Quellcode in deinem Workspace – eine Datei, eine Sprache, ein Slug – im Browser geschrieben und überall wiederverwendbar, wo SupaCloud genau diese Logik braucht. Skripte findest du unter Build → Skripte.

Ein Skript läuft nicht in einem Container. Es läuft in einem festen, vorgebauten Interpreterboa für JavaScript und TypeScript, CPython für Python – innerhalb einer WebAssembly-Sandbox (WASI 0.2). Dein Quellcode wird diesem Interpreter als Daten übergeben: nichts wird kompiliert, keine Pakete werden installiert, kein Image wird geladen. Genau das macht ein Skript billig im Start und sicher im unbeaufsichtigten Betrieb: standardmäßig hat es kein Dateisystem, keine Shell, keine Datenbank und überhaupt kein Netzwerk. Netzwerkzugriff ist etwas, das du gewährst – Host für Host und nie versehentlich.

Der Tab „Skripte“ im Build-Hub, mit Sprache und letzter Revision je Skript.Der Tab „Skripte“ im Build-Hub, mit Sprache und letzter Revision je Skript.
  1. Öffne Build → Skripte und wähle + Neues Skript.

  2. Fülle die Kopffelder aus:

    • Name – die menschenlesbare Bezeichnung, bis zu 200 Zeichen.
    • Slug – wird automatisch aus dem Namen abgeleitet, solange du ihn nicht angefasst hast. Nur Kleinbuchstaben, Ziffern und Bindestriche, 1–63 Zeichen, und er darf nicht mit einem Bindestrich beginnen. Das ist die stabile Adresse, die alles andere verwendet – wähle sie also bewusst; sie muss im Workspace eindeutig sein.
    • Sprache – TypeScript, JavaScript oder Python. Ein Sprachwechsel bei noch leerem Editor tauscht den Starter-Schnipsel aus.
    • Beschreibung – optional, wird im Board angezeigt.
  3. Schreibe den Rumpf im Editor Quellcode. Ein Skript ist eine einzige Datei, deshalb zeigt der Editor keinen Dateibaum – nur den Code und einen Zeilenzähler.

  4. Wähle Skript erstellen. Du landest im Vollbild-Editor, rechts das Ausführungs-Panel und im Kopf die Reiter Bearbeiten / Versionen.

Der Starter-Schnipsel, den der Editor vorbelegt, ist für eine Workflow-Code-Node geformt – eine exportierte handler-Funktion oder Python, das von der Standardeingabe liest. Ein direkter Skriptlauf ruft das nie auf. Das Substrat wertet deinen Quellcode von oben nach unten aus und nimmt den Wert des letzten Ausdrucks als Ergebnis. Ersetze den Starter also vor dem ersten Lauf.

Die Regeln sind in jeder Sprache dieselben:

  • Was du als Eingabe übergibst, kommt als globale input an (sie ist null, wenn du nichts sendest).
  • Das Ergebnis ist der Wert des letzten Ausdrucks. In Python wird, falls die letzte Anweisung auf oberster Ebene kein Ausdruck ist, stattdessen eine Variable result auf oberster Ebene verwendet – setzt du keines von beidem, ist das Ergebnis leer.
  • Das Ergebnis muss JSON-serialisierbar sein. Python weist eine Koroutine oder einen Generator mit einer klaren Meldung zurück, weil Skripte synchron laufen.
// input ist das übergebene JSON; der letzte Ausdruck ist das Ergebnis.
const names = (input as { names?: string[] })?.names ?? [];
({
count: names.length,
upper: names.map((n) => n.toUpperCase()),
});

TypeScript wird vor der Auswertung von seinen Typen befreit – Typen werden also entfernt, nicht geprüft. Ein Typfehler ist damit kein Laufzeitfehler, ein echter Laufzeitfehler schon.

Ein Skript startet mit leerer Egress-Allowlist, und eine leere Allowlist bedeutet: jede ausgehende Anfrage wird abgewiesen. Du öffnest eine Lücke, indem du im Quellcode selbst deklarierst, welche Workspace-Ressource das Skript braucht:

// resource: billing_api

Python darf beide Kommentarformen verwenden – # resource: billing_api funktioniert genauso. Der Marker muss der ganze Kommentar sein; eine angehängte //-Notiz nach dem Namen wird abgeschnitten, und wiederholte Namen werden zusammengefasst.

Beim Start schlägt der Server jeden deklarierten Namen unter den Ressourcen deines Workspace nach, entschlüsselt dessen Secret und leitet daraus die Autoritäten ab, die diese Ressource freischaltet:

  • Eine Ressource, deren Konfiguration ein base_url, url oder endpoint trägt, schaltet genau dieses Schema, diesen Host und diesen Port frei – eine https://-Ressource lässt sich also nicht auf Klartext gegen denselben Host herabstufen.
  • Eine Ressource mit host (und optional port) schaltet diesen Host und Port frei.

Mehr ist nicht erreichbar. Jede Anfrage wird zusätzlich gegen den SSRF-Klassifizierer geprüft – private, Loopback-, Link-Local- und Cloud-Metadaten-Adressen sind gesperrt – und die Adresse wird nach dieser Prüfung festgenagelt, sodass eine DNS-Antwort sich zwischen Prüfung und Verbindung nicht mehr ändern kann.

Im Skript ist Egress ein expliziter Aufruf, keine allgegenwärtige Fähigkeit:

Sprache Anfrage stellen Gebundene Ressource lesen
JavaScript / TypeScript scHttp.request(method, url, { headers, body }) oder der fetch-Ersatz über denselben Weg scResource(name)
Python sc_http sc_resource
  1. Nutze im Vollbild-Editor das Panel Skript ausführen auf der rechten Seite.

  2. Trage ein JSON-Objekt in Eingabe (JSON) ein – daraus wird die globale input. Lass {} stehen, wenn das Skript nichts erwartet. Ungültiges JSON wird abgewiesen, bevor überhaupt etwas gestartet wird.

  3. Wähle Ausführen. Der Start kehrt sofort mit einer Lauf-Id zurück und das Panel beginnt zu pollen; das Skript selbst läuft im Hintergrund zu Ende.

  4. Beobachte Letzte Läufe. Jede Zeile zeigt Status und Zeitpunkt und führt zur vollständigen Lauf-Detailansicht. Ein gescheiterter Lauf trägt den Grund direkt in der Zeile.

Die Eingabe wird direkt an den Interpreter übergeben und nie gespeichert – am Lauf festgehalten werden nur die Tatsache, dass eine Eingabe vorlag, sowie die Namen der vom Skript deklarierten Ressourcen. Damit kannst du gefahrlos ein Einmal-Token oder eine Kundenkennung übergeben, ohne dass es im Laufverlauf landet.

Das Editor-Panel ist nur der nächstliegende Weg. Dasselbe Skript lässt sich von vier weiteren Stellen aus starten, und jede hat ihren eigenen Grund.

Füge eine code-Node hinzu, stelle ihren Modus auf Script und wähle das Skript aus der Workspace-Liste. Die Engine lädt Quellcode und Sprache dieses Skripts in die Node, bevor sie läuft.

So bekommst du ein Skript auf einen Zeitplan: Ein Zeitplan kann kein Skript direkt ansprechen, aber ein Workflow kann einen Schedule-Trigger tragen, und seine Code-Node kann das Skript referenzieren. Siehe Deinen ersten Workflow erstellen und Einen Zeitplan einrichten.

Denk an den Substrat-Unterschied aus dem Hinweis am Seitenanfang: Eine Code-Node ohne Ressourcen-Bindungen führt dein Skript in einem Docker-Container ohne Netzwerk aus – dort existiert scHttp nicht.

Jedes Speichern, das den Quellcode ändert, sichert die vorherige Fassung als Version. Der Editor zeigt also immer den aktuellen Code, und der Verlauf hält alles davor. Öffne den Reiter Versionen, um sie neueste zuerst aufzulisten, den Quellcode einer Fassung anzusehen oder eine Fassung gegen den aktuellen Stand zu diffen. Versionen, die von Repo-Sync oder einem anderen Systemweg geschrieben wurden, tragen keinen Autor. Wird ein Skript gelöscht, verschwindet sein Verlauf mit ihm.

Das Löschen ist außerdem blockiert, solange eine Workflow-Code-Node das Skript noch referenziert – die Fehlermeldung nennt die Workflows, damit du sie zuerst lösen kannst.

Schranke Wert
Laufzeitbudget pro Lauf 30 Sekunden, fest – nicht pro Skript einstellbar
Speicher pro Lauf 128 MiB, harte Obergrenze 256 MiB
Quellcode-Größe 1 MiB, und er darf nicht leer sein
Sprache, Eingabe und Quellcode zusammen 8 MiB pro Start
Name 200 Zeichen
Slug 1–63 Zeichen, Kleinbuchstaben, Ziffern und Bindestriche

Für den Rückgabewert eines Skripts gibt es keine eigene Schranke; er ist durch den Speicher pro Lauf begrenzt. Ein Lauf, der sein Budget überschreitet, endet als failed und wird als abgelaufen markiert.