@djangocfg/ext-base 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Extension Base configuration
3
+ */
4
+
5
+ import type { ExtensionMetadata } from './types';
6
+ import packageJson from '../package.json';
7
+
8
+ export const extensionConfig: ExtensionMetadata = {
9
+ name: 'base',
10
+ version: packageJson.version,
11
+ author: 'DjangoCFG Team',
12
+ displayName: 'Extension Base',
13
+ description: 'Base utilities and common code for building DjangoCFG extensions. Includes CLI tool for managing extensions.',
14
+ icon: 'Wrench',
15
+ license: 'MIT',
16
+ githubUrl: 'https://github.com/markolofsen/django-cfg',
17
+ homepage: 'https://djangocfg.com',
18
+ keywords: ['base', 'utilities', 'cli', 'toolkit', 'helpers', 'hooks'],
19
+
20
+ // Marketplace metadata
21
+ category: 'utilities',
22
+ tags: ['base', 'utilities', 'cli', 'toolkit'],
23
+ features: [
24
+ 'Extension registration system',
25
+ 'React hooks for pagination and infinite scroll',
26
+ 'Environment utilities and helpers',
27
+ 'CLI tool for extension management',
28
+ 'Type-safe context helpers',
29
+ 'Logger utilities',
30
+ ],
31
+ npmUrl: `https://www.npmjs.com/package/${packageJson.name}`,
32
+ installCommand: `pnpm add ${packageJson.name}`,
33
+ peerDependencies: packageJson.peerDependencies,
34
+ examples: [
35
+ {
36
+ title: 'Basic Extension Setup',
37
+ description: 'Initialize a new DjangoCFG extension',
38
+ code: `import { createExtension } from '@djangocfg/ext-base';
39
+
40
+ const myExtension = createExtension({
41
+ name: 'my-extension',
42
+ version: '1.0.0',
43
+ register: (app) => {
44
+ console.log('Extension registered!');
45
+ },
46
+ });
47
+
48
+ export default myExtension;`,
49
+ language: 'typescript',
50
+ },
51
+ {
52
+ title: 'Using Pagination Hook',
53
+ description: 'Implement infinite scroll with usePagination',
54
+ code: `import { usePagination } from '@djangocfg/ext-base';
55
+
56
+ function DataList() {
57
+ const { data, loading, hasMore, loadMore } = usePagination({
58
+ fetchFn: (page) => fetch(\`/api/data?page=\${page}\`),
59
+ pageSize: 20,
60
+ });
61
+
62
+ return (
63
+ <div>
64
+ {data.map(item => <div key={item.id}>{item.name}</div>)}
65
+ {hasMore && <button onClick={loadMore}>Load More</button>}
66
+ </div>
67
+ );
68
+ }`,
69
+ language: 'tsx',
70
+ },
71
+ ],
72
+ githubStars: 245,
73
+ };
@@ -10,6 +10,60 @@ export interface ExtensionContextOptions {
10
10
  revalidateIfStale?: boolean;
11
11
  }
12
12
 
13
+ /**
14
+ * Extension category types
15
+ */
16
+ export type ExtensionCategory =
17
+ | 'forms' // Forms, CRM, Lead Management
18
+ | 'payments' // Payment Processing, Billing
19
+ | 'content' // Content Management, Marketing
20
+ | 'support' // Support, Helpdesk, Tickets
21
+ | 'utilities' // Tools, Base, Infrastructure
22
+ | 'analytics' // Analytics, Tracking, Monitoring
23
+ | 'security' // Security, Authentication, Authorization
24
+ | 'integration' // Third-party Integrations
25
+ | 'other'; // Other/Uncategorized
26
+
27
+ /**
28
+ * Extension categories with display names for CLI and UI
29
+ */
30
+ export const EXTENSION_CATEGORIES: Array<{ title: string; value: ExtensionCategory }> = [
31
+ { title: 'Forms', value: 'forms' },
32
+ { title: 'Payments', value: 'payments' },
33
+ { title: 'Content', value: 'content' },
34
+ { title: 'Support', value: 'support' },
35
+ { title: 'Utilities', value: 'utilities' },
36
+ { title: 'Analytics', value: 'analytics' },
37
+ { title: 'Security', value: 'security' },
38
+ { title: 'Integration', value: 'integration' },
39
+ { title: 'Other', value: 'other' },
40
+ ];
41
+
42
+ /**
43
+ * Code example for extension documentation
44
+ */
45
+ export interface ExtensionExample {
46
+ /**
47
+ * Example title
48
+ */
49
+ title: string;
50
+
51
+ /**
52
+ * Example description
53
+ */
54
+ description?: string;
55
+
56
+ /**
57
+ * Code snippet
58
+ */
59
+ code: string;
60
+
61
+ /**
62
+ * Programming language for syntax highlighting
63
+ */
64
+ language: string;
65
+ }
66
+
13
67
  export interface ExtensionMetadata {
14
68
  /**
15
69
  * Unique extension name (e.g., 'newsletter', 'payments')
@@ -58,13 +112,13 @@ export interface ExtensionMetadata {
58
112
  keywords?: string[];
59
113
 
60
114
  /**
61
- * Extension icon URL or emoji
62
- * @example '📧' or 'https://example.com/icon.png'
115
+ * Extension icon - Lucide icon name or emoji
116
+ * @example 'Mail' or '📧'
63
117
  */
64
118
  icon?: string;
65
119
 
66
120
  /**
67
- * List of extension dependencies
121
+ * List of extension dependencies (other extension names)
68
122
  * @example ['payments', 'auth']
69
123
  */
70
124
  dependencies?: string[];
@@ -73,6 +127,73 @@ export interface ExtensionMetadata {
73
127
  * Minimum required DjangoCFG version
74
128
  */
75
129
  minVersion?: string;
130
+
131
+ // ─────────────────────────────────────────────────────────────────────────
132
+ // Marketplace-specific fields
133
+ // ─────────────────────────────────────────────────────────────────────────
134
+
135
+ /**
136
+ * Extension category for marketplace organization
137
+ */
138
+ category?: ExtensionCategory;
139
+
140
+ /**
141
+ * Tags for search and filtering
142
+ */
143
+ tags?: string[];
144
+
145
+ /**
146
+ * List of key features
147
+ */
148
+ features?: string[];
149
+
150
+ /**
151
+ * npm package URL
152
+ * @example 'https://www.npmjs.com/package/@djangocfg/ext-newsletter'
153
+ */
154
+ npmUrl?: string;
155
+
156
+ /**
157
+ * Installation command
158
+ * @example 'pnpm add @djangocfg/ext-newsletter'
159
+ */
160
+ installCommand?: string;
161
+
162
+ /**
163
+ * Code examples for documentation
164
+ */
165
+ examples?: ExtensionExample[];
166
+
167
+ /**
168
+ * npm package dependencies
169
+ */
170
+ packageDependencies?: Record<string, string>;
171
+
172
+ /**
173
+ * npm peer dependencies
174
+ */
175
+ peerDependencies?: Record<string, string>;
176
+
177
+ /**
178
+ * Related extension IDs
179
+ */
180
+ relatedExtensions?: string[];
181
+
182
+ /**
183
+ * README content in markdown
184
+ */
185
+ readme?: string;
186
+
187
+ /**
188
+ * Preview image URL (1200x630 recommended)
189
+ * @example 'https://unpkg.com/@djangocfg/ext-leads@latest/preview.svg'
190
+ */
191
+ preview?: string;
192
+
193
+ /**
194
+ * GitHub stars count
195
+ */
196
+ githubStars?: number;
76
197
  }
77
198
 
78
199
  export interface ExtensionProviderProps {
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Helper to create extension configuration from package.json
3
+ */
4
+
5
+ import type { ExtensionMetadata } from '../types';
6
+
7
+ /**
8
+ * Package.json structure
9
+ */
10
+ interface PackageJson {
11
+ name: string;
12
+ version: string;
13
+ description?: string;
14
+ keywords?: string[];
15
+ author?: string | { name: string; email?: string; url?: string };
16
+ license?: string;
17
+ homepage?: string;
18
+ repository?: string | { type: string; url: string; directory?: string };
19
+ peerDependencies?: Record<string, string>;
20
+ dependencies?: Record<string, string>;
21
+ }
22
+
23
+ /**
24
+ * Manual metadata fields that must be provided
25
+ */
26
+ export interface ExtensionConfigInput {
27
+ /**
28
+ * Extension short name (e.g., 'leads', 'payments')
29
+ */
30
+ name: string;
31
+
32
+ /**
33
+ * Display name for marketplace
34
+ */
35
+ displayName: string;
36
+
37
+ /**
38
+ * Lucide icon name
39
+ * @example 'FileText', 'CreditCard', 'Mail'
40
+ */
41
+ icon: string;
42
+
43
+ /**
44
+ * Extension category
45
+ */
46
+ category: ExtensionMetadata['category'];
47
+
48
+ /**
49
+ * Key features list
50
+ */
51
+ features: string[];
52
+
53
+ /**
54
+ * Code examples (optional)
55
+ */
56
+ examples?: ExtensionMetadata['examples'];
57
+
58
+ /**
59
+ * Minimum required DjangoCFG version (optional)
60
+ */
61
+ minVersion?: string;
62
+
63
+ /**
64
+ * Related extension IDs (optional)
65
+ */
66
+ relatedExtensions?: string[];
67
+
68
+ /**
69
+ * GitHub stars count (optional)
70
+ */
71
+ githubStars?: number;
72
+ }
73
+
74
+ /**
75
+ * Create extension configuration from package.json + manual metadata
76
+ *
77
+ * @example
78
+ * ```ts
79
+ * import packageJson from '../package.json';
80
+ * import { createExtensionConfig } from '@djangocfg/ext-base';
81
+ *
82
+ * export const extensionConfig = createExtensionConfig(packageJson, {
83
+ * name: 'leads',
84
+ * displayName: 'Leads & Forms',
85
+ * icon: 'FileText',
86
+ * category: 'forms',
87
+ * features: [
88
+ * 'Contact form components',
89
+ * 'Lead tracking',
90
+ * ],
91
+ * });
92
+ * ```
93
+ */
94
+ export function createExtensionConfig(
95
+ packageJson: PackageJson,
96
+ config: ExtensionConfigInput
97
+ ): ExtensionMetadata {
98
+ // Extract author name
99
+ const author = typeof packageJson.author === 'string'
100
+ ? packageJson.author
101
+ : packageJson.author?.name || 'Unknown';
102
+
103
+ // Extract repository URL
104
+ const githubUrl = typeof packageJson.repository === 'string'
105
+ ? packageJson.repository
106
+ : packageJson.repository?.url;
107
+
108
+ return {
109
+ // From package.json
110
+ name: config.name,
111
+ version: packageJson.version,
112
+ author,
113
+ description: packageJson.description,
114
+ keywords: packageJson.keywords,
115
+ license: packageJson.license,
116
+ homepage: packageJson.homepage,
117
+ githubUrl,
118
+ peerDependencies: packageJson.peerDependencies,
119
+
120
+ // From manual config
121
+ displayName: config.displayName,
122
+ icon: config.icon,
123
+ category: config.category,
124
+ features: config.features,
125
+ examples: config.examples,
126
+ minVersion: config.minVersion,
127
+ relatedExtensions: config.relatedExtensions,
128
+ githubStars: config.githubStars,
129
+
130
+ // Auto-generated
131
+ npmUrl: `https://www.npmjs.com/package/${packageJson.name}`,
132
+ installCommand: `pnpm add ${packageJson.name}`,
133
+ tags: packageJson.keywords,
134
+ preview: `https://unpkg.com/${packageJson.name}@latest/preview.png`,
135
+
136
+ // Dependencies (empty by default, can be set via keywords)
137
+ dependencies: [],
138
+ };
139
+ }
@@ -8,3 +8,8 @@ export {
8
8
  formatErrorMessage,
9
9
  handleExtensionError,
10
10
  } from './errors';
11
+
12
+ export {
13
+ createExtensionConfig,
14
+ type ExtensionConfigInput,
15
+ } from './createExtensionConfig';
@@ -0,0 +1,62 @@
1
+ <div align="center">
2
+
3
+ ![DjangoCFG Extension Preview](https://unpkg.com/@djangocfg/ext-__NAME__@latest/preview.png)
4
+
5
+ </div>
6
+
7
+ # @djangocfg/ext-__NAME__
8
+
9
+ __DESCRIPTION__
10
+
11
+ **Part of [DjangoCFG](https://djangocfg.com)** — modern Django framework for production-ready SaaS applications.
12
+
13
+ ## Features
14
+
15
+ - Feature 1
16
+ - Feature 2
17
+ - Feature 3
18
+
19
+ ## Install
20
+
21
+ ```bash
22
+ pnpm add @djangocfg/ext-__NAME__
23
+ ```
24
+
25
+ ## Usage
26
+
27
+ ### Provider Setup
28
+
29
+ ```typescript
30
+ import { __PROVIDER_NAME__ExtensionProvider } from '@djangocfg/ext-__NAME__/hooks';
31
+
32
+ export default function RootLayout({ children }) {
33
+ return (
34
+ <__PROVIDER_NAME__ExtensionProvider>
35
+ {children}
36
+ </__PROVIDER_NAME__ExtensionProvider>
37
+ );
38
+ }
39
+ ```
40
+
41
+ ### Using Hooks
42
+
43
+ ```typescript
44
+ 'use client';
45
+
46
+ import { use__PROVIDER_NAME__ } from '@djangocfg/ext-__NAME__/hooks';
47
+
48
+ export function MyComponent() {
49
+ const context = use__PROVIDER_NAME__();
50
+
51
+ return <div>Your component</div>;
52
+ }
53
+ ```
54
+
55
+ ## License
56
+
57
+ MIT
58
+
59
+ ## Links
60
+
61
+ - [DjangoCFG Documentation](https://djangocfg.com)
62
+ - [GitHub](https://github.com/markolofsen/django-cfg)
@@ -0,0 +1,73 @@
1
+ {
2
+ "name": "@djangocfg/ext-__NAME__",
3
+ "version": "1.0.0",
4
+ "description": "__DESCRIPTION__",
5
+ "keywords": [
6
+ "django",
7
+ "djangocfg",
8
+ "extension",
9
+ "__NAME__",
10
+ "typescript",
11
+ "react"
12
+ ],
13
+ "author": {
14
+ "name": "DjangoCFG",
15
+ "url": "https://djangocfg.com"
16
+ },
17
+ "homepage": "https://djangocfg.com",
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "https://github.com/markolofsen/django-cfg.git",
21
+ "directory": "extensions/__NAME__"
22
+ },
23
+ "bugs": {
24
+ "url": "https://github.com/markolofsen/django-cfg/issues"
25
+ },
26
+ "license": "MIT",
27
+ "type": "module",
28
+ "main": "./dist/index.cjs",
29
+ "module": "./dist/index.js",
30
+ "types": "./dist/index.d.ts",
31
+ "exports": {
32
+ ".": {
33
+ "types": "./dist/index.d.ts",
34
+ "import": "./dist/index.js",
35
+ "require": "./dist/index.cjs"
36
+ },
37
+ "./hooks": {
38
+ "types": "./dist/hooks.d.ts",
39
+ "import": "./dist/hooks.js",
40
+ "require": "./dist/hooks.cjs"
41
+ }
42
+ },
43
+ "files": [
44
+ "dist",
45
+ "src",
46
+ "preview.png"
47
+ ],
48
+ "scripts": {
49
+ "build": "tsup",
50
+ "dev": "tsup --watch",
51
+ "check": "tsc --noEmit"
52
+ },
53
+ "peerDependencies": {
54
+ "@djangocfg/ext-base": "latest",
55
+ "@djangocfg/ui-core": "latest",
56
+ "@djangocfg/ui-nextjs": "latest",
57
+ "consola": "^3.4.2",
58
+ "lucide-react": "^0.545.0",
59
+ "next": "^15.5.7",
60
+ "react": "^18 || ^19",
61
+ "swr": "^2.3.7"
62
+ },
63
+ "devDependencies": {
64
+ "@djangocfg/ext-base": "latest",
65
+ "@djangocfg/typescript-config": "latest",
66
+ "@types/node": "^24.7.2",
67
+ "@types/react": "^19.0.0",
68
+ "consola": "^3.4.2",
69
+ "swr": "^2.3.7",
70
+ "tsup": "^8.5.0",
71
+ "typescript": "^5.9.3"
72
+ }
73
+ }
@@ -0,0 +1,35 @@
1
+ /**
2
+ * __DISPLAY_NAME__ extension configuration
3
+ */
4
+
5
+ import { createExtensionConfig } from '@djangocfg/ext-base';
6
+ import packageJson from '../package.json';
7
+
8
+ export const extensionConfig = createExtensionConfig(packageJson, {
9
+ name: '__NAME__',
10
+ displayName: '__DISPLAY_NAME__',
11
+ icon: '__ICON__',
12
+ category: '__CATEGORY__',
13
+ features: [
14
+ 'Feature 1',
15
+ 'Feature 2',
16
+ 'Feature 3',
17
+ ],
18
+ minVersion: '2.0.0',
19
+ examples: [
20
+ {
21
+ title: 'Basic Usage',
22
+ description: 'How to use this extension',
23
+ code: `import { __PROVIDER_NAME__ExtensionProvider } from '@djangocfg/ext-__NAME__/hooks';
24
+
25
+ export default function RootLayout({ children }) {
26
+ return (
27
+ <__PROVIDER_NAME__ExtensionProvider>
28
+ {children}
29
+ </__PROVIDER_NAME__ExtensionProvider>
30
+ );
31
+ }`,
32
+ language: 'tsx',
33
+ },
34
+ ],
35
+ });
@@ -0,0 +1,41 @@
1
+ 'use client';
2
+
3
+ /**
4
+ * Main __DISPLAY_NAME__ Context
5
+ */
6
+
7
+ import { createContext, useContext, type ReactNode } from 'react';
8
+
9
+ interface __PROVIDER_NAME__ContextValue {
10
+ // Add your context values here
11
+ }
12
+
13
+ const __PROVIDER_NAME__Context = createContext<__PROVIDER_NAME__ContextValue | undefined>(undefined);
14
+
15
+ export interface __PROVIDER_NAME__ProviderProps {
16
+ children: ReactNode;
17
+ }
18
+
19
+ export function __PROVIDER_NAME__Provider({ children }: __PROVIDER_NAME__ProviderProps) {
20
+ const value: __PROVIDER_NAME__ContextValue = {
21
+ // Implement your context logic here
22
+ };
23
+
24
+ return (
25
+ <__PROVIDER_NAME__Context.Provider value={value}>
26
+ {children}
27
+ </__PROVIDER_NAME__Context.Provider>
28
+ );
29
+ }
30
+
31
+ export function use__PROVIDER_NAME__() {
32
+ const context = useContext(__PROVIDER_NAME__Context);
33
+ if (context === undefined) {
34
+ throw new Error('use__PROVIDER_NAME__ must be used within __PROVIDER_NAME__Provider');
35
+ }
36
+ return context;
37
+ }
38
+
39
+ export function use__PROVIDER_NAME__Optional() {
40
+ return useContext(__PROVIDER_NAME__Context);
41
+ }
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Main __DISPLAY_NAME__ Extension Provider
3
+ *
4
+ * Wraps all contexts with ExtensionProvider for proper registration
5
+ */
6
+
7
+ 'use client';
8
+
9
+ import type { ReactNode } from 'react';
10
+ import { ExtensionProvider } from '@djangocfg/ext-base/hooks';
11
+ import { extensionConfig } from '../config';
12
+ import { __PROVIDER_NAME__Provider } from './__PROVIDER_NAME__Context';
13
+
14
+ interface __PROVIDER_NAME__ExtensionProviderProps {
15
+ children: ReactNode;
16
+ }
17
+
18
+ /**
19
+ * Main provider for __DISPLAY_NAME__ extension
20
+ *
21
+ * @example
22
+ * ```tsx
23
+ * <__PROVIDER_NAME__ExtensionProvider>
24
+ * <YourApp />
25
+ * </__PROVIDER_NAME__ExtensionProvider>
26
+ * ```
27
+ */
28
+ export function __PROVIDER_NAME__ExtensionProvider({ children }: __PROVIDER_NAME__ExtensionProviderProps) {
29
+ return (
30
+ <ExtensionProvider metadata={extensionConfig}>
31
+ <__PROVIDER_NAME__Provider>
32
+ {children}
33
+ </__PROVIDER_NAME__Provider>
34
+ </ExtensionProvider>
35
+ );
36
+ }
@@ -0,0 +1,27 @@
1
+ 'use client';
2
+
3
+ /**
4
+ * @djangocfg/ext-__NAME__/hooks
5
+ * React hooks and client-only components
6
+ *
7
+ * This entry point includes React components, hooks, and SWR functionality.
8
+ * NOT safe for Server Components.
9
+ */
10
+
11
+ // ============================================================================
12
+ // Re-export everything from main entry (types, constants)
13
+ // ============================================================================
14
+ export * from '../index';
15
+
16
+ // ============================================================================
17
+ // Contexts & Hooks
18
+ // ============================================================================
19
+ export {
20
+ __PROVIDER_NAME__ExtensionProvider,
21
+ } from '../contexts/__PROVIDER_NAME__ExtensionProvider';
22
+
23
+ export {
24
+ __PROVIDER_NAME__Provider,
25
+ use__PROVIDER_NAME__,
26
+ use__PROVIDER_NAME__Optional,
27
+ } from '../contexts/__PROVIDER_NAME__Context';
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @djangocfg/ext-__NAME__
3
+ * Server-safe entry point (no client-only code)
4
+ *
5
+ * Contains types and server-safe exports only.
6
+ * For React hooks and SWR, use '@djangocfg/ext-__NAME__/hooks'
7
+ */
8
+
9
+ // ============================================================================
10
+ // Config
11
+ // ============================================================================
12
+ export { extensionConfig } from './config';
13
+
14
+ // ============================================================================
15
+ // Types
16
+ // ============================================================================
17
+ export type * from './types';
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Extension TypeScript types
3
+ */
4
+
5
+ export interface ExtensionData {
6
+ // Add your types here
7
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "extends": "@djangocfg/typescript-config/nextjs.json",
3
+ "compilerOptions": {
4
+ "outDir": "dist"
5
+ },
6
+ "include": ["src"],
7
+ "exclude": ["node_modules", "dist"]
8
+ }