Migration Guide

This guide helps you migrate from previous versions of the Asterisms JS SDK to the latest version, covering breaking changes, deprecated features, and migration strategies.

Migration Overview

Version History

  • v3.x → v4.x: Major API restructuring, new authentication system
  • v2.x → v3.x: Resource-based architecture, TypeScript rewrite
  • v1.x → v2.x: Event system improvements, configuration changes

Migration Path

graph LR
    A[v1.x] --> B[v2.x]
    B --> C[v3.x]
    C --> D[v4.x Latest]

    A --> E[Direct Migration to v4.x]

    style D fill:#4CAF50
    style E fill:#FF9800

Migrating from v3.x to v4.x

Breaking Changes

1. SDK Initialization

Before (v3.x):

import { AsterismsSDK } from '@asterisms/sdk';

const sdk = new AsterismsSDK({
  appId: 'your-app-id',
  domain: 'yourapp.com',
  router: yourRouter
});

After (v4.x):

import { createAsterismsSDK } from '@asterisms/sdk';

const sdk = createAsterismsSDK({
  bundleId: 'com.yourcompany.yourapp', // Changed from appId
  rootDomain: 'yourapp.com', // Changed from domain
  navigationAdapter: yourNavigationAdapter // Changed from router
});

2. Authentication Provider Registration

Before (v3.x):

sdk.registerAuthProvider('srp6', {
  authenticate: async (credentials) => {
    /* ... */
  }
});

After (v4.x):

import { SRP6AuthProvider } from '@asterisms/auth-provider-srp6';

sdk.auth.registerProvider(
  'srp6',
  new SRP6AuthProvider({
    serviceUrl: 'https://auth.yourapp.com'
  })
);

3. Resource Access

Before (v3.x):

// Direct method calls
await sdk.uploadFile(file);
await sdk.createFolder(name);
await sdk.shareItem(itemId, users);

After (v4.x):

// Resource-based access
await sdk.storage.upload(file);
await sdk.drive.createFolder({ name });
await sdk.drive.share(itemId, { users });

4. Event Subscription

Before (v3.x):

sdk.on('auth:login', (user) => {
  console.log('User logged in:', user);
});

sdk.on('upload:progress', (progress) => {
  console.log('Upload progress:', progress);
});

After (v4.x):

sdk.auth.onAuthStateChanged((state) => {
  if (state.isAuthenticated) {
    console.log('User logged in:', state.user);
  }
});

sdk.storage.onUploadProgress((progress) => {
  console.log('Upload progress:', progress);
});

Migration Steps

Step 1: Update Dependencies

# Remove old packages
npm uninstall @asterisms/sdk@^3.0.0

# Install new packages
npm install @asterisms/sdk@^4.0.0 @asterisms/auth-provider-srp6

Step 2: Update Imports

Create a migration script to update imports:

// migration/update-imports.ts
import { readFileSync, writeFileSync } from 'fs';
import { glob } from 'glob';

const files = glob.sync('src/**/*.{ts,tsx}');

files.forEach((file) => {
  let content = readFileSync(file, 'utf8');

  // Update imports
  content = content.replace(
    /import\s+{\s*AsterismsSDK\s*}\s+from\s+['"]@asterisms\/sdk['"]/g,
    "import { createAsterismsSDK } from '@asterisms/sdk'"
  );

  // Update initialization
  content = content.replace(/new AsterismsSDK\(/g, 'createAsterismsSDK(');

  writeFileSync(file, content);
});

Step 3: Update Configuration

// config/sdk-config.ts
export function createSDKConfig() {
  return {
    // v3.x config
    // appId: 'your-app-id',
    // domain: 'yourapp.com',
    // router: yourRouter,

    // v4.x config
    bundleId: 'com.yourcompany.yourapp',
    rootDomain: 'yourapp.com',
    navigationAdapter: {
      navigate: (url) => yourRouter.push(url),
      getCurrentPath: () => yourRouter.currentRoute.path
    },

    // New configuration options
    environment: 'production',
    logLevel: 'info',
    resources: {
      storage: {
        maxFileSize: 100 * 1024 * 1024
      }
    }
  };
}

Step 4: Update Authentication

// services/auth.ts - Before
class AuthService {
  constructor(private sdk: AsterismsSDK) {}

  async login(credentials: any) {
    return await this.sdk.authenticate('srp6', credentials);
  }
}

// services/auth.ts - After
import { SRP6AuthProvider } from '@asterisms/auth-provider-srp6';

class AuthService {
  constructor(private sdk: any) {
    // Register provider during initialization
    this.sdk.auth.registerProvider(
      'srp6',
      new SRP6AuthProvider({
        serviceUrl: 'https://auth.yourapp.com'
      })
    );
  }

  async login(credentials: any) {
    return await this.sdk.auth.login({
      provider: 'srp6',
      credentials
    });
  }
}

Step 5: Update Resource Operations

// services/file-service.ts - Before
class FileService {
  constructor(private sdk: AsterismsSDK) {}

  async uploadFile(file: File) {
    return await this.sdk.uploadFile(file);
  }

  async createFolder(name: string, parent?: string) {
    return await this.sdk.createFolder(name, parent);
  }

  async shareItem(itemId: string, users: string[]) {
    return await this.sdk.shareItem(itemId, users);
  }
}

// services/file-service.ts - After
class FileService {
  constructor(private sdk: any) {}

  async uploadFile(file: File) {
    return await this.sdk.storage.upload(file);
  }

  async createFolder(name: string, parent?: string) {
    return await this.sdk.drive.createFolder({
      name,
      parent: parent || 'root'
    });
  }

  async shareItem(itemId: string, users: string[]) {
    return await this.sdk.drive.share(itemId, {
      users,
      permission: 'read'
    });
  }
}

Step 6: Update Event Handling

// hooks/useAuth.ts - Before
function useAuth() {
  const [user, setUser] = useState(null);

  useEffect(() => {
    const handleLogin = (user: any) => setUser(user);
    const handleLogout = () => setUser(null);

    sdk.on('auth:login', handleLogin);
    sdk.on('auth:logout', handleLogout);

    return () => {
      sdk.off('auth:login', handleLogin);
      sdk.off('auth:logout', handleLogout);
    };
  }, []);

  return { user };
}

// hooks/useAuth.ts - After
function useAuth() {
  const [authState, setAuthState] = useState({
    isAuthenticated: false,
    user: null
  });

  useEffect(() => {
    const unsubscribe = sdk.auth.onAuthStateChanged((state) => {
      setAuthState(state);
    });

    return unsubscribe; // Simpler cleanup
  }, []);

  return authState;
}

Migrating from v2.x to v4.x

Major Changes

  1. Complete API Redesign: Resource-based architecture
  2. TypeScript First: Full TypeScript support
  3. New Authentication System: Provider-based authentication
  4. Enhanced Error Handling: Structured error hierarchy
  5. Real-time Events: Improved event system

Migration Strategy

Option 1: Gradual Migration

// Create adapter layer for gradual migration
class V2ToV4Adapter {
  constructor(private v4SDK: any) {}

  // V2 API compatibility
  async uploadFile(file: File) {
    return await this.v4SDK.storage.upload(file);
  }

  async authenticate(provider: string, credentials: any) {
    return await this.v4SDK.auth.login({ provider, credentials });
  }

  on(event: string, callback: Function) {
    // Map v2 events to v4 events
    switch (event) {
      case 'auth:login':
        return this.v4SDK.auth.onAuthStateChanged((state: any) => {
          if (state.isAuthenticated) {
            callback(state.user);
          }
        });
      // Add more event mappings
    }
  }
}

// Usage
const v4SDK = createAsterismsSDK(config);
const sdk = new V2ToV4Adapter(v4SDK);

Option 2: Complete Rewrite

// Identify all v2 usage patterns
const v2Patterns = [
  'sdk.uploadFile',
  'sdk.authenticate',
  'sdk.on(',
  'sdk.createFolder',
  'sdk.shareItem'
];

// Create mapping to v4 equivalents
const v4Mappings = {
  uploadFile: 'storage.upload',
  authenticate: 'auth.login',
  createFolder: 'drive.createFolder',
  shareItem: 'drive.share'
};

Migrating from v1.x to v4.x

Complete Overhaul Required

V1.x to v4.x migration requires a complete rewrite due to fundamental architectural changes.

Assessment Checklist

  • Inventory all SDK usage in your application
  • Identify custom authentication implementations
  • Map file operations to new resource APIs
  • Update event handling patterns
  • Review configuration requirements
  • Update test suites

Migration Plan

  1. Phase 1: Set up v4.x in parallel
  2. Phase 2: Migrate authentication first
  3. Phase 3: Migrate core features one by one
  4. Phase 4: Update event handling
  5. Phase 5: Remove v1.x dependencies

Framework-Specific Migration

React Migration

// Before - v3.x React integration
import { AsterismsSDK } from '@asterisms/sdk';

const sdk = new AsterismsSDK(config);

function App() {
  const [user, setUser] = useState(null);

  useEffect(() => {
    sdk.on('auth:change', setUser);
    return () => sdk.off('auth:change', setUser);
  }, []);
}

// After - v4.x React integration
import { createAsterismsSDK } from '@asterisms/sdk';

const sdk = createAsterismsSDK(config);

function App() {
  const [authState, setAuthState] = useState({
    isAuthenticated: false,
    user: null
  });

  useEffect(() => {
    const unsubscribe = sdk.auth.onAuthStateChanged(setAuthState);
    return unsubscribe;
  }, []);
}

SvelteKit Migration

// Before - v3.x SvelteKit integration
// stores/auth.ts
import { writable } from 'svelte/store';
import { sdk } from '../lib/sdk';

export const user = writable(null);

sdk.on('auth:login', (userData) => user.set(userData));
sdk.on('auth:logout', () => user.set(null));

// After - v4.x SvelteKit integration
// stores/auth.ts
import { writable } from 'svelte/store';
import { sdk } from '../lib/sdk';

export const authState = writable({
  isAuthenticated: false,
  user: null
});

sdk.auth.onAuthStateChanged((state) => {
  authState.set(state);
});

Configuration Migration

Environment Configuration

// v3.x configuration
const config = {
  appId: 'your-app',
  domain: 'yourapp.com',
  apiUrl: 'https://api.yourapp.com',
  authUrl: 'https://auth.yourapp.com',
  debug: true
};

// v4.x configuration
const config = {
  bundleId: 'com.yourcompany.yourapp',
  rootDomain: 'yourapp.com',

  endpoints: {
    api: 'https://api.yourapp.com',
    auth: 'https://auth.yourapp.com'
  },

  logLevel: 'debug',
  environment: 'development',

  resources: {
    storage: {
      maxFileSize: 100 * 1024 * 1024,
      allowedTypes: ['image/*', 'application/pdf']
    }
  }
};

Testing Migration

Update Test Mocks

// Before - v3.x mocks
const mockSDK = {
  uploadFile: jest.fn(),
  authenticate: jest.fn(),
  on: jest.fn(),
  off: jest.fn()
};

// After - v4.x mocks
const mockSDK = {
  auth: {
    login: jest.fn(),
    logout: jest.fn(),
    onAuthStateChanged: jest.fn()
  },
  storage: {
    upload: jest.fn(),
    onUploadProgress: jest.fn()
  },
  drive: {
    createFolder: jest.fn(),
    share: jest.fn()
  }
};

Migration Tools

Automated Migration Script

// migration/migrate-to-v4.ts
import { execSync } from 'child_process';
import { readFileSync, writeFileSync } from 'fs';
import { glob } from 'glob';

class V4Migrator {
  async migrate() {
    console.log('Starting migration to v4.x...');

    await this.updateDependencies();
    await this.updateImports();
    await this.updateInitialization();
    await this.updateResourceCalls();
    await this.updateEventHandling();

    console.log('Migration complete! Please review changes and test thoroughly.');
  }

  private async updateDependencies() {
    console.log('Updating dependencies...');
    execSync('npm uninstall @asterisms/sdk@^3.0.0');
    execSync('npm install @asterisms/sdk@^4.0.0 @asterisms/auth-provider-srp6');
  }

  private async updateImports() {
    console.log('Updating imports...');
    const files = glob.sync('src/**/*.{ts,tsx,js,jsx}');

    files.forEach((file) => {
      let content = readFileSync(file, 'utf8');

      // Update SDK import
      content = content.replace(
        /import\s+{\s*AsterismsSDK\s*}\s+from\s+['"]@asterisms\/sdk['"]/g,
        "import { createAsterismsSDK } from '@asterisms/sdk'"
      );

      writeFileSync(file, content);
    });
  }

  // Add more migration methods...
}

// Run migration
new V4Migrator().migrate();

Validation Script

// migration/validate-migration.ts
class MigrationValidator {
  validate() {
    const issues = [];

    // Check for remaining v3.x patterns
    const v3Patterns = [
      'new AsterismsSDK(',
      'sdk.uploadFile(',
      'sdk.authenticate(',
      'sdk.on(',
      'sdk.off('
    ];

    const files = glob.sync('src/**/*.{ts,tsx}');

    files.forEach((file) => {
      const content = readFileSync(file, 'utf8');

      v3Patterns.forEach((pattern) => {
        if (content.includes(pattern)) {
          issues.push(`${file}: Found v3.x pattern: ${pattern}`);
        }
      });
    });

    if (issues.length > 0) {
      console.error('Migration issues found:');
      issues.forEach((issue) => console.error(`- ${issue}`));
      process.exit(1);
    } else {
      console.log('✅ Migration validation passed!');
    }
  }
}

new MigrationValidator().validate();

Post-Migration Checklist

  • All dependencies updated
  • SDK initialization updated
  • Authentication flow working
  • File operations working
  • Event subscriptions working
  • Configuration updated
  • Tests updated and passing
  • Error handling updated
  • Performance testing completed
  • Documentation updated

Common Migration Issues

Issue 1: Event Subscription Memory Leaks

Problem: V3.x event unsubscription not working in v4.x

Solution:

// Incorrect
useEffect(() => {
  sdk.auth.onAuthStateChanged(callback);
  // Missing cleanup!
}, []);

// Correct
useEffect(() => {
  const unsubscribe = sdk.auth.onAuthStateChanged(callback);
  return unsubscribe; // Proper cleanup
}, []);

Issue 2: Configuration Conflicts

Problem: V3.x configuration keys not recognized

Solution: Use the configuration mapping tool to update all config keys systematically.

Issue 3: Type Errors

Problem: TypeScript errors after migration

Solution:

// Install type definitions
npm install --save-dev @types/asterisms__sdk

// Update tsconfig.json
{
  "compilerOptions": {
    "types": ["@asterisms/sdk"]
  }
}

Getting Help

Migration Support

  • GitHub Issues: Report migration problems
  • Community Forum: Ask questions and share solutions
  • Documentation: Comprehensive migration guides
  • Migration Tool: Automated migration assistance

Professional Services

For complex migrations or large applications, consider professional migration services that include:

  • Code analysis and migration planning
  • Automated migration tooling
  • Testing and validation
  • Training and support

Next Steps