Aller au contenu principal

Introduction

Le SDK @cloudforge/sdk est le client officiel TypeScript pour CloudForge. Il couvre l'intégralité de l'API REST et fournit des helpers typés pour l'authentification, les projets, les déploiements, l'IA, les domaines et la gestion des tokens CLI.

TypeScript natif

Strict types

Edge-compatible

Web Crypto

Auto refresh

Rotation 30j

MFA TOTP

RFC 6238

Installation

# npm
npm install @cloudforge/sdk

# pnpm
pnpm add @cloudforge/sdk

# yarn
yarn add @cloudforge/sdk

Démarrage rapide

Authentification par Personal Access Token (recommandé pour scripts, CI/CD, backend) :

import { CloudForge } from '@cloudforge/sdk';

const cf = new CloudForge({
  baseUrl: 'https://cloudforge-ai.pages.dev',
  apiToken: process.env.CLOUDFORGE_TOKEN!, // cfp_xxx
});

// Lister les projets
const { projects } = await cf.projects.list({ limit: 10 });

// Créer un projet
const project = await cf.projects.create({
  name: 'Mon API',
  type: 'api',
  framework: 'express',
});

// Déclencher un déploiement
const deploy = await cf.deploy.trigger({ projectId: project.id });
console.log('Deployment ID:', deploy.deploymentId);

Authentification

Pour les flux interactifs (scripts E2E, tests) — login/mot de passe avec cookies HttpOnly :

const cf = new CloudForge({ baseUrl: 'https://cloudforge-ai.pages.dev' });

await cf.auth.login({
  email: 'user@example.com',
  password: 'secret',
});

// Le token est automatiquement stocké dans le client
// Le refresh token est géré automatiquement
const me = await cf.me();
console.log(`Connecté en tant que ${me?.email}`);

Authentification MFA TOTP

Si MFA est activé sur le compte, la première invocation de login() sans code TOTP lève une erreur avec code = 'MFA_REQUIRED'.

try {
  await cf.auth.login({ email, password });
} catch (e: any) {
  if (e.code === 'MFA_REQUIRED') {
    const code = await promptUser('Code TOTP:');
    await cf.auth.login({ email, password, mfaCode: code });
  }
}

// Activer le MFA sur un compte existant
const setup = await cf.auth.mfaSetup();
console.log('Scannez ce QR:', setup.otpauth);

const result = await cf.auth.mfaVerify(userCode);
console.log('Backup codes:', result.backupCodes);

Refresh tokens automatiques

Le SDK gère automatiquement le cycle de vie des tokens. Si une requête renvoie 401 (token expiré), le SDK appelle /api/auth/refresh en arrière-plan et rejoue la requête originale.

const cf = new CloudForge({
  baseUrl,
  token: accessToken,
  refreshToken,
  onTokensRefreshed: ({ token, refreshToken }) => {
    // Persister les nouveaux tokens
    saveToKeychain({ token, refreshToken });
  },
});
Sécurité : la rotation des refresh tokens détecte automatiquement toute tentative de réutilisation. Si un token déjà rotaté est présenté, tous les tokens de l'utilisateur sont révoqués immédiatement.

Projets, fichiers, versions

// CRUD projets
const project = await cf.projects.create({ name: 'API', type: 'api' });
const detail = await cf.projects.get(project.id);
await cf.projects.update(project.id, { description: '...' });
await cf.projects.delete(project.id);

// Fichiers
await cf.projects.upsertFile(project.id, {
  path: '/src/index.ts',
  content: 'console.log("hello")',
  language: 'typescript',
});

// Versions (snapshots)
await cf.projects.saveVersion(project.id, 'v1.0', 'Initial release');
await cf.projects.restoreVersion(project.id, versionId);

Déploiement

const trigger = await cf.deploy.trigger({ projectId });

// Polling du statut
while (true) {
  const { deployment } = await cf.deploy.get(trigger.deploymentId);
  if (deployment.status === 'live') {
    console.log('URL:', deployment.url);
    break;
  }
  if (deployment.status === 'failed') throw new Error('deploy failed');
  await new Promise(r => setTimeout(r, 3000));
}

Gestion d'erreurs

import { CloudForgeError, isCloudForgeError } from '@cloudforge/sdk';

try {
  await cf.projects.get('invalid-id');
} catch (e) {
  if (isCloudForgeError(e)) {
    console.error('Status:', e.status);   // 404
    console.error('Code:', e.code);       // 'PROJECT_NOT_FOUND'
    console.error('Message:', e.message); // 'Projet introuvable'
  }
}
401UNAUTHORIZED

Token manquant ou invalide

200MFA_REQUIRED

MFA activé, code TOTP requis

401MFA_INVALID

Code TOTP ou backup code invalide

429RATE_LIMITED

Limite de débit dépassée

409DOMAIN_UNAVAILABLE

Domaine déjà enregistré