@djangocfg/ext-base 1.0.3 → 1.0.4

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.
Files changed (40) hide show
  1. package/README.md +134 -8
  2. package/dist/api.cjs +40 -0
  3. package/dist/api.d.cts +35 -0
  4. package/dist/api.d.ts +35 -0
  5. package/dist/api.js +2 -0
  6. package/dist/auth.cjs +10 -0
  7. package/dist/auth.d.cts +1 -0
  8. package/dist/auth.d.ts +1 -0
  9. package/dist/auth.js +2 -0
  10. package/dist/chunk-3RG5ZIWI.js +8 -0
  11. package/dist/chunk-UXTBBEO5.js +237 -0
  12. package/dist/chunk-VJEGYVBV.js +140 -0
  13. package/dist/cli.mjs +530 -0
  14. package/dist/hooks.cjs +437 -0
  15. package/dist/hooks.d.cts +97 -0
  16. package/dist/hooks.d.ts +97 -0
  17. package/dist/hooks.js +95 -0
  18. package/dist/index.cjs +345 -0
  19. package/dist/index.d.cts +363 -0
  20. package/dist/index.d.ts +363 -0
  21. package/dist/index.js +3 -0
  22. package/package.json +3 -1
  23. package/src/cli/index.ts +281 -15
  24. package/src/context/ExtensionProvider.tsx +67 -4
  25. package/src/extensionConfig.ts +77 -28
  26. package/templates/extension-template/README.md.template +30 -0
  27. package/templates/extension-template/package.json.template +2 -1
  28. package/templates/extension-template/playground/.gitignore.template +34 -0
  29. package/templates/extension-template/playground/CLAUDE.md +35 -0
  30. package/templates/extension-template/playground/README.md.template +76 -0
  31. package/templates/extension-template/playground/app/globals.css.template +19 -0
  32. package/templates/extension-template/playground/app/layout.tsx.template +30 -0
  33. package/templates/extension-template/playground/app/page.tsx.template +44 -0
  34. package/templates/extension-template/playground/next.config.ts.template +62 -0
  35. package/templates/extension-template/playground/package.json.template +33 -0
  36. package/templates/extension-template/playground/tsconfig.json.template +27 -0
  37. package/templates/extension-template/src/contexts/__PROVIDER_NAME__Context.tsx +1 -1
  38. package/templates/extension-template/src/contexts/__PROVIDER_NAME__ExtensionProvider.tsx +1 -0
  39. package/templates/extension-template/src/index.ts +12 -4
  40. package/templates/extension-template/src/utils/withSmartProvider.tsx +70 -0
@@ -0,0 +1,34 @@
1
+ # Dependencies
2
+ node_modules/
3
+
4
+ # Next.js
5
+ .next/
6
+ out/
7
+ next-env.d.ts
8
+
9
+ # Build
10
+ dist/
11
+ build/
12
+
13
+ # Environment
14
+ .env
15
+ .env.local
16
+ .env.development.local
17
+ .env.test.local
18
+ .env.production.local
19
+
20
+ # Logs
21
+ npm-debug.log*
22
+ yarn-debug.log*
23
+ yarn-error.log*
24
+ pnpm-debug.log*
25
+
26
+ # IDE
27
+ .vscode/
28
+ .idea/
29
+
30
+ # OS
31
+ .DS_Store
32
+
33
+ # Misc
34
+ .turbo/
@@ -0,0 +1,35 @@
1
+ # DjangoCFG AI Documentation
2
+
3
+ ## MCP Server
4
+
5
+ ```json
6
+ {
7
+ "mcpServers": {
8
+ "djangocfg-docs": {
9
+ "url": "https://mcp.djangocfg.com/mcp"
10
+ }
11
+ }
12
+ }
13
+ ```
14
+
15
+ ## CLI
16
+
17
+ ```bash
18
+ # In this project (uses workspace @djangocfg/nextjs)
19
+ pnpm ai-docs search "database configuration"
20
+ pnpm ai-docs mcp
21
+ ```
22
+
23
+ ## API
24
+
25
+ ```bash
26
+ curl 'https://mcp.djangocfg.com/api/search?q=database&limit=5'
27
+ ```
28
+
29
+ ## TypeScript
30
+
31
+ ```ts
32
+ import { search, getDocs } from '@djangocfg/nextjs/ai';
33
+
34
+ const results = await search('database configuration');
35
+ ```
@@ -0,0 +1,76 @@
1
+ # __DISPLAY_NAME__ - Development Playground
2
+
3
+ This is a Next.js development environment for testing and developing the __DISPLAY_NAME__ extension.
4
+
5
+ ## Quick Start
6
+
7
+ From the extension root directory, run:
8
+
9
+ ```bash
10
+ # Install dependencies (first time only)
11
+ pnpm install
12
+
13
+ # Start the development server
14
+ pnpm dev:playground
15
+ ```
16
+
17
+ The playground will be available at **http://localhost:3333**
18
+
19
+ ## What's Included
20
+
21
+ - **BaseApp Wrapper**: Pre-configured with auth, theme support, and SWR
22
+ - **Hot Module Replacement**: Changes to `src/` files reload automatically
23
+ - **Next.js 15**: Latest App Router with React 19
24
+ - **TypeScript**: Full type safety
25
+
26
+ ## How to Use
27
+
28
+ 1. Open `playground/app/page.tsx`
29
+ 2. Import your extension components
30
+ 3. Add them to the page
31
+ 4. Save and see changes instantly
32
+
33
+ Example:
34
+
35
+ ```tsx
36
+ import { YourComponent } from '__PACKAGE_NAME__';
37
+
38
+ export default function PlaygroundPage() {
39
+ return (
40
+ <BaseApp>
41
+ <__PROVIDER_NAME__Provider>
42
+ <div>
43
+ <YourComponent />
44
+ </div>
45
+ </__PROVIDER_NAME__Provider>
46
+ </BaseApp>
47
+ );
48
+ }
49
+ ```
50
+
51
+ ## Available Features
52
+
53
+ - ✅ Auth context via `useAuth()`
54
+ - ✅ Theme switching (light/dark)
55
+ - ✅ SWR data fetching
56
+ - ✅ Error tracking
57
+ - ✅ TypeScript support
58
+
59
+ ## Troubleshooting
60
+
61
+ **Port 3333 already in use?**
62
+ Edit `playground/package.json` and change the port:
63
+ ```json
64
+ "dev": "next dev --port 3334"
65
+ ```
66
+
67
+ **Module not found?**
68
+ Make sure dependencies are installed:
69
+ ```bash
70
+ pnpm install
71
+ cd playground && pnpm install
72
+ ```
73
+
74
+ ---
75
+
76
+ **[📖 Documentation](https://djangocfg.com/docs)** • **[⭐ GitHub](https://github.com/markolofsen/django-cfg)**
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Global styles for __DISPLAY_NAME__ playground
3
+ * Single entry point for all styles
4
+ *
5
+ * CRITICAL: Import order matters for Tailwind CSS v4!
6
+ * Theme variables MUST come BEFORE @import "tailwindcss"
7
+ */
8
+
9
+ /* 1. Import UI package styles FIRST (contains theme variables) */
10
+ @import "@djangocfg/ui-nextjs/styles";
11
+
12
+ /* 2. Import layouts styles (may contain additional tokens) */
13
+ @import "@djangocfg/layouts/styles";
14
+
15
+ /* 3. Import Tailwind CSS v4 (AFTER theme variables) */
16
+ @import "tailwindcss";
17
+
18
+ /* 4. Load tailwindcss-animate plugin */
19
+ @plugin "tailwindcss-animate";
@@ -0,0 +1,30 @@
1
+ import type { Metadata } from 'next';
2
+ import { Manrope } from 'next/font/google';
3
+ import { BaseApp } from '@djangocfg/layouts';
4
+ import './globals.css';
5
+
6
+ export const metadata: Metadata = {
7
+ title: '__DISPLAY_NAME__ - Development Playground',
8
+ description: 'Development environment for __DISPLAY_NAME__ extension',
9
+ };
10
+
11
+ const manrope = Manrope({
12
+ subsets: ['latin', 'cyrillic'],
13
+ weight: ['400', '500', '600', '700', '800'],
14
+ variable: '--font-manrope',
15
+ display: 'swap',
16
+ });
17
+
18
+ export default function RootLayout({
19
+ children,
20
+ }: Readonly<{
21
+ children: React.ReactNode;
22
+ }>) {
23
+ return (
24
+ <html lang="en" suppressHydrationWarning>
25
+ <body className={manrope.className} style={{ fontFamily: manrope.style.fontFamily }}>
26
+ <BaseApp>{children}</BaseApp>
27
+ </body>
28
+ </html>
29
+ );
30
+ }
@@ -0,0 +1,44 @@
1
+ 'use client';
2
+
3
+ import { __PROVIDER_NAME__Provider } from '__PACKAGE_NAME__';
4
+
5
+ /**
6
+ * Development playground for __DISPLAY_NAME__ extension
7
+ *
8
+ * This page demonstrates how to use the extension in a Next.js application.
9
+ * The extension is wrapped with __PROVIDER_NAME__Provider which provides
10
+ * extension-specific context and state management.
11
+ *
12
+ * BaseApp (from layout.tsx) provides:
13
+ * - Theme support (light/dark mode)
14
+ * - Auth context
15
+ * - SWR configuration
16
+ * - Error tracking
17
+ *
18
+ * To start development:
19
+ * 1. Run `pnpm dev:playground` from the extension root
20
+ * 2. Open http://localhost:3333 in your browser
21
+ * 3. Make changes to src/ files and see them hot-reload
22
+ */
23
+ export default function PlaygroundPage() {
24
+ return (
25
+ <__PROVIDER_NAME__Provider>
26
+ <div style={{ padding: '2rem' }}>
27
+ <h1>__DISPLAY_NAME__ - Development Playground</h1>
28
+ <p>
29
+ This is a development environment for testing the __DISPLAY_NAME__ extension.
30
+ </p>
31
+
32
+ <div style={{ marginTop: '2rem', padding: '1rem', border: '1px solid #ccc', borderRadius: '8px' }}>
33
+ <h2>Add your components here</h2>
34
+ <p>
35
+ Import and render your extension components below to test them.
36
+ </p>
37
+
38
+ {/* TODO: Add your extension components here */}
39
+ {/* Example: <YourComponent /> */}
40
+ </div>
41
+ </div>
42
+ </__PROVIDER_NAME__Provider>
43
+ );
44
+ }
@@ -0,0 +1,62 @@
1
+ import type { NextConfig } from 'next';
2
+ import type { Configuration as WebpackConfig, Compiler } from 'webpack';
3
+
4
+ /**
5
+ * Simple webpack plugin to auto-open browser in dev mode
6
+ */
7
+ class AutoOpenBrowserPlugin {
8
+ private opened = false;
9
+
10
+ apply(compiler: Compiler): void {
11
+ compiler.hooks.done.tap('AutoOpenBrowserPlugin', () => {
12
+ if (!this.opened) {
13
+ this.opened = true;
14
+ this.openBrowser();
15
+ }
16
+ });
17
+ }
18
+
19
+ private openBrowser(): void {
20
+ setTimeout(async () => {
21
+ try {
22
+ const { exec } = await import('child_process');
23
+ const port = process.env.PORT || '3333';
24
+ const url = `http://localhost:${port}`;
25
+
26
+ const command = process.platform === 'darwin'
27
+ ? 'open'
28
+ : process.platform === 'win32'
29
+ ? 'start'
30
+ : 'xdg-open';
31
+
32
+ exec(`${command} ${url}`, (error) => {
33
+ if (error) {
34
+ console.warn(`Failed to open browser: ${error.message}`);
35
+ }
36
+ });
37
+ } catch (error) {
38
+ console.warn('Failed to open browser');
39
+ }
40
+ }, 2000);
41
+ }
42
+ }
43
+
44
+ const nextConfig: NextConfig = {
45
+ reactStrictMode: true,
46
+ transpilePackages: [
47
+ '__PACKAGE_NAME__',
48
+ '@djangocfg/api',
49
+ ],
50
+ webpack: (config: WebpackConfig, { isServer, dev }) => {
51
+ // Auto-open browser in dev mode (client-side only)
52
+ if (dev && !isServer) {
53
+ if (!config.plugins) {
54
+ config.plugins = [];
55
+ }
56
+ config.plugins.push(new AutoOpenBrowserPlugin());
57
+ }
58
+ return config;
59
+ },
60
+ };
61
+
62
+ export default nextConfig;
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "__PACKAGE_NAME__-playground",
3
+ "version": "1.0.0",
4
+ "private": true,
5
+ "description": "Development playground for __DISPLAY_NAME__ extension",
6
+ "scripts": {
7
+ "predev": "cd .. && pnpm build",
8
+ "prebuild": "cd .. && pnpm build",
9
+ "dev": "next dev --port 3333",
10
+ "build": "next build",
11
+ "start": "next start",
12
+ "ai-docs": "pnpm exec djangocfg-docs"
13
+ },
14
+ "dependencies": {
15
+ "__PACKAGE_NAME__": "workspace:*",
16
+ "@djangocfg/layouts": "workspace:*",
17
+ "@djangocfg/ui-core": "workspace:*",
18
+ "@djangocfg/ui-nextjs": "workspace:*",
19
+ "@djangocfg/nextjs": "workspace:*",
20
+ "@djangocfg/api": "workspace:*",
21
+ "next": "15.5.7",
22
+ "react": "19.2.0",
23
+ "react-dom": "19.2.0",
24
+ "tailwindcss": "^4.1.14",
25
+ "tailwindcss-animate": "^1.0.7"
26
+ },
27
+ "devDependencies": {
28
+ "@types/node": "^24.7.2",
29
+ "@types/react": "^19.2.7",
30
+ "@types/react-dom": "^19.2.3",
31
+ "typescript": "^5.9.3"
32
+ }
33
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "lib": ["dom", "dom.iterable", "esnext"],
5
+ "allowJs": true,
6
+ "skipLibCheck": true,
7
+ "strict": true,
8
+ "noEmit": true,
9
+ "esModuleInterop": true,
10
+ "module": "esnext",
11
+ "moduleResolution": "bundler",
12
+ "resolveJsonModule": true,
13
+ "isolatedModules": true,
14
+ "jsx": "preserve",
15
+ "incremental": true,
16
+ "plugins": [
17
+ {
18
+ "name": "next"
19
+ }
20
+ ],
21
+ "paths": {
22
+ "@/*": ["./*"]
23
+ }
24
+ },
25
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
26
+ "exclude": ["node_modules"]
27
+ }
@@ -4,7 +4,7 @@
4
4
  * Main __DISPLAY_NAME__ Context
5
5
  */
6
6
 
7
- import { createContext, useContext, type ReactNode } from 'react';
7
+ import React, { createContext, useContext, type ReactNode } from 'react';
8
8
 
9
9
  interface __PROVIDER_NAME__ContextValue {
10
10
  // Add your context values here
@@ -7,6 +7,7 @@
7
7
  'use client';
8
8
 
9
9
  import type { ReactNode } from 'react';
10
+ import React from 'react';
10
11
  import { ExtensionProvider } from '@djangocfg/ext-base/hooks';
11
12
  import { extensionConfig } from '../config';
12
13
  import { __PROVIDER_NAME__Provider } from './__PROVIDER_NAME__Context';
@@ -1,9 +1,6 @@
1
1
  /**
2
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'
3
+ * Main entry point for __DISPLAY_NAME__ extension
7
4
  */
8
5
 
9
6
  // ============================================================================
@@ -15,3 +12,14 @@ export { extensionConfig } from './config';
15
12
  // Types
16
13
  // ============================================================================
17
14
  export type * from './types';
15
+
16
+ // ============================================================================
17
+ // Context & Providers (Client-side)
18
+ // ============================================================================
19
+ export { __PROVIDER_NAME__ExtensionProvider as __PROVIDER_NAME__Provider } from './contexts/__PROVIDER_NAME__ExtensionProvider';
20
+ export { use__PROVIDER_NAME__, use__PROVIDER_NAME__Optional } from './contexts/__PROVIDER_NAME__Context';
21
+
22
+ // ============================================================================
23
+ // Smart Wrapper Utility
24
+ // ============================================================================
25
+ export { withSmartProvider } from './utils/withSmartProvider';
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Smart Provider Wrapper
3
+ *
4
+ * Automatically wraps components with ExtensionProvider only if needed.
5
+ * If provider already exists in parent tree, reuses it.
6
+ *
7
+ * @example
8
+ * ```tsx
9
+ * // Component is automatically wrapped
10
+ * const SmartComponent = withSmartProvider(MyComponent);
11
+ *
12
+ * // Works standalone
13
+ * <SmartComponent />
14
+ *
15
+ * // Also works with manual provider (shares context)
16
+ * <__PROVIDER_NAME__Provider>
17
+ * <SmartComponent />
18
+ * <SmartComponent />
19
+ * </__PROVIDER_NAME__Provider>
20
+ * ```
21
+ */
22
+
23
+ 'use client';
24
+
25
+ import React, { type ComponentType, type ReactNode } from 'react';
26
+ import { __PROVIDER_NAME__ExtensionProvider } from '../contexts/__PROVIDER_NAME__ExtensionProvider';
27
+ import { use__PROVIDER_NAME__Optional } from '../contexts/__PROVIDER_NAME__Context';
28
+
29
+ /**
30
+ * HOC that wraps a component with smart provider detection
31
+ */
32
+ export function withSmartProvider<P extends object>(
33
+ Component: ComponentType<P>
34
+ ): ComponentType<P> {
35
+ const WrappedComponent = (props: P) => {
36
+ return (
37
+ <SmartProviderWrapper>
38
+ <Component {...props} />
39
+ </SmartProviderWrapper>
40
+ );
41
+ };
42
+
43
+ WrappedComponent.displayName = `withSmartProvider(${Component.displayName || Component.name || 'Component'})`;
44
+
45
+ return WrappedComponent;
46
+ }
47
+
48
+ /**
49
+ * Smart wrapper that only creates provider if not already in tree
50
+ */
51
+ function SmartProviderWrapper({ children }: { children: ReactNode }) {
52
+ const existingContext = use__PROVIDER_NAME__Optional();
53
+
54
+ // Provider already exists higher in tree - just render children
55
+ if (existingContext !== undefined) {
56
+ return <>{children}</>;
57
+ }
58
+
59
+ // No provider found - create one automatically
60
+ return (
61
+ <__PROVIDER_NAME__ExtensionProvider>
62
+ {children}
63
+ </__PROVIDER_NAME__ExtensionProvider>
64
+ );
65
+ }
66
+
67
+ /**
68
+ * Direct component export for manual usage
69
+ */
70
+ export { SmartProviderWrapper };