Skip to content

Migration Guide ​

This guide helps you migrate existing applications to use ziegel packages. Whether you're coming from other frameworks or upgrading existing ziegel usage, this guide provides step-by-step instructions.

From Other Frameworks ​

From Lodash to ziegel-core ​

If you're currently using Lodash for utility functions:

Before (Lodash) ​

typescript
import _ from 'lodash';

// String manipulation
const formatted = _.template('Hello, ${name}!')({ name: 'World' });

// Object operations
const cloned = _.cloneDeep(originalObject);
const isEmpty = _.isEmpty(obj);

// Type checking
if (_.isString(value)) {
    // handle string
}

After (ziegel-core) ​

typescript
import {
    StringExtensions,
    ObjectExtensions,
    TypeGuard
} from '@breadstone/ziegel-core';

// String manipulation
const formatted = StringExtensions.format('Hello, {0}!', 'World');

// Object operations
const cloned = ObjectExtensions.deepClone(originalObject);
const isEmpty = ObjectExtensions.isEmpty(obj);

// Type checking
if (TypeGuard.isString(value)) {
    // handle string
}

From Axios to ziegel-platform-http ​

Migrating from Axios HTTP client:

Before (Axios) ​

typescript
import axios from 'axios';

const api = axios.create({
    baseURL: 'https://api.example.com',
    timeout: 5000
});

// Add interceptor
api.interceptors.request.use((config) => {
    config.headers.Authorization = `Bearer ${token}`;
    return config;
});

// Make requests
const users = await api.get<User[]>('/users');
const newUser = await api.post<User>('/users', userData);

After (ziegel-platform-http) ​

typescript
import { HttpClient, HttpInterceptor } from '@breadstone/ziegel-platform-http';

class AuthInterceptor implements HttpInterceptor {
    async intercept(request: Request): Promise<Request> {
        request.headers.set('Authorization', `Bearer ${token}`);
        return request;
    }
}

const httpClient = new HttpClient('https://api.example.com', {
    timeout: 5000
});
httpClient.addInterceptor(new AuthInterceptor());

// Make requests
const users = await httpClient.get<User[]>('/users');
const newUser = await httpClient.post<User>('/users', userData);

From Winston to ziegel-platform-logging ​

Migrating from Winston logging:

Before (Winston) ​

typescript
import winston from 'winston';

const logger = winston.createLogger({
    level: 'info',
    format: winston.format.json(),
    transports: [
        new winston.transports.File({ filename: 'error.log', level: 'error' }),
        new winston.transports.File({ filename: 'combined.log' })
    ]
});

logger.info('Application started');
logger.error('Something went wrong', error);

After (ziegel-platform-logging) ​

typescript
import { LoggerManager, ILogger, LogLevel } from '@breadstone/ziegel-platform-logging';

const logger = LoggerManager.getLogger('Application');

// Configure logging (typically in application startup)
LoggerManager.configure({
    level: LogLevel.Info,
    providers: [
        new FileLogProvider('logs/app.log'),
        new ConsoleLogProvider()
    ]
});

logger.info('Application started');
logger.error('Something went wrong', error);

From i18next to ziegel-platform-localization ​

Migrating from i18next:

Before (i18next) ​

typescript
import i18n from 'i18next';
import Backend from 'i18next-http-backend';

await i18n
    .use(Backend)
    .init({
        lng: 'en',
        fallbackLng: 'en',
        backend: {
            loadPath: '/locales/{{lng}}/{{ns}}.json'
        }
    });

const welcome = i18n.t('welcome');
const userCount = i18n.t('userCount', { count: 5 });

After (ziegel-platform-localization) ​

typescript
import {
    LocalizationManager,
    LoaderLocalizationProvider,
    HttpLocalizationLoader
} from '@breadstone/ziegel-platform-localization';

const loader = new HttpLocalizationLoader('/locales/{culture}.json');
const provider = new LoaderLocalizationProvider(loader);
const localizationManager = new LocalizationManager(provider);

await localizationManager.setCulture('en');

const welcome = await localizationManager.getLocalizedString('welcome');
const userCount = await localizationManager.getLocalizedString('userCount', 5);

Upgrading ziegel Versions ​

From ziegel 0.0.1 to 0.0.2 ​

Current version is 0.0.2. For future upgrades, here are best practices:

1. Check the Changelog ​

Always review the changelog before upgrading:

  • Breaking changes
  • New features
  • Deprecations
  • Migration notes

2. Update Dependencies ​

bash
# Update all ziegel packages at once
npm update @breadstone/ziegel-*

# Or update individually
npm update @breadstone/ziegel-core
npm update @breadstone/ziegel-platform

3. Run Tests ​

Ensure your test suite passes after the upgrade:

bash
npm test

4. Check TypeScript Compilation ​

Verify that TypeScript compilation succeeds:

bash
npx tsc --noEmit

Step-by-Step Migration ​

Phase 1: Foundation (Week 1) ​

  1. Install core packages

    bash
    npm install @breadstone/ziegel-core @breadstone/ziegel-platform
  2. Replace basic utilities

    • Migrate string operations to StringExtensions
    • Replace object utilities with ObjectExtensions
    • Update type checking to use TypeGuard
  3. Setup service location

    • Replace direct instantiation with ServiceLocator
    • Register core services

Phase 2: Infrastructure (Week 2) ​

  1. Add logging

    bash
    npm install @breadstone/ziegel-platform-logging
    • Replace existing logging with ziegel logging
    • Configure log providers
  2. Add configuration management

    bash
    npm install @breadstone/ziegel-platform-configuration
    • Migrate configuration to ConfigurationManager
    • Setup environment-specific configs
  3. Migrate HTTP client

    bash
    npm install @breadstone/ziegel-platform-http
    • Replace existing HTTP library
    • Migrate interceptors

Phase 3: Features (Week 3-4) ​

  1. Add internationalization (if needed)

    bash
    npm install @breadstone/ziegel-intl @breadstone/ziegel-platform-localization
  2. Add specialized services (as needed)

    bash
    npm install @breadstone/ziegel-platform-caching
    npm install @breadstone/ziegel-platform-messaging
  3. Update presentation layer (if applicable)

    bash
    npm install @breadstone/ziegel-presentation

Common Migration Patterns ​

Service Registration Pattern ​

Before ​

typescript
class UserService {
    private httpClient: any;
    private logger: any;

    constructor() {
        this.httpClient = new HttpClient();
        this.logger = new Logger();
    }
}

export const userService = new UserService();

After ​

typescript
import { ServiceLocator } from '@breadstone/ziegel-platform';

class UserService {
    private httpClient: HttpClient;
    private logger: ILogger;

    constructor() {
        this.httpClient = ServiceLocator.get<HttpClient>('httpClient');
        this.logger = ServiceLocator.get<ILogger>('logger');
    }
}

// Register in application startup
ServiceLocator.register('userService', () => new UserService());

Configuration Pattern ​

Before ​

typescript
const config = {
    apiUrl: process.env.API_URL || 'http://localhost:3000',
    dbConnection: process.env.DB_CONNECTION,
    features: {
        enableAnalytics: process.env.ENABLE_ANALYTICS === 'true'
    }
};

After ​

typescript
import { ConfigurationManager } from '@breadstone/ziegel-platform-configuration';

const config = new ConfigurationManager();
config.addJsonFile('appsettings.json');
config.addEnvironmentVariables();

const apiUrl = config.getValue<string>('api:url', 'http://localhost:3000');
const dbConnection = config.getValue<string>('database:connection');
const enableAnalytics = config.getValue<boolean>('features:enableAnalytics', false);

Error Handling Pattern ​

Before ​

typescript
function validateUser(user: any) {
    if (!user) {
        throw new Error('User is required');
    }
    if (!user.email) {
        throw new Error('Email is required');
    }
}

After ​

typescript
import { ArgumentNullException, ArgumentException } from '@breadstone/ziegel-core';

function validateUser(user: any) {
    if (!user) {
        throw new ArgumentNullException('user', 'User is required');
    }
    if (!user.email) {
        throw new ArgumentException('user.email', 'Email is required');
    }
}

Migration Checklist ​

Before Starting ​

  • [ ] Review current dependencies
  • [ ] Backup your project
  • [ ] Plan migration phases
  • [ ] Setup testing environment

During Migration ​

  • [ ] Update package.json
  • [ ] Migrate utilities first
  • [ ] Update service registration
  • [ ] Migrate configuration
  • [ ] Update HTTP client
  • [ ] Migrate logging
  • [ ] Update error handling
  • [ ] Run tests frequently

After Migration ​

  • [ ] Remove old dependencies
  • [ ] Update documentation
  • [ ] Train team on new patterns
  • [ ] Monitor for issues
  • [ ] Performance testing

Troubleshooting ​

Common Issues ​

TypeScript Compilation Errors ​

bash
# Clear TypeScript cache
rm -rf node_modules/.cache/typescript

# Reinstall dependencies
rm -rf node_modules package-lock.json
npm install

Service Location Issues ​

Make sure services are registered before they're used:

typescript
// Wrong order
const service = ServiceLocator.get<MyService>('myService'); // Error!
ServiceLocator.register('myService', () => new MyService());

// Correct order
ServiceLocator.register('myService', () => new MyService());
const service = ServiceLocator.get<MyService>('myService'); // Works!

Configuration Not Found ​

Ensure configuration files exist and are properly formatted:

typescript
try {
    const config = new ConfigurationManager();
    config.addJsonFile('appsettings.json'); // Make sure this file exists
} catch (error) {
    console.error('Configuration error:', error);
}

Getting Help ​

If you encounter issues during migration:

  1. Check the documentation for the specific package
  2. Review the examples in this guide
  3. Search existing issues on Azure DevOps
  4. Create a new issue with:
    • Your current setup
    • What you're trying to migrate
    • The specific error or problem
    • A minimal reproduction case

Next Steps ​

After completing your migration: