Guest-side SDK for building FastEdge wizard forms that embed inside the Gcore FastEdge portal UI.
A wizard is a small web app (any framework, or plain HTML/JS) that the portal loads in a hardened iframe. The wizard never holds a Gcore API credential — instead it talks to the portal over a capability-mediated postMessage bridge, and the portal performs Gcore API calls on its behalf.
Published on npm (public):
npm install @gcoredev/fastedge-wizard-sdkOr in package.json:
"dependencies": {
"@gcoredev/fastedge-wizard-sdk": "latest"
}import { connect } from '@gcoredev/fastedge-wizard-sdk';
const session = await connect({
// Must exactly match the origin of the Gcore portal that hosts your wizard.
expectedHostOrigin: 'https://portal.gcore.com',
});
const ctx = await session.context.get();
console.log(ctx.theme, ctx.locale);
const templates = await session.fastedge.templates.list();See docs/quickstart.md for a full end-to-end example and local dev setup.
Performs the handshake with the portal host and returns a live session.
| Option | Type | Required | Description |
|---|---|---|---|
expectedHostOrigin |
string |
Yes | Exact origin of the portal (https://…). The SDK rejects INIT from any other origin. |
handshakeTimeoutMs |
number |
No | Override the default 10 s handshake timeout. |
Throws WizardError with code timeout if the portal doesn't complete the handshake in time, or protocol_error on a version mismatch.
The full, always-current surface is the WizardSession interface in src/sdk.ts (the method tree) and the param/result types in src/types.ts. Both are re-exported from the package, so your editor shows every signature and its doc comment the moment you import. Those files are the canonical contract — the map below is orientation, not an exhaustive signature list.
| Namespace | Purpose |
|---|---|
session.context |
Locale, theme, the wizard's own app ID, managed app IDs, feature flags |
session.fastedge.templates |
List / read FastEdge templates |
session.fastedge.apps |
List / get / create / update / link apps |
session.fastedge.secrets |
Pick-or-create secrets, generate ES256 keypairs |
session.fastedge.stores |
Pick-or-create Edge Storage (KV) instances |
session.cdn.resources |
List / pick CDN resources |
session.cdn.origins |
List / create CDN origin groups |
session.cdn.rules |
List / create CDN rules |
session.deployment |
Plan-then-apply — prefer deploy() |
Behaviours the types don't spell out:
- Consent-gated writes —
apps.create/apps.update/apps.link,cdn.origins.create, andcdn.rules.createopen a portal consent dialog; a user cancel throwsWizardErrorwith codeuser_cancelled. Pickers (secrets.pickOrCreate,stores.pickOrCreate,cdn.resources.pick) are consent points too. - Refs only, never plaintext — secrets and Edge Storage instances cross the bridge as
{ id, name }refs, both with an optionaloriginof'picked'|'created'; the guest never sees a secret value or enumerates the account. - Deployment scope —
plan/deploycreate apps, CDN origins, and CDN rules, not secrets or stores. Create those eagerly withsecrets.pickOrCreate/secrets.generateKeypair/stores.pickOrCreateand reference them by id.deployplans, applies, streamsdeployment.progress, and tears the listener down afterwards (even if apply rejects) — prefer it overplan+apply.
Subscribe to host-pushed events. Returns an unsubscribe function.
const off = session.on('deployment.progress', ({ step, total, describe }) => {
console.log(`[${step}/${total}] ${describe}`);
});
// later:
off();Closes the MessageChannel port and rejects all pending intents. Call this when the wizard unmounts.
All bridge errors are thrown as WizardError, which extends Error and adds a typed .code field.
| Code | Meaning |
|---|---|
denied |
Intent not in the catalog or host refused it |
out_of_scope |
Resource is outside the wizard's managed scope |
invalid_params |
Request params failed host-side validation |
user_cancelled |
User dismissed a consent or picker dialog |
unauthorized |
Session token expired |
not_found |
Requested resource doesn't exist |
conflict |
Duplicate name or conflicting state |
upstream_error |
Gcore API returned an error |
rate_limited |
Exceeded 20 intents per 10 s |
timeout |
Intent or handshake took longer than allowed |
protocol_error |
Message version mismatch or session disposed |
import { WizardError } from '@gcoredev/fastedge-wizard-sdk';
try {
await session.fastedge.apps.create(params);
} catch (err) {
if (err instanceof WizardError && err.code === 'user_cancelled') {
// user clicked cancel in the portal consent dialog — not a real error
}
}- Max 20 intents per 10 s sliding window (host-enforced;
rate_limitedon breach). - Max 8 in-flight intents at a time.
- Messages larger than 64 KB are silently dropped by the host (the client-side timeout fires after ~90 s).
- The bridge rejects
INITfrom any origin other thanexpectedHostOrigin.
Worked examples live in the sibling fastedge-wizard-apps repo under wizards/:
| Wizard | What it shows |
|---|---|
_example/ |
Minimal framework-agnostic wizard: handshake, context.get, templates.list |
_example-intents/ |
Step-by-step exercise of the full intent surface (apps.*, secrets.*, stores.*, cdn.*, deployment.*) |
edge-totp/ |
Canonical real wizard — two apps + CDN wiring, eager secrets/stores, deployment.deploy |
For local dev (mock host, fixtures) see docs/quickstart.md.