@lumerahq/cli 0.10.0 → 0.11.0
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/dist/chunk-CHRKCAIZ.js +155 -0
- package/dist/{chunk-WRAZC6SJ.js → chunk-HIYM7EM2.js} +17 -1
- package/dist/dev-2HVDP3NX.js +155 -0
- package/dist/index.js +166 -14
- package/dist/init-VNJNSU4Q.js +440 -0
- package/dist/{resources-PGBVCS2K.js → resources-GTG3QMVV.js} +2 -4
- package/dist/{run-WIRQDYYX.js → run-47GF5VVS.js} +2 -4
- package/dist/templates-6KMZWOYH.js +194 -0
- package/package.json +1 -1
- package/dist/chunk-2CR762KB.js +0 -18
- package/dist/dev-BHBF4ECH.js +0 -87
- package/dist/init-EDSRR3YM.js +0 -360
- package/templates/default/ARCHITECTURE.md +0 -80
- package/templates/default/CLAUDE.md +0 -238
- package/templates/default/README.md +0 -59
- package/templates/default/biome.json +0 -38
- package/templates/default/gitignore +0 -9
- package/templates/default/index.html +0 -13
- package/templates/default/package.json.hbs +0 -47
- package/templates/default/platform/automations/.gitkeep +0 -0
- package/templates/default/platform/collections/example_items.json +0 -26
- package/templates/default/platform/hooks/.gitkeep +0 -0
- package/templates/default/pyproject.toml.hbs +0 -14
- package/templates/default/scripts/seed-demo.py +0 -35
- package/templates/default/src/components/Sidebar.tsx +0 -82
- package/templates/default/src/components/StatCard.tsx +0 -25
- package/templates/default/src/components/layout.tsx +0 -13
- package/templates/default/src/lib/queries.ts +0 -27
- package/templates/default/src/main.tsx +0 -131
- package/templates/default/src/routes/__root.tsx +0 -10
- package/templates/default/src/routes/index.tsx +0 -88
- package/templates/default/src/routes/settings.tsx +0 -21
- package/templates/default/src/styles.css +0 -44
- package/templates/default/tsconfig.json +0 -23
- package/templates/default/vite.config.ts +0 -28
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
import { type HostPayload, isEmbedded, onInitMessage, postReadyMessage } from '@lumerahq/ui/lib';
|
|
2
|
-
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
3
|
-
import { createHashHistory, createRouter, RouterProvider } from '@tanstack/react-router';
|
|
4
|
-
import { createContext, StrictMode, useEffect, useRef, useState } from 'react';
|
|
5
|
-
import ReactDOM from 'react-dom/client';
|
|
6
|
-
import { Toaster } from 'sonner';
|
|
7
|
-
|
|
8
|
-
import { routeTree } from './routeTree.gen';
|
|
9
|
-
import '@lumerahq/ui/styles.css';
|
|
10
|
-
import './styles.css';
|
|
11
|
-
|
|
12
|
-
const queryClient = new QueryClient({
|
|
13
|
-
defaultOptions: {
|
|
14
|
-
queries: { staleTime: 30_000, retry: 1 },
|
|
15
|
-
},
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
// Use hash history so route persists across iframe refreshes
|
|
19
|
-
const hashHistory = createHashHistory();
|
|
20
|
-
|
|
21
|
-
const router = createRouter({
|
|
22
|
-
routeTree,
|
|
23
|
-
history: hashHistory,
|
|
24
|
-
context: {},
|
|
25
|
-
defaultPreload: 'intent',
|
|
26
|
-
scrollRestoration: true,
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
declare module '@tanstack/react-router' {
|
|
30
|
-
interface Register {
|
|
31
|
-
router: typeof router;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const ROUTE_STORAGE_KEY = '{{projectName}}-route';
|
|
36
|
-
|
|
37
|
-
function RouteRestorer() {
|
|
38
|
-
const isFirstLoad = useRef(true);
|
|
39
|
-
|
|
40
|
-
useEffect(() => {
|
|
41
|
-
if (isFirstLoad.current) {
|
|
42
|
-
isFirstLoad.current = false;
|
|
43
|
-
const savedRoute = localStorage.getItem(ROUTE_STORAGE_KEY);
|
|
44
|
-
if (savedRoute && savedRoute !== '/' && router.state.location.pathname === '/') {
|
|
45
|
-
router.navigate({ to: savedRoute });
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return router.subscribe('onResolved', ({ toLocation }) => {
|
|
50
|
-
localStorage.setItem(ROUTE_STORAGE_KEY, toLocation.pathname);
|
|
51
|
-
});
|
|
52
|
-
}, []);
|
|
53
|
-
|
|
54
|
-
return null;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
type AuthContextValue = {
|
|
58
|
-
company?: { id: string; name?: string; apiName?: string };
|
|
59
|
-
user?: { id: string; name: string; email: string; role?: string };
|
|
60
|
-
sessionToken?: string;
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
export const AuthContext = createContext<AuthContextValue | null>(null);
|
|
64
|
-
|
|
65
|
-
const App = () => {
|
|
66
|
-
const [hostContext, setHostContext] = useState<AuthContextValue | null>(null);
|
|
67
|
-
const [status, setStatus] = useState<'pending' | 'ready' | 'denied'>('pending');
|
|
68
|
-
|
|
69
|
-
useEffect(() => {
|
|
70
|
-
if (typeof window === 'undefined') return;
|
|
71
|
-
|
|
72
|
-
const standaloneDevMode =
|
|
73
|
-
import.meta.env.DEV && !isEmbedded() && !!import.meta.env.VITE_DEV_API_BASE_URL;
|
|
74
|
-
|
|
75
|
-
if (!isEmbedded() && !standaloneDevMode) {
|
|
76
|
-
setStatus('denied');
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const cleanup = onInitMessage((payload?: HostPayload) => {
|
|
81
|
-
setHostContext({
|
|
82
|
-
company: payload?.company,
|
|
83
|
-
user: payload?.user,
|
|
84
|
-
sessionToken: payload?.session?.token,
|
|
85
|
-
});
|
|
86
|
-
setStatus('ready');
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
postReadyMessage();
|
|
90
|
-
return cleanup;
|
|
91
|
-
}, []);
|
|
92
|
-
|
|
93
|
-
if (status === 'pending') {
|
|
94
|
-
return (
|
|
95
|
-
<main className="flex min-h-screen items-center justify-center bg-slate-900 text-white">
|
|
96
|
-
<p>Authenticating...</p>
|
|
97
|
-
</main>
|
|
98
|
-
);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
if (status === 'denied' || !hostContext) {
|
|
102
|
-
return (
|
|
103
|
-
<main className="flex min-h-screen items-center justify-center bg-slate-900 text-white">
|
|
104
|
-
<div className="text-center space-y-4 rounded-xl border border-slate-700/60 bg-slate-800/70 px-8 py-10">
|
|
105
|
-
<p className="text-sm uppercase tracking-widest text-slate-400">Error</p>
|
|
106
|
-
<p className="text-6xl font-semibold">403</p>
|
|
107
|
-
<p className="text-sm text-slate-300">Access Denied</p>
|
|
108
|
-
</div>
|
|
109
|
-
</main>
|
|
110
|
-
);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
return (
|
|
114
|
-
<AuthContext.Provider value={hostContext}>
|
|
115
|
-
<QueryClientProvider client={queryClient}>
|
|
116
|
-
<RouterProvider router={router} />
|
|
117
|
-
<RouteRestorer />
|
|
118
|
-
<Toaster position="top-right" richColors />
|
|
119
|
-
</QueryClientProvider>
|
|
120
|
-
</AuthContext.Provider>
|
|
121
|
-
);
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
const rootElement = document.getElementById('app');
|
|
125
|
-
if (rootElement && !rootElement.innerHTML) {
|
|
126
|
-
ReactDOM.createRoot(rootElement).render(
|
|
127
|
-
<StrictMode>
|
|
128
|
-
<App />
|
|
129
|
-
</StrictMode>
|
|
130
|
-
);
|
|
131
|
-
}
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import { createFileRoute } from '@tanstack/react-router';
|
|
2
|
-
import { Activity, FileText, TrendingUp, Users } from 'lucide-react';
|
|
3
|
-
import { useContext } from 'react';
|
|
4
|
-
import { StatCard } from '../components/StatCard';
|
|
5
|
-
import { AuthContext } from '../main';
|
|
6
|
-
|
|
7
|
-
export const Route = createFileRoute('/')({
|
|
8
|
-
component: HomePage,
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
function HomePage() {
|
|
12
|
-
const auth = useContext(AuthContext);
|
|
13
|
-
|
|
14
|
-
return (
|
|
15
|
-
<div className="space-y-6">
|
|
16
|
-
{/* Header */}
|
|
17
|
-
<div>
|
|
18
|
-
<h1 className="text-2xl font-semibold">Dashboard</h1>
|
|
19
|
-
<p className="text-muted-foreground mt-1">Welcome back, {auth?.user?.name ?? 'User'}</p>
|
|
20
|
-
</div>
|
|
21
|
-
|
|
22
|
-
{/* Stats Grid */}
|
|
23
|
-
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
|
|
24
|
-
<StatCard
|
|
25
|
-
title="Total Users"
|
|
26
|
-
value="1,234"
|
|
27
|
-
subtitle="+12% from last month"
|
|
28
|
-
icon={<Users className="size-5" />}
|
|
29
|
-
/>
|
|
30
|
-
<StatCard
|
|
31
|
-
title="Documents"
|
|
32
|
-
value="856"
|
|
33
|
-
subtitle="23 added today"
|
|
34
|
-
icon={<FileText className="size-5" />}
|
|
35
|
-
/>
|
|
36
|
-
<StatCard
|
|
37
|
-
title="Active Sessions"
|
|
38
|
-
value="42"
|
|
39
|
-
subtitle="Real-time"
|
|
40
|
-
icon={<Activity className="size-5" />}
|
|
41
|
-
/>
|
|
42
|
-
<StatCard
|
|
43
|
-
title="Growth Rate"
|
|
44
|
-
value="+24.5%"
|
|
45
|
-
subtitle="vs last quarter"
|
|
46
|
-
icon={<TrendingUp className="size-5" />}
|
|
47
|
-
/>
|
|
48
|
-
</div>
|
|
49
|
-
|
|
50
|
-
{/* Content Area */}
|
|
51
|
-
<div className="grid gap-6 lg:grid-cols-2">
|
|
52
|
-
<div className="rounded-xl border bg-card p-6">
|
|
53
|
-
<h2 className="font-semibold mb-4">Recent Activity</h2>
|
|
54
|
-
<div className="space-y-3">
|
|
55
|
-
{[1, 2, 3].map((i) => (
|
|
56
|
-
<div key={i} className="flex items-center gap-3 text-sm">
|
|
57
|
-
<div className="size-2 rounded-full bg-primary" />
|
|
58
|
-
<span className="text-muted-foreground">Activity item {i}</span>
|
|
59
|
-
<span className="ml-auto text-xs text-muted-foreground">2h ago</span>
|
|
60
|
-
</div>
|
|
61
|
-
))}
|
|
62
|
-
</div>
|
|
63
|
-
<p className="text-sm text-muted-foreground mt-4 pt-4 border-t">
|
|
64
|
-
Replace with your actual activity data
|
|
65
|
-
</p>
|
|
66
|
-
</div>
|
|
67
|
-
|
|
68
|
-
<div className="rounded-xl border bg-card p-6">
|
|
69
|
-
<h2 className="font-semibold mb-4">Quick Actions</h2>
|
|
70
|
-
<div className="grid grid-cols-2 gap-3">
|
|
71
|
-
{['Create Report', 'Add User', 'View Analytics', 'Settings'].map((action) => (
|
|
72
|
-
<button
|
|
73
|
-
key={action}
|
|
74
|
-
type="button"
|
|
75
|
-
className="p-3 text-sm font-medium rounded-lg border bg-background hover:bg-muted transition-colors text-left"
|
|
76
|
-
>
|
|
77
|
-
{action}
|
|
78
|
-
</button>
|
|
79
|
-
))}
|
|
80
|
-
</div>
|
|
81
|
-
<p className="text-sm text-muted-foreground mt-4 pt-4 border-t">
|
|
82
|
-
Customize these actions for your app
|
|
83
|
-
</p>
|
|
84
|
-
</div>
|
|
85
|
-
</div>
|
|
86
|
-
</div>
|
|
87
|
-
);
|
|
88
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { createFileRoute } from '@tanstack/react-router';
|
|
2
|
-
|
|
3
|
-
export const Route = createFileRoute('/settings')({
|
|
4
|
-
component: SettingsPage,
|
|
5
|
-
});
|
|
6
|
-
|
|
7
|
-
function SettingsPage() {
|
|
8
|
-
return (
|
|
9
|
-
<div className="space-y-6">
|
|
10
|
-
<div>
|
|
11
|
-
<h1 className="text-2xl font-semibold">Settings</h1>
|
|
12
|
-
<p className="text-muted-foreground mt-1">Manage your application settings</p>
|
|
13
|
-
</div>
|
|
14
|
-
|
|
15
|
-
<div className="rounded-xl border bg-card p-6">
|
|
16
|
-
<h2 className="font-semibold mb-4">General</h2>
|
|
17
|
-
<p className="text-sm text-muted-foreground">Add your settings UI here</p>
|
|
18
|
-
</div>
|
|
19
|
-
</div>
|
|
20
|
-
);
|
|
21
|
-
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
@import "tailwindcss";
|
|
2
|
-
|
|
3
|
-
@custom-variant dark (&:is(.dark *));
|
|
4
|
-
|
|
5
|
-
body {
|
|
6
|
-
@apply m-0;
|
|
7
|
-
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
8
|
-
-webkit-font-smoothing: antialiased;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
:root {
|
|
12
|
-
--background: oklch(1 0 0);
|
|
13
|
-
--foreground: oklch(0.141 0.005 285.823);
|
|
14
|
-
--card: oklch(1 0 0);
|
|
15
|
-
--card-foreground: oklch(0.141 0.005 285.823);
|
|
16
|
-
--primary: oklch(0.32 0.05 200);
|
|
17
|
-
--primary-foreground: oklch(0.985 0 0);
|
|
18
|
-
--muted: oklch(0.967 0.001 286.375);
|
|
19
|
-
--muted-foreground: oklch(0.552 0.016 285.938);
|
|
20
|
-
--border: oklch(0.92 0.004 286.32);
|
|
21
|
-
--radius: 0.625rem;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
@theme inline {
|
|
25
|
-
--color-background: var(--background);
|
|
26
|
-
--color-foreground: var(--foreground);
|
|
27
|
-
--color-card: var(--card);
|
|
28
|
-
--color-card-foreground: var(--card-foreground);
|
|
29
|
-
--color-primary: var(--primary);
|
|
30
|
-
--color-primary-foreground: var(--primary-foreground);
|
|
31
|
-
--color-muted: var(--muted);
|
|
32
|
-
--color-muted-foreground: var(--muted-foreground);
|
|
33
|
-
--color-border: var(--border);
|
|
34
|
-
--radius-lg: var(--radius);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
@layer base {
|
|
38
|
-
* {
|
|
39
|
-
@apply border-border;
|
|
40
|
-
}
|
|
41
|
-
body {
|
|
42
|
-
@apply bg-background text-foreground;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"include": ["**/*.ts", "**/*.tsx"],
|
|
3
|
-
"compilerOptions": {
|
|
4
|
-
"target": "ES2022",
|
|
5
|
-
"jsx": "react-jsx",
|
|
6
|
-
"module": "ESNext",
|
|
7
|
-
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
|
8
|
-
"types": ["vite/client"],
|
|
9
|
-
"moduleResolution": "bundler",
|
|
10
|
-
"allowImportingTsExtensions": true,
|
|
11
|
-
"verbatimModuleSyntax": true,
|
|
12
|
-
"noEmit": true,
|
|
13
|
-
"skipLibCheck": true,
|
|
14
|
-
"strict": true,
|
|
15
|
-
"noUnusedLocals": true,
|
|
16
|
-
"noUnusedParameters": true,
|
|
17
|
-
"noFallthroughCasesInSwitch": true,
|
|
18
|
-
"baseUrl": ".",
|
|
19
|
-
"paths": {
|
|
20
|
-
"@/*": ["./src/*"]
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import tailwindcss from '@tailwindcss/vite';
|
|
2
|
-
import { tanstackRouter } from '@tanstack/router-plugin/vite';
|
|
3
|
-
import viteReact from '@vitejs/plugin-react';
|
|
4
|
-
import { defineConfig } from 'vite';
|
|
5
|
-
|
|
6
|
-
export default defineConfig({
|
|
7
|
-
base: './', // Use relative paths for S3 hosting at subpaths
|
|
8
|
-
plugins: [
|
|
9
|
-
tanstackRouter({
|
|
10
|
-
target: 'react',
|
|
11
|
-
autoCodeSplitting: true,
|
|
12
|
-
}),
|
|
13
|
-
viteReact(),
|
|
14
|
-
tailwindcss(),
|
|
15
|
-
],
|
|
16
|
-
resolve: {
|
|
17
|
-
alias: {
|
|
18
|
-
'@': new URL('./src', import.meta.url).pathname,
|
|
19
|
-
},
|
|
20
|
-
dedupe: ['react', 'react-dom'],
|
|
21
|
-
},
|
|
22
|
-
server: {
|
|
23
|
-
allowedHosts: [
|
|
24
|
-
'mac.lumerahq.com',
|
|
25
|
-
'untunable-del-nonephemerally.ngrok-free.dev',
|
|
26
|
-
],
|
|
27
|
-
},
|
|
28
|
-
});
|