@djangocfg/ext-base 1.0.1 → 1.0.3
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.
- package/README.md +154 -25
- package/package.json +11 -8
- package/preview.png +0 -0
- package/src/cli/index.ts +326 -160
- package/src/config.ts +17 -0
- package/src/extensionConfig.ts +65 -0
- package/src/index.ts +5 -1
- package/src/metadata.ts +72 -0
- package/src/types/context.ts +135 -8
- package/src/utils/createExtensionConfig.ts +155 -0
- package/src/utils/index.ts +5 -0
- package/templates/extension-template/README.md.template +64 -0
- package/templates/extension-template/package.json.template +80 -0
- package/templates/extension-template/preview.png +0 -0
- package/templates/extension-template/src/components/.gitkeep +0 -0
- package/templates/extension-template/src/config.ts +34 -0
- package/templates/extension-template/src/contexts/__PROVIDER_NAME__Context.tsx +41 -0
- package/templates/extension-template/src/contexts/__PROVIDER_NAME__ExtensionProvider.tsx +36 -0
- package/templates/extension-template/src/hooks/index.ts +27 -0
- package/templates/extension-template/src/index.ts +17 -0
- package/templates/extension-template/src/types.ts +7 -0
- package/templates/extension-template/tsconfig.json +8 -0
- package/templates/extension-template/tsup.config.ts +40 -0
package/src/metadata.ts
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
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
|
+
license: 'MIT',
|
|
15
|
+
githubUrl: 'https://github.com/markolofsen/django-cfg',
|
|
16
|
+
homepage: 'https://djangocfg.com',
|
|
17
|
+
keywords: ['base', 'utilities', 'cli', 'toolkit', 'helpers', 'hooks'],
|
|
18
|
+
|
|
19
|
+
// Marketplace metadata
|
|
20
|
+
category: 'utilities',
|
|
21
|
+
tags: ['base', 'utilities', 'cli', 'toolkit'],
|
|
22
|
+
features: [
|
|
23
|
+
'Extension registration system',
|
|
24
|
+
'React hooks for pagination and infinite scroll',
|
|
25
|
+
'Environment utilities and helpers',
|
|
26
|
+
'CLI tool for extension management',
|
|
27
|
+
'Type-safe context helpers',
|
|
28
|
+
'Logger utilities',
|
|
29
|
+
],
|
|
30
|
+
npmUrl: `https://www.npmjs.com/package/${packageJson.name}`,
|
|
31
|
+
installCommand: `pnpm add ${packageJson.name}`,
|
|
32
|
+
packagePeerDependencies: packageJson.peerDependencies,
|
|
33
|
+
examples: [
|
|
34
|
+
{
|
|
35
|
+
title: 'Basic Extension Setup',
|
|
36
|
+
description: 'Initialize a new DjangoCFG extension',
|
|
37
|
+
code: `import { createExtension } from '@djangocfg/ext-base';
|
|
38
|
+
|
|
39
|
+
const myExtension = createExtension({
|
|
40
|
+
name: 'my-extension',
|
|
41
|
+
version: '1.0.0',
|
|
42
|
+
register: (app) => {
|
|
43
|
+
console.log('Extension registered!');
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
export default myExtension;`,
|
|
48
|
+
language: 'typescript',
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
title: 'Using Pagination Hook',
|
|
52
|
+
description: 'Implement infinite scroll with usePagination',
|
|
53
|
+
code: `import { usePagination } from '@djangocfg/ext-base';
|
|
54
|
+
|
|
55
|
+
function DataList() {
|
|
56
|
+
const { data, loading, hasMore, loadMore } = usePagination({
|
|
57
|
+
fetchFn: (page) => fetch(\`/api/data?page=\${page}\`),
|
|
58
|
+
pageSize: 20,
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
return (
|
|
62
|
+
<div>
|
|
63
|
+
{data.map(item => <div key={item.id}>{item.name}</div>)}
|
|
64
|
+
{hasMore && <button onClick={loadMore}>Load More</button>}
|
|
65
|
+
</div>
|
|
66
|
+
);
|
|
67
|
+
}`,
|
|
68
|
+
language: 'tsx',
|
|
69
|
+
},
|
|
70
|
+
],
|
|
71
|
+
githubStars: 245,
|
|
72
|
+
};
|
package/src/types/context.ts
CHANGED
|
@@ -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,21 +112,94 @@ export interface ExtensionMetadata {
|
|
|
58
112
|
keywords?: string[];
|
|
59
113
|
|
|
60
114
|
/**
|
|
61
|
-
*
|
|
62
|
-
|
|
115
|
+
* Minimum required DjangoCFG version
|
|
116
|
+
*/
|
|
117
|
+
minVersion?: string;
|
|
118
|
+
|
|
119
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
120
|
+
// Marketplace-specific fields
|
|
121
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Extension category for marketplace organization
|
|
63
125
|
*/
|
|
64
|
-
|
|
126
|
+
category?: ExtensionCategory;
|
|
65
127
|
|
|
66
128
|
/**
|
|
67
|
-
*
|
|
68
|
-
* @example ['payments', 'auth']
|
|
129
|
+
* Tags for search and filtering
|
|
69
130
|
*/
|
|
70
|
-
|
|
131
|
+
tags?: string[];
|
|
71
132
|
|
|
72
133
|
/**
|
|
73
|
-
*
|
|
134
|
+
* List of key features
|
|
74
135
|
*/
|
|
75
|
-
|
|
136
|
+
features?: string[];
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* npm package URL
|
|
140
|
+
* @example 'https://www.npmjs.com/package/@djangocfg/ext-newsletter'
|
|
141
|
+
*/
|
|
142
|
+
npmUrl?: string;
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Marketplace-safe ID (package name with @ and / replaced by -)
|
|
146
|
+
* @example '@djangocfg/ext-newsletter' -> 'djangocfg-ext-newsletter'
|
|
147
|
+
*/
|
|
148
|
+
marketplaceId?: string;
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Marketplace URL
|
|
152
|
+
* @example 'https://hub.djangocfg.com/extensions/djangocfg-ext-newsletter'
|
|
153
|
+
*/
|
|
154
|
+
marketplaceUrl?: string;
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Installation command
|
|
158
|
+
* @example 'pnpm add @djangocfg/ext-newsletter'
|
|
159
|
+
*/
|
|
160
|
+
installCommand?: string;
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Download URL for npm tarball
|
|
164
|
+
* @example 'https://registry.npmjs.org/@djangocfg/ext-newsletter/-/ext-newsletter-1.0.0.tgz'
|
|
165
|
+
*/
|
|
166
|
+
downloadUrl?: string;
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Code examples for documentation
|
|
170
|
+
*/
|
|
171
|
+
examples?: ExtensionExample[];
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* npm package dependencies
|
|
175
|
+
*/
|
|
176
|
+
packageDependencies?: Record<string, string>;
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* npm peer dependencies
|
|
180
|
+
*/
|
|
181
|
+
packagePeerDependencies?: Record<string, string>;
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* npm dev dependencies
|
|
185
|
+
*/
|
|
186
|
+
packageDevDependencies?: Record<string, string>;
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* README content in markdown
|
|
190
|
+
*/
|
|
191
|
+
readme?: string;
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Preview image URL (1200x630 recommended)
|
|
195
|
+
* @example 'https://unpkg.com/@djangocfg/ext-leads@latest/preview.svg'
|
|
196
|
+
*/
|
|
197
|
+
preview?: string;
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* GitHub stars count
|
|
201
|
+
*/
|
|
202
|
+
githubStars?: number;
|
|
76
203
|
}
|
|
77
204
|
|
|
78
205
|
export interface ExtensionProviderProps {
|
|
@@ -0,0 +1,155 @@
|
|
|
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
|
+
dependencies?: Record<string, string>;
|
|
20
|
+
peerDependencies?: Record<string, string>;
|
|
21
|
+
devDependencies?: Record<string, string>;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Manual metadata fields that must be provided
|
|
26
|
+
*/
|
|
27
|
+
export interface ExtensionConfigInput {
|
|
28
|
+
/**
|
|
29
|
+
* Extension short name (e.g., 'leads', 'payments')
|
|
30
|
+
*/
|
|
31
|
+
name: string;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Display name for marketplace
|
|
35
|
+
*/
|
|
36
|
+
displayName: string;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Extension category
|
|
40
|
+
*/
|
|
41
|
+
category: ExtensionMetadata['category'];
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Key features list
|
|
45
|
+
*/
|
|
46
|
+
features: string[];
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Code examples (optional)
|
|
50
|
+
*/
|
|
51
|
+
examples?: ExtensionMetadata['examples'];
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Minimum required DjangoCFG version (optional)
|
|
55
|
+
*/
|
|
56
|
+
minVersion?: string;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* GitHub stars count (optional)
|
|
60
|
+
*/
|
|
61
|
+
githubStars?: number;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Create extension configuration from package.json + manual metadata
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```ts
|
|
69
|
+
* import packageJson from '../package.json';
|
|
70
|
+
* import { createExtensionConfig } from '@djangocfg/ext-base';
|
|
71
|
+
*
|
|
72
|
+
* export const extensionConfig = createExtensionConfig(packageJson, {
|
|
73
|
+
* name: 'leads',
|
|
74
|
+
* displayName: 'Leads & Forms',
|
|
75
|
+
* icon: 'FileText',
|
|
76
|
+
* category: 'forms',
|
|
77
|
+
* features: [
|
|
78
|
+
* 'Contact form components',
|
|
79
|
+
* 'Lead tracking',
|
|
80
|
+
* ],
|
|
81
|
+
* });
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
/**
|
|
85
|
+
* Replace workspace:* with latest in dependencies
|
|
86
|
+
*/
|
|
87
|
+
function replaceWorkspaceDeps(deps?: Record<string, string>): Record<string, string> | undefined {
|
|
88
|
+
if (!deps) return undefined;
|
|
89
|
+
|
|
90
|
+
const result: Record<string, string> = {};
|
|
91
|
+
for (const [key, value] of Object.entries(deps)) {
|
|
92
|
+
result[key] = value === 'workspace:*' ? 'latest' : value;
|
|
93
|
+
}
|
|
94
|
+
return result;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function createExtensionConfig(
|
|
98
|
+
packageJson: PackageJson,
|
|
99
|
+
config: ExtensionConfigInput
|
|
100
|
+
): ExtensionMetadata {
|
|
101
|
+
// Extract author name
|
|
102
|
+
const author = typeof packageJson.author === 'string'
|
|
103
|
+
? packageJson.author
|
|
104
|
+
: packageJson.author?.name || 'Unknown';
|
|
105
|
+
|
|
106
|
+
// Extract repository URL
|
|
107
|
+
const githubUrl = typeof packageJson.repository === 'string'
|
|
108
|
+
? packageJson.repository
|
|
109
|
+
: packageJson.repository?.url;
|
|
110
|
+
|
|
111
|
+
// Generate npm tarball download URL
|
|
112
|
+
// Format: https://registry.npmjs.org/{package}/-/{name-without-scope}-{version}.tgz
|
|
113
|
+
const packageNameWithoutScope = packageJson.name.split('/').pop() || packageJson.name;
|
|
114
|
+
const downloadUrl = `https://registry.npmjs.org/${packageJson.name}/-/${packageNameWithoutScope}-${packageJson.version}.tgz`;
|
|
115
|
+
|
|
116
|
+
// Generate marketplace-safe ID (replace @ and / with -)
|
|
117
|
+
// @djangocfg/ext-newsletter -> djangocfg-ext-newsletter
|
|
118
|
+
// somepackage -> somepackage
|
|
119
|
+
const marketplaceId = packageJson.name.replace('@', '').replace('/', '-');
|
|
120
|
+
|
|
121
|
+
return {
|
|
122
|
+
// From package.json
|
|
123
|
+
name: config.name,
|
|
124
|
+
version: packageJson.version,
|
|
125
|
+
author,
|
|
126
|
+
description: packageJson.description,
|
|
127
|
+
keywords: packageJson.keywords,
|
|
128
|
+
license: packageJson.license,
|
|
129
|
+
homepage: packageJson.homepage,
|
|
130
|
+
githubUrl,
|
|
131
|
+
packageDependencies: replaceWorkspaceDeps(packageJson.dependencies),
|
|
132
|
+
packagePeerDependencies: replaceWorkspaceDeps(packageJson.peerDependencies),
|
|
133
|
+
packageDevDependencies: replaceWorkspaceDeps(packageJson.devDependencies),
|
|
134
|
+
|
|
135
|
+
// From manual config
|
|
136
|
+
displayName: config.displayName,
|
|
137
|
+
category: config.category,
|
|
138
|
+
features: config.features,
|
|
139
|
+
examples: config.examples,
|
|
140
|
+
minVersion: config.minVersion,
|
|
141
|
+
githubStars: config.githubStars,
|
|
142
|
+
|
|
143
|
+
// Auto-generated
|
|
144
|
+
npmUrl: `https://www.npmjs.com/package/${packageJson.name}`,
|
|
145
|
+
marketplaceId,
|
|
146
|
+
// Only generate marketplace URL for official @djangocfg extensions
|
|
147
|
+
marketplaceUrl: packageJson.name.startsWith('@djangocfg/ext-')
|
|
148
|
+
? `https://hub.djangocfg.com/extensions/${marketplaceId}`
|
|
149
|
+
: undefined,
|
|
150
|
+
installCommand: `pnpm add ${packageJson.name}`,
|
|
151
|
+
downloadUrl,
|
|
152
|
+
tags: packageJson.keywords,
|
|
153
|
+
preview: `https://unpkg.com/${packageJson.name}@latest/preview.png`,
|
|
154
|
+
};
|
|
155
|
+
}
|
package/src/utils/index.ts
CHANGED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
__MARKETPLACE_LINK__
|
|
6
|
+
|
|
7
|
+
</div>
|
|
8
|
+
|
|
9
|
+
# __PACKAGE_NAME__
|
|
10
|
+
|
|
11
|
+
__DESCRIPTION__
|
|
12
|
+
|
|
13
|
+
**Part of [DjangoCFG](https://djangocfg.com)** — modern Django framework for production-ready SaaS applications.
|
|
14
|
+
|
|
15
|
+
## Features
|
|
16
|
+
|
|
17
|
+
- Feature 1
|
|
18
|
+
- Feature 2
|
|
19
|
+
- Feature 3
|
|
20
|
+
|
|
21
|
+
## Install
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pnpm add __PACKAGE_NAME__
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Usage
|
|
28
|
+
|
|
29
|
+
### Provider Setup
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
import { __PROVIDER_NAME__ExtensionProvider } from '__PACKAGE_NAME__/hooks';
|
|
33
|
+
|
|
34
|
+
export default function RootLayout({ children }) {
|
|
35
|
+
return (
|
|
36
|
+
<__PROVIDER_NAME__ExtensionProvider>
|
|
37
|
+
{children}
|
|
38
|
+
</__PROVIDER_NAME__ExtensionProvider>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Using Hooks
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
'use client';
|
|
47
|
+
|
|
48
|
+
import { use__PROVIDER_NAME__ } from '__PACKAGE_NAME__/hooks';
|
|
49
|
+
|
|
50
|
+
export function MyComponent() {
|
|
51
|
+
const context = use__PROVIDER_NAME__();
|
|
52
|
+
|
|
53
|
+
return <div>Your component</div>;
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## License
|
|
58
|
+
|
|
59
|
+
MIT
|
|
60
|
+
|
|
61
|
+
## Links
|
|
62
|
+
|
|
63
|
+
- [DjangoCFG Documentation](https://djangocfg.com)
|
|
64
|
+
- [GitHub](https://github.com/markolofsen/django-cfg)
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "__PACKAGE_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://hub.djangocfg.com/extensions/__MARKETPLACE_ID__",
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "https://github.com/markolofsen/django-cfg.git"
|
|
21
|
+
},
|
|
22
|
+
"bugs": {
|
|
23
|
+
"url": "https://github.com/markolofsen/django-cfg/issues"
|
|
24
|
+
},
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"type": "module",
|
|
27
|
+
"main": "./dist/index.cjs",
|
|
28
|
+
"module": "./dist/index.js",
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"exports": {
|
|
31
|
+
".": {
|
|
32
|
+
"types": "./dist/index.d.ts",
|
|
33
|
+
"import": "./dist/index.js",
|
|
34
|
+
"require": "./dist/index.cjs"
|
|
35
|
+
},
|
|
36
|
+
"./hooks": {
|
|
37
|
+
"types": "./dist/hooks.d.ts",
|
|
38
|
+
"import": "./dist/hooks.js",
|
|
39
|
+
"require": "./dist/hooks.cjs"
|
|
40
|
+
},
|
|
41
|
+
"./config": {
|
|
42
|
+
"types": "./dist/config.d.ts",
|
|
43
|
+
"import": "./dist/config.js",
|
|
44
|
+
"require": "./dist/config.cjs"
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"files": [
|
|
48
|
+
"dist",
|
|
49
|
+
"src",
|
|
50
|
+
"preview.png"
|
|
51
|
+
],
|
|
52
|
+
"scripts": {
|
|
53
|
+
"build": "tsup",
|
|
54
|
+
"dev": "tsup --watch",
|
|
55
|
+
"check": "tsc --noEmit"
|
|
56
|
+
},
|
|
57
|
+
"peerDependencies": {
|
|
58
|
+
"@djangocfg/api": "latest",
|
|
59
|
+
"@djangocfg/ext-base": "latest",
|
|
60
|
+
"@djangocfg/ui-core": "latest",
|
|
61
|
+
"@djangocfg/ui-nextjs": "latest",
|
|
62
|
+
"consola": "^3.4.2",
|
|
63
|
+
"lucide-react": "^0.545.0",
|
|
64
|
+
"next": "^15.5.7",
|
|
65
|
+
"react": "^18 || ^19",
|
|
66
|
+
"react-dom": "^18 || ^19",
|
|
67
|
+
"swr": "^2.3.7"
|
|
68
|
+
},
|
|
69
|
+
"devDependencies": {
|
|
70
|
+
"@djangocfg/api": "latest",
|
|
71
|
+
"@djangocfg/ext-base": "latest",
|
|
72
|
+
"@djangocfg/typescript-config": "latest",
|
|
73
|
+
"@types/node": "^24.7.2",
|
|
74
|
+
"@types/react": "^19.0.0",
|
|
75
|
+
"consola": "^3.4.2",
|
|
76
|
+
"swr": "^2.3.7",
|
|
77
|
+
"tsup": "^8.5.0",
|
|
78
|
+
"typescript": "^5.9.3"
|
|
79
|
+
}
|
|
80
|
+
}
|
|
Binary file
|
|
File without changes
|
|
@@ -0,0 +1,34 @@
|
|
|
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
|
+
category: '__CATEGORY__',
|
|
12
|
+
features: [
|
|
13
|
+
'Feature 1',
|
|
14
|
+
'Feature 2',
|
|
15
|
+
'Feature 3',
|
|
16
|
+
],
|
|
17
|
+
minVersion: '2.0.0',
|
|
18
|
+
examples: [
|
|
19
|
+
{
|
|
20
|
+
title: 'Basic Usage',
|
|
21
|
+
description: 'How to use this extension',
|
|
22
|
+
code: `import { __PROVIDER_NAME__ExtensionProvider } from '__PACKAGE_NAME__/hooks';
|
|
23
|
+
|
|
24
|
+
export default function RootLayout({ children }) {
|
|
25
|
+
return (
|
|
26
|
+
<__PROVIDER_NAME__ExtensionProvider>
|
|
27
|
+
{children}
|
|
28
|
+
</__PROVIDER_NAME__ExtensionProvider>
|
|
29
|
+
);
|
|
30
|
+
}`,
|
|
31
|
+
language: 'tsx',
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
});
|
|
@@ -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
|
+
* __PACKAGE_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';
|