Socket
Book a DemoInstallSign in
Socket

@djangocfg/ext-base

Package Overview
Dependencies
Maintainers
1
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@djangocfg/ext-base

Base utilities and common code for DjangoCFG extensions

Source
npmnpm
Version
1.0.0
Version published
Weekly downloads
140
-77.92%
Maintainers
1
Weekly downloads
 
Created
Source

@djangocfg/ext-base

Base utilities and common code for building DjangoCFG extensions.

Part of DjangoCFG — modern Django framework for production-ready SaaS applications.

What is this?

@djangocfg/ext-base is a foundation library for DjangoCFG extensions. It provides:

  • Extension registration system - automatic extension metadata tracking
  • Common React hooks - pagination, infinite scroll, data fetching patterns
  • Environment utilities - isDevelopment, isProduction, isStaticBuild helpers
  • Type-safe context helpers - factory functions for creating contexts
  • Logger utilities - structured logging with tags
  • Auth integration - convenient re-exports of useAuth
  • TypeScript types - shared types for all extensions

This package is used internally by all official DjangoCFG extensions (newsletter, payments, support, leads, knowbase) and can be used to build your own custom extensions.

Install

pnpm add @djangocfg/ext-base

Quick Start

1. Create extension metadata

// src/config.ts
import type { ExtensionMetadata } from '@djangocfg/ext-base';

export const extensionConfig: ExtensionMetadata = {
  name: 'my-extension',
  version: '1.0.0',
  author: 'Your Name',
  displayName: 'My Extension',
  description: 'Amazing extension functionality',
  icon: '🚀',
  license: 'MIT',
  keywords: ['extension', 'feature'],
};

2. Create your extension provider

// src/contexts/MyExtensionProvider.tsx
'use client';

import { ExtensionProvider } from '@djangocfg/ext-base/hooks';
import { extensionConfig } from '../config';

export function MyExtensionProvider({ children }) {
  return (
    <ExtensionProvider metadata={extensionConfig}>
      {/* Your extension contexts here */}
      {children}
    </ExtensionProvider>
  );
}

3. Use in your app

import { MyExtensionProvider } from '@your-org/my-extension/hooks';

export default function RootLayout({ children }) {
  return (
    <MyExtensionProvider>
      {children}
    </MyExtensionProvider>
  );
}

The extension will automatically register itself and log in development mode:

[ext-base] Extension registered: My Extension v1.0.0

Core Features

Environment Configuration

import { isDevelopment, isProduction, isStaticBuild, isClient, isServer } from '@djangocfg/ext-base';

if (isDevelopment) {
  console.log('Running in development mode');
}

if (isStaticBuild) {
  // Special handling for Next.js static export
}

API Factory

Create extension API instances with shared authentication in one line:

// src/api/index.ts
import { API } from './generated/ext_myextension';
import { createExtensionAPI } from '@djangocfg/ext-base/api';

// That's it! All configuration is handled automatically:
// - API URL from environment
// - Static build detection
// - Shared authentication storage from @djangocfg/api
export const apiMyExtension = createExtensionAPI(API);

Before (manual setup):

import { API } from './generated/ext_myextension';
import { api as accountsApi } from '@djangocfg/api';

const isStaticBuild = process.env.NEXT_PUBLIC_STATIC_BUILD === 'true';
const apiUrl = isStaticBuild ? '' : process.env.NEXT_PUBLIC_API_URL || '';
const storage = (accountsApi as any)._storage;

export const apiMyExtension = new API(apiUrl, { storage });

After (with factory):

import { API } from './generated/ext_myextension';
import { createExtensionAPI } from '@djangocfg/ext-base/api';

export const apiMyExtension = createExtensionAPI(API);

Pagination Hooks

import { usePagination, useInfinitePagination } from '@djangocfg/ext-base/hooks';

// Standard pagination
const { items, page, pageSize, totalPages, goToPage, nextPage, prevPage } = usePagination({
  keyPrefix: 'articles',
  fetcher: async (page, pageSize) => {
    const response = await api.articles.list({ page, page_size: pageSize });
    return response.data;
  },
  initialPage: 1,
  pageSize: 20,
});

// Infinite scroll
const { items, isLoading, hasMore, loadMore } = useInfinitePagination({
  keyPrefix: 'articles',
  fetcher: async (page, pageSize) => {
    const response = await api.articles.list({ page, page_size: pageSize });
    return response.data;
  },
  pageSize: 20,
});

Type-Safe Context Creation

import { createExtensionContext } from '@djangocfg/ext-base/hooks';

interface MyContextValue {
  data: any[];
  refresh: () => void;
}

const { Provider, useContext: useMyContext } = createExtensionContext<MyContextValue>({
  displayName: 'MyContext',
  errorMessage: 'useMyContext must be used within MyProvider',
});

// In components
export function MyComponent() {
  const { data, refresh } = useMyContext();
  return <div>{data.length} items</div>;
}

Logger

import { createExtensionLogger } from '@djangocfg/ext-base';

const logger = createExtensionLogger({
  tag: 'my-extension',
  level: 'info',
});

logger.info('Extension initialized');
logger.error('Something went wrong', error);
logger.success('Operation completed!');

Auth Integration

import { useAuth } from '@djangocfg/ext-base/auth';

function MyComponent() {
  const { user, isAuthenticated, login, logout } = useAuth();

  if (!isAuthenticated) {
    return <button onClick={login}>Login</button>;
  }

  return <div>Welcome, {user?.email}</div>;
}

Error Handling

import { handleError, formatError } from '@djangocfg/ext-base';

try {
  await someOperation();
} catch (error) {
  handleError(error, (formattedError) => {
    logger.error('Operation failed:', formattedError);
  });
}

Package Exports

Main entry (@djangocfg/ext-base)

Server-safe exports - can be used in both client and server components:

  • All TypeScript types
  • Environment configuration (isDevelopment, isProduction, etc.)
  • API factory (createExtensionAPI)
  • Logger utilities
  • Error handling utilities

Hooks entry (@djangocfg/ext-base/hooks)

Client-only exports:

  • ExtensionProvider - main provider component
  • usePagination - standard pagination hook
  • useInfinitePagination - infinite scroll hook
  • createExtensionContext - context factory

Auth entry (@djangocfg/ext-base/auth)

Auth re-exports:

  • useAuth - authentication hook
  • UserProfile type
  • AuthContextType type

API entry (@djangocfg/ext-base/api)

API utilities:

  • createExtensionAPI - API instance factory
  • getSharedAuthStorage - Get shared auth storage

TypeScript Types

import type {
  // Extension metadata
  ExtensionMetadata,
  ExtensionProviderProps,

  // Pagination
  PaginatedResponse,
  PaginationParams,
  PaginationState,
  InfinitePaginationReturn,

  // Logger
  ExtensionLogger,
  LoggerOptions,

  // Errors
  ExtensionError,
  ErrorHandler,

  // Context
  ExtensionContextOptions,
} from '@djangocfg/ext-base';

Example: Complete Extension

// config.ts
export const extensionConfig: ExtensionMetadata = {
  name: 'blog',
  version: '1.0.0',
  author: 'Your Company',
  displayName: 'Blog',
  description: 'Blog management system',
  icon: '📝',
  keywords: ['blog', 'articles'],
};

// contexts/BlogProvider.tsx
'use client';

import { ExtensionProvider } from '@djangocfg/ext-base/hooks';
import { useInfinitePagination } from '@djangocfg/ext-base/hooks';
import { createExtensionLogger } from '@djangocfg/ext-base';
import { extensionConfig } from '../config';

const logger = createExtensionLogger({ tag: 'blog' });

export function BlogProvider({ children }) {
  const { items, loadMore, hasMore } = useInfinitePagination({
    keyPrefix: 'blog-articles',
    fetcher: async (page, pageSize) => {
      const response = await api.articles.list({ page, page_size: pageSize });
      return response.data;
    },
  });

  logger.info('Blog provider initialized with', items.length, 'articles');

  return (
    <ExtensionProvider metadata={extensionConfig}>
      {/* Your contexts here */}
      {children}
    </ExtensionProvider>
  );
}

Best Practices

  • Always use ExtensionProvider - Wrap your extension with it for proper registration
  • Define metadata - Create a config.ts file with complete metadata
  • Use provided hooks - Leverage usePagination and useInfinitePagination
  • Structured logging - Use createExtensionLogger with consistent tags
  • Type safety - Import types from @djangocfg/ext-base
  • Separate entry points - Use /hooks for client code, main entry for server-safe code

License

MIT

Keywords

django

FAQs

Package last updated on 08 Dec 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts