UNPKG

spaps-sdk

Version:

Sweet Potato Authentication & Payment Service SDK - Zero-config client with built-in permission checking and role-based access control

439 lines (338 loc) 11.2 kB
--- id: spaps-typescript-sdk title: spaps TypeScript SDK category: sdk tags: - sdk - typescript - client ai_summary: | Reference for the spaps TypeScript SDK covering configuration, admin helpers, and examples for interacting with authentication, payments, and permission APIs from JavaScript or TypeScript applications. last_updated: 2025-02-14 --- # @spaps/sdk <a href="https://www.npmjs.com/package/spaps-sdk"><img alt="npm" src="https://img.shields.io/npm/v/spaps-sdk.svg"></a> <img alt="node" src="https://img.shields.io/badge/node-%3E%3D14-brightgreen"> <img alt="types" src="https://img.shields.io/badge/types-TypeScript-blue"> > Sweet Potato Authentication & Payment Service SDK Zero-config client for SPAPS authentication, payments, and permission checking. Works automatically with local development mode. ## 🔐 New in v1.1.0: Admin API Methods! Built-in admin API methods for Stripe product management: ```typescript import { SPAPSClient } from 'spaps-sdk'; const spaps = new SPAPSClient({ apiKey: 'your-api-key', apiUrl: 'https://api.sweetpotato.dev' }); // Authenticate as admin await spaps.signIn('admin@example.com', 'password'); // Admin API methods await spaps.admin.createProduct({ name: 'Premium Plan', category: 'subscription', description: 'Advanced features' }); await spaps.admin.updateProduct('prod_123', { name: 'Premium Plan Pro' }); await spaps.admin.createPrice({ product_id: 'prod_123', unit_amount: 2999, currency: 'usd', interval: 'month' }); // Super admin operations await spaps.admin.syncProducts(); ``` ## 🔐 Permission Utilities Built-in permission checking and role-based access control: ```typescript import { isAdminAccount, canAccessAdmin, getUserRole } from 'spaps-sdk'; // Check admin status const isAdmin = isAdminAccount('buildooor@gmail.com'); // true // Check admin access with detailed result const adminCheck = canAccessAdmin(user); if (adminCheck.allowed) { // Show admin UI } // Get user role const role = getUserRole('user@example.com'); // 'user' | 'admin' | 'guest' // Check if authenticated user is admin if (spaps.isAdmin(currentUser)) { // Show admin features } ``` See [PERMISSIONS.md](./PERMISSIONS.md) for React examples and complete documentation. ## Installation ```bash npm install spaps-sdk # or yarn add spaps-sdk # or pnpm add spaps-sdk ``` ### Compatibility - ✅ **Node.js**: Fully supported (v14+) with automatic fetch polyfill - ✅ **Browser**: Works in all modern browsers - ✅ **TypeScript**: Full type definitions included - ✅ **Next.js**: Server and client components supported - ✅ **React Native**: Compatible with proper setup The SDK automatically includes a `cross-fetch` polyfill for Node.js environments that don't have native fetch support. ## Quick Start ```javascript import { SPAPSClient } from 'spaps-sdk'; // or const { SPAPSClient } = require('spaps-sdk'); // Auto-detects local mode - no API key needed for localhost! const spaps = new SPAPSClient({ apiUrl: 'http://localhost:3300' // Optional, auto-detected }); // Login const { data } = await spaps.login('user@example.com', 'password'); console.log('User:', data.user); // Check authentication if (spaps.isAuthenticated()) { const user = await spaps.getUser(); console.log('Current user:', user.data); } ``` ## Local Mode Explained - If `apiUrl` is omitted or points to `localhost`/`127.0.0.1`, the SDK runs in local mode. - Local mode integrates seamlessly with the `spaps` CLI (`npx spaps local`), defaulting to `http://localhost:3300`. - No API key is required in local mode; tokens and data are managed locally for development. You can check the mode at runtime: ```ts spaps.isLocalMode(); // true | false ``` ## Environment Variables The SDK can read configuration from environment variables (useful in Next.js and Node): - `SPAPS_API_URL` or `NEXT_PUBLIC_SPAPS_API_URL` — API base URL - `SPAPS_API_KEY` — API key for production use Example (Node): ```bash export SPAPS_API_URL=https://api.sweetpotato.dev export SPAPS_API_KEY=spaps_xxx ``` Example (Next.js): ```env NEXT_PUBLIC_SPAPS_API_URL=https://api.sweetpotato.dev ``` ## Features ### 🚀 Zero Configuration - **Auto-detects local mode** - No API key needed for localhost - **Auto-refreshes tokens** - Handles expired tokens automatically - **TypeScript support** - Full type definitions included - **Crypto payments ready** - Create invoices, poll status, verify webhooks, trigger reconciliation ### 🔐 Authentication Methods ```javascript // Email/Password await spaps.login(email, password); await spaps.register(email, password); // Wallet Authentication await spaps.walletSignIn(walletAddress, signature, message, 'solana'); // Token Management await spaps.refresh(); await spaps.logout(); // Get User const user = await spaps.getUser(); ``` ### 💳 Stripe Integration ```javascript // Create checkout session const session = await spaps.createCheckoutSession(priceId, successUrl); window.location.href = session.data.url; // Manage subscription const subscription = await spaps.getSubscription(); await spaps.cancelSubscription(); ``` ### 📊 Usage Tracking ```javascript // Check balance const balance = await spaps.getUsageBalance(); console.log(`Credits: ${balance.data.balance}`); // Record usage await spaps.recordUsage('api-call', 1); ``` ### ✉️ Secure Messaging ```javascript // Create a secure message (content encrypted server-side when pii_enabled) const message = await spaps.secureMessages.create({ patientId: '3d6f0a51-8d77-4b38-8248-2d1b2f1f6c7f', practitionerId: 'a3d7f431-6c9d-4cbc-9f78-4e5b6a7c8d9e', content: 'Patient is experiencing intermittent headaches.', metadata: { urgency: 'high' } }); // List secure messages for the current application const messages = await spaps.secureMessages.list(); console.log(messages[0].content); ``` > Ensure your application has `settings.pii_enabled = true` so payloads are encrypted automatically. ```typescript // Provide a strongly typed metadata shape for downstream usage type SecureMessageMetadata = { urgency: 'low' | 'high'; tags?: string[] }; const spaps = new SPAPSClient<SecureMessageMetadata>({ apiKey: process.env.SPAPS_API_KEY }); await spaps.secureMessages.create({ patientId: '3d6f0a51-8d77-4b38-8248-2d1b2f1f6c7f', practitionerId: 'a3d7f431-6c9d-4cbc-9f78-4e5b6a7c8d9e', content: 'Follow up scheduled for next week.', metadata: { urgency: 'low', tags: ['follow-up'] } }); const typedMessages = await spaps.secureMessages.list(); typedMessages[0].metadata.urgency; // "low" | "high" ``` Need runtime validation too? Reuse the shared schemas that ship with the SDK: ```typescript import { z } from 'zod'; import { createSecureMessageRequestSchema } from 'spaps-sdk'; const secureMessageRequestSchema = createSecureMessageRequestSchema( z.object({ urgency: z.enum(['low', 'high']), tags: z.array(z.string()).optional() }) ); secureMessageRequestSchema.parse({ patientId: '3d6f0a51-8d77-4b38-8248-2d1b2f1f6c7f', practitionerId: 'a3d7f431-6c9d-4cbc-9f78-4e5b6a7c8d9e', content: 'All clear.', metadata: { urgency: 'low' } }); ``` ## Configuration ### Production Mode ```javascript const spaps = new SPAPSClient({ apiUrl: 'https://api.sweetpotato.dev', apiKey: 'spaps_your_api_key_here', timeout: 10000 // Optional timeout in ms }); ``` ### Local Development Mode (Auto-detected) ```javascript const spaps = new SPAPSClient(); // Automatically uses http://localhost:3300 with no API key ``` ### Environment Variables ```bash # .env SPAPS_API_URL=https://api.sweetpotato.dev SPAPS_API_KEY=spaps_your_api_key_here # Next.js NEXT_PUBLIC_SPAPS_API_URL=https://api.sweetpotato.dev ``` ## Helper Methods ```javascript // Check if authenticated spaps.isAuthenticated() // boolean // Get current access token spaps.getAccessToken() // string | undefined // Set access token manually spaps.setAccessToken(token) // Check if in local mode spaps.isLocalMode() // boolean // Health check await spaps.health() ``` ## Types The SDK ships with full TypeScript definitions. For most apps, import types directly from `spaps-sdk`: ```ts import { SPAPSClient, type User, type Session, type Role } from 'spaps-sdk'; ``` For advanced or library use cases, you can also import canonical types from the standalone package: ```ts import type { User, Session, Role, Permission, TokenPayload, } from 'spaps-types'; ``` Notes: - `spaps-sdk` re-exports commonly used types for convenience. - `spaps-types` is useful when building framework integrations, server middleware, or utilities that need to share types without depending on the SDK runtime. ## Import Styles All these work: ```javascript // ES6 Import import { SPAPSClient } from 'spaps-sdk'; import SPAPSClient from 'spaps-sdk'; // CommonJS const { SPAPSClient } = require('spaps-sdk'); const SPAPSClient = require('spaps-sdk'); // Alternative names import { SPAPS } from 'spaps-sdk'; import { SweetPotatoSDK } from 'spaps-sdk'; ``` ## Admin API Methods The SDK includes comprehensive admin methods for Stripe product management: ### Product Management ```typescript // Create product (Admin required) const product = await spaps.admin.createProduct({ name: 'Premium Plan', category: 'subscription', description: 'Advanced features for power users', images: ['https://example.com/product-image.jpg'], metadata: { feature_set: 'premium' }, active: true }); // Update product (Admin required) const updatedProduct = await spaps.admin.updateProduct('prod_123', { name: 'Premium Plan Pro', description: 'Updated features' }); // Archive product (Admin required) await spaps.admin.deleteProduct('prod_123'); // Get products (includes admin metadata if user is admin) const { data } = await spaps.admin.getProducts(); if (data.adminMetadata) { console.log('Total revenue:', data.adminMetadata.total_revenue); } ``` ### Price Management ```typescript // Create price (Admin required) const price = await spaps.admin.createPrice({ product_id: 'prod_123', unit_amount: 2999, // $29.99 currency: 'usd', interval: 'month', interval_count: 1, nickname: 'Monthly Premium' }); ``` ### Super Admin Operations ```typescript // Sync all products from Stripe (Super Admin required) const syncResult = await spaps.admin.syncProducts(); console.log(`Synced ${syncResult.data.synced_count} products`); ``` ### Permission Checking ```typescript // Check if current user can access admin features const user = await spaps.getCurrentUser(); if (spaps.isAdmin(user)) { // Show admin UI components console.log('User has admin privileges'); } else { // Show regular user UI console.log('Regular user'); } ``` ## Error Handling ```javascript try { await spaps.admin.createProduct(productData); } catch (error) { if (error.response?.status === 401) { console.error('Authentication required'); } else if (error.response?.status === 403) { console.error('Admin privileges required'); } else if (error.response?.status === 429) { console.error('Rate limited'); } else { console.error('Error:', error.message); } } ``` ## License MIT