@emberkit/cli 0.5.2 → 0.6.1-alpha.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/cli.js +44 -10
- package/dist/commands/create.js +10 -21
- package/dist/templates/action/index.js +12 -0
- package/dist/templates/action.js +12 -0
- package/dist/templates/api/api.js +280 -0
- package/dist/templates/apiRoute/index.js +20 -0
- package/dist/templates/apiRoute.js +20 -0
- package/dist/templates/blog/blog.js +358 -0
- package/dist/templates/component/index.js +14 -0
- package/dist/templates/component.js +14 -0
- package/dist/templates/config/index.js +13 -0
- package/dist/templates/config.js +13 -0
- package/dist/templates/context/index.js +21 -0
- package/dist/templates/context.js +21 -0
- package/dist/templates/dashboard/dashboard.js +406 -0
- package/dist/templates/entry/index.js +15 -0
- package/dist/templates/entry.js +15 -0
- package/dist/templates/errorBoundary/index.js +17 -0
- package/dist/templates/errorBoundary.js +17 -0
- package/dist/templates/form/index.js +59 -0
- package/dist/templates/form.js +59 -0
- package/dist/templates/index.js +0 -260
- package/dist/templates/layout/index.js +16 -0
- package/dist/templates/layout.js +16 -0
- package/dist/templates/layoutRoutes/index.js +9 -0
- package/dist/templates/layoutRoutes.js +9 -0
- package/dist/templates/loader/index.js +10 -0
- package/dist/templates/loader.js +10 -0
- package/dist/templates/minimal/minimal.js +89 -0
- package/dist/templates/project-templates/_shared/base.js +139 -0
- package/dist/templates/project-templates/api/api.js +209 -0
- package/dist/templates/project-templates/blog/blog.js +283 -0
- package/dist/templates/project-templates/dashboard/dashboard.js +331 -0
- package/dist/templates/project-templates/minimal/minimal.js +21 -0
- package/dist/templates/project-templates/saas/saas.js +461 -0
- package/dist/templates/project-templates/starter-kit/starter.js +209 -0
- package/dist/templates/project-templates/starter-kit/with-ui.js +365 -0
- package/dist/templates/projects/starter.js +286 -0
- package/dist/templates/projects/with-ui.js +445 -0
- package/dist/templates/projects.js +419 -191
- package/dist/templates/route/index.js +12 -0
- package/dist/templates/route.js +12 -0
- package/dist/templates/saas/saas.js +539 -0
- package/dist/templates/signal/index.js +25 -0
- package/dist/templates/signal.js +25 -0
- package/dist/utils/generator.js +30 -2
- package/package.json +1 -2
package/dist/templates/index.js
CHANGED
|
@@ -1,263 +1,3 @@
|
|
|
1
|
-
export const routeTemplate = `import type { RouteComponent } from '@emberkit/core';
|
|
2
|
-
|
|
3
|
-
const {{name}}: RouteComponent = () => {
|
|
4
|
-
return (
|
|
5
|
-
<div>
|
|
6
|
-
<h1>{{name}}</h1>
|
|
7
|
-
</div>
|
|
8
|
-
);
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export default {{name}};
|
|
12
|
-
`;
|
|
13
|
-
export const componentTemplate = `interface {{name}}Props {
|
|
14
|
-
className?: string;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const {{name}} = ({ className = '' }: {{name}}Props) => {
|
|
18
|
-
return (
|
|
19
|
-
<div className={className}>
|
|
20
|
-
{{name}} component
|
|
21
|
-
</div>
|
|
22
|
-
);
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
export default {{name}};
|
|
26
|
-
`;
|
|
27
|
-
export const layoutTemplate = `import type { RouteComponent } from '@emberkit/core';
|
|
28
|
-
|
|
29
|
-
const {{name}}Layout: RouteComponent = ({ children }) => {
|
|
30
|
-
return (
|
|
31
|
-
<div>
|
|
32
|
-
<header>
|
|
33
|
-
<nav>{{name}} Navigation</nav>
|
|
34
|
-
</header>
|
|
35
|
-
<main>{children}</main>
|
|
36
|
-
<footer>Footer</footer>
|
|
37
|
-
</div>
|
|
38
|
-
);
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
export default {{name}}Layout;
|
|
42
|
-
`;
|
|
43
|
-
export const errorBoundaryTemplate = `import type { RouteComponent } from '@emberkit/core';
|
|
44
|
-
|
|
45
|
-
interface {{name}}ErrorProps {
|
|
46
|
-
error: Error;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const {{name}}Error: RouteComponent<{{name}}ErrorProps> = ({ error }) => {
|
|
50
|
-
return (
|
|
51
|
-
<div className="error-boundary">
|
|
52
|
-
<h2>Something went wrong</h2>
|
|
53
|
-
<p>{error.message}</p>
|
|
54
|
-
</div>
|
|
55
|
-
);
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
export default {{name}}Error;
|
|
59
|
-
`;
|
|
60
|
-
export const loaderTemplate = `import type { LoaderFunction, LoaderResult } from '@emberkit/core';
|
|
61
|
-
|
|
62
|
-
export const loader: LoaderFunction = async ({ params, query, request }) => {
|
|
63
|
-
return {
|
|
64
|
-
data: {
|
|
65
|
-
// Add your data here
|
|
66
|
-
},
|
|
67
|
-
} as LoaderResult<unknown>;
|
|
68
|
-
};
|
|
69
|
-
`;
|
|
70
|
-
export const actionTemplate = `import type { ActionFunction, LoaderResult } from '@emberkit/core';
|
|
71
|
-
|
|
72
|
-
export const action: ActionFunction = async ({ params, request }) => {
|
|
73
|
-
const formData = await request.formData();
|
|
74
|
-
|
|
75
|
-
return {
|
|
76
|
-
data: {
|
|
77
|
-
success: true,
|
|
78
|
-
},
|
|
79
|
-
} as LoaderResult<unknown>;
|
|
80
|
-
};
|
|
81
|
-
`;
|
|
82
|
-
export const apiRouteTemplate = `import type { LoaderFunction, LoaderResult } from '@emberkit/core';
|
|
83
|
-
|
|
84
|
-
export const GET: LoaderFunction = async ({ params, query, request }) => {
|
|
85
|
-
return {
|
|
86
|
-
data: {
|
|
87
|
-
message: 'Hello from API',
|
|
88
|
-
},
|
|
89
|
-
} as LoaderResult<unknown>;
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
export const POST: LoaderFunction = async ({ request }) => {
|
|
93
|
-
const body = await request.json();
|
|
94
|
-
|
|
95
|
-
return {
|
|
96
|
-
data: {
|
|
97
|
-
received: body,
|
|
98
|
-
},
|
|
99
|
-
} as LoaderResult<unknown>;
|
|
100
|
-
};
|
|
101
|
-
`;
|
|
102
|
-
export const configTemplate = `import { defineConfig } from '@emberkit/core';
|
|
103
|
-
|
|
104
|
-
export default defineConfig({
|
|
105
|
-
mode: 'hybrid',
|
|
106
|
-
server: {
|
|
107
|
-
port: 3000,
|
|
108
|
-
},
|
|
109
|
-
build: {
|
|
110
|
-
outDir: 'dist',
|
|
111
|
-
target: 'esnext',
|
|
112
|
-
},
|
|
113
|
-
});
|
|
114
|
-
`;
|
|
115
|
-
export const indexTemplate = `import { render } from '@emberkit/core';
|
|
116
|
-
import { routes } from 'virtual:emberkit-routes';
|
|
117
|
-
import App from './routes/_layout';
|
|
118
|
-
import './styles.css';
|
|
119
|
-
|
|
120
|
-
const root = document.getElementById('app');
|
|
121
|
-
|
|
122
|
-
if (root) {
|
|
123
|
-
try {
|
|
124
|
-
render(App, root, { routes });
|
|
125
|
-
} catch (error) {
|
|
126
|
-
console.error('[entry] Render error:', error);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
`;
|
|
130
|
-
export const layoutRoutesTemplate = `// EmberKit uses file-based routing.
|
|
131
|
-
// Routes are automatically discovered from the src/routes directory.
|
|
132
|
-
// - src/routes/index.tsx → /
|
|
133
|
-
// - src/routes/about.tsx → /about
|
|
134
|
-
// - src/routes/[slug].tsx → /:slug
|
|
135
|
-
// - src/routes/[...rest].tsx → catch-all
|
|
136
|
-
|
|
137
|
-
export {};
|
|
138
|
-
`;
|
|
139
|
-
export const signalTemplate = `import { signal, computed, effect } from '@emberkit/core';
|
|
140
|
-
|
|
141
|
-
// Writable signal
|
|
142
|
-
const count = signal(0);
|
|
143
|
-
|
|
144
|
-
// Computed value
|
|
145
|
-
const doubled = computed(() => count.value * 2);
|
|
146
|
-
|
|
147
|
-
// Side effect
|
|
148
|
-
effect(() => {
|
|
149
|
-
console.log('Count changed to:', count.value);
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
// Update
|
|
153
|
-
count.value++;
|
|
154
|
-
|
|
155
|
-
// Batch updates
|
|
156
|
-
import { batch } from '@emberkit/core';
|
|
157
|
-
|
|
158
|
-
batch(() => {
|
|
159
|
-
count.value = 10;
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
export { count, doubled };
|
|
163
|
-
`;
|
|
164
|
-
export const contextTemplate = `import { createContext, useContext } from '@emberkit/core';
|
|
165
|
-
|
|
166
|
-
interface {{name}}Context {
|
|
167
|
-
// Define your context shape
|
|
168
|
-
value: string;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
const {{name}}Context = createContext<{{name}}Context>({
|
|
172
|
-
value: 'default',
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
// Provider usage:
|
|
176
|
-
// <{{name}}Context.Provider value={{ value: 'hello' }}>
|
|
177
|
-
// {children}
|
|
178
|
-
// </{{name}}Context.Provider>
|
|
179
|
-
|
|
180
|
-
// Consumer usage:
|
|
181
|
-
// const ctx = useContext({{name}}Context);
|
|
182
|
-
|
|
183
|
-
export { {{name}}Context };
|
|
184
|
-
`;
|
|
185
|
-
export const formTemplate = `import { signal } from '@emberkit/core';
|
|
186
|
-
|
|
187
|
-
const {{name}}Form = () => {
|
|
188
|
-
const email = signal('');
|
|
189
|
-
const password = signal('');
|
|
190
|
-
const error = signal<string | null>(null);
|
|
191
|
-
const loading = signal(false);
|
|
192
|
-
|
|
193
|
-
const handleSubmit = async (e: Event) => {
|
|
194
|
-
e.preventDefault();
|
|
195
|
-
error.value = null;
|
|
196
|
-
loading.value = true;
|
|
197
|
-
|
|
198
|
-
try {
|
|
199
|
-
const response = await fetch('/api/auth/login', {
|
|
200
|
-
method: 'POST',
|
|
201
|
-
headers: { 'Content-Type': 'application/json' },
|
|
202
|
-
body: JSON.stringify({
|
|
203
|
-
email: email.value,
|
|
204
|
-
password: password.value,
|
|
205
|
-
}),
|
|
206
|
-
});
|
|
207
|
-
|
|
208
|
-
if (!response.ok) {
|
|
209
|
-
throw new Error('Login failed');
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
// Handle success
|
|
213
|
-
} catch (err) {
|
|
214
|
-
error.value = err instanceof Error ? err.message : 'Unknown error';
|
|
215
|
-
} finally {
|
|
216
|
-
loading.value = false;
|
|
217
|
-
}
|
|
218
|
-
};
|
|
219
|
-
|
|
220
|
-
return (
|
|
221
|
-
<form onSubmit={handleSubmit}>
|
|
222
|
-
<input
|
|
223
|
-
type="email"
|
|
224
|
-
value={email.value}
|
|
225
|
-
onInput={(e) => { email.value = e.currentTarget.value; }}
|
|
226
|
-
placeholder="Email"
|
|
227
|
-
/>
|
|
228
|
-
<input
|
|
229
|
-
type="password"
|
|
230
|
-
value={password.value}
|
|
231
|
-
onInput={(e) => { password.value = e.currentTarget.value; }}
|
|
232
|
-
placeholder="Password"
|
|
233
|
-
/>
|
|
234
|
-
{error.value && <p className="text-red-500">{error.value}</p>}
|
|
235
|
-
<button type="submit" disabled={loading.value}>
|
|
236
|
-
{loading.value ? 'Loading...' : 'Submit'}
|
|
237
|
-
</button>
|
|
238
|
-
</form>
|
|
239
|
-
);
|
|
240
|
-
};
|
|
241
|
-
|
|
242
|
-
export default {{name}}Form;
|
|
243
|
-
`;
|
|
244
|
-
export function getTemplate(type) {
|
|
245
|
-
const templates = {
|
|
246
|
-
route: routeTemplate,
|
|
247
|
-
component: componentTemplate,
|
|
248
|
-
layout: layoutTemplate,
|
|
249
|
-
error: errorBoundaryTemplate,
|
|
250
|
-
loader: loaderTemplate,
|
|
251
|
-
action: actionTemplate,
|
|
252
|
-
api: apiRouteTemplate,
|
|
253
|
-
config: configTemplate,
|
|
254
|
-
index: indexTemplate,
|
|
255
|
-
signal: signalTemplate,
|
|
256
|
-
context: contextTemplate,
|
|
257
|
-
form: formTemplate,
|
|
258
|
-
};
|
|
259
|
-
return templates[type] ?? routeTemplate;
|
|
260
|
-
}
|
|
261
1
|
export function formatTemplate(template, params) {
|
|
262
2
|
let result = template;
|
|
263
3
|
for (const [key, value] of Object.entries(params)) {
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const layoutTemplate = `import type { RouteComponent } from '@emberkit/core';
|
|
2
|
+
|
|
3
|
+
const {{name}}Layout: RouteComponent = ({ children }) => {
|
|
4
|
+
return (
|
|
5
|
+
<div>
|
|
6
|
+
<header>
|
|
7
|
+
<nav>{{name}} Navigation</nav>
|
|
8
|
+
</header>
|
|
9
|
+
<main>{children}</main>
|
|
10
|
+
<footer>Footer</footer>
|
|
11
|
+
</div>
|
|
12
|
+
);
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export default {{name}}Layout;
|
|
16
|
+
`;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const layoutTemplate = `import type { RouteComponent } from '@emberkit/core';
|
|
2
|
+
|
|
3
|
+
const {{name}}Layout: RouteComponent = ({ children }) => {
|
|
4
|
+
return (
|
|
5
|
+
<div>
|
|
6
|
+
<header>
|
|
7
|
+
<nav>{{name}} Navigation</nav>
|
|
8
|
+
</header>
|
|
9
|
+
<main>{children}</main>
|
|
10
|
+
<footer>Footer</footer>
|
|
11
|
+
</div>
|
|
12
|
+
);
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export default {{name}}Layout;
|
|
16
|
+
`;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export const layoutRoutesTemplate = `// EmberKit uses file-based routing.
|
|
2
|
+
// Routes are automatically discovered from the src/routes directory.
|
|
3
|
+
// - src/routes/index.tsx → /
|
|
4
|
+
// - src/routes/about.tsx → /about
|
|
5
|
+
// - src/routes/[slug].tsx → /:slug
|
|
6
|
+
// - src/routes/[...rest].tsx → catch-all
|
|
7
|
+
|
|
8
|
+
export {};
|
|
9
|
+
`;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export const layoutRoutesTemplate = `// EmberKit uses file-based routing.
|
|
2
|
+
// Routes are automatically discovered from the src/routes directory.
|
|
3
|
+
// - src/routes/index.tsx → /
|
|
4
|
+
// - src/routes/about.tsx → /about
|
|
5
|
+
// - src/routes/[slug].tsx → /:slug
|
|
6
|
+
// - src/routes/[...rest].tsx → catch-all
|
|
7
|
+
|
|
8
|
+
export {};
|
|
9
|
+
`;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export const loaderTemplate = `import type { LoaderFunction, LoaderResult } from '@emberkit/core';
|
|
2
|
+
|
|
3
|
+
export const loader: LoaderFunction = async ({ params, query, request }) => {
|
|
4
|
+
return {
|
|
5
|
+
data: {
|
|
6
|
+
// Add your data here
|
|
7
|
+
},
|
|
8
|
+
} as LoaderResult<unknown>;
|
|
9
|
+
};
|
|
10
|
+
`;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export const loaderTemplate = `import type { LoaderFunction, LoaderResult } from '@emberkit/core';
|
|
2
|
+
|
|
3
|
+
export const loader: LoaderFunction = async ({ params, query, request }) => {
|
|
4
|
+
return {
|
|
5
|
+
data: {
|
|
6
|
+
// Add your data here
|
|
7
|
+
},
|
|
8
|
+
} as LoaderResult<unknown>;
|
|
9
|
+
};
|
|
10
|
+
`;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
export const minimalTemplate = {
|
|
2
|
+
"package.json": `{
|
|
3
|
+
"name": "{{name}}",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"private": true,
|
|
6
|
+
"type": "module",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"dev": "emberkit dev",
|
|
9
|
+
"build": "emberkit build",
|
|
10
|
+
"preview": "emberkit preview"
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"@emberkit/core": "^0.2.4"
|
|
14
|
+
},
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"@emberkit/cli": "^0.2.4",
|
|
17
|
+
"typescript": "^5.7.0",
|
|
18
|
+
"vite": "^6.0.0"
|
|
19
|
+
}
|
|
20
|
+
}`,
|
|
21
|
+
"tsconfig.json": `{
|
|
22
|
+
"compilerOptions": {
|
|
23
|
+
"target": "ES2022",
|
|
24
|
+
"module": "ESNext",
|
|
25
|
+
"moduleResolution": "bundler",
|
|
26
|
+
"jsx": "react-jsx",
|
|
27
|
+
"jsxImportSource": "@emberkit/core",
|
|
28
|
+
"strict": true,
|
|
29
|
+
"esModuleInterop": true,
|
|
30
|
+
"skipLibCheck": true,
|
|
31
|
+
"forceConsistentCasingInFileNames": true,
|
|
32
|
+
"resolveJsonModule": true,
|
|
33
|
+
"isolatedModules": true,
|
|
34
|
+
"noEmit": true,
|
|
35
|
+
"lib": ["ES2022", "DOM", "DOM.Iterable"]
|
|
36
|
+
},
|
|
37
|
+
"include": ["src"],
|
|
38
|
+
"exclude": ["node_modules", "dist"]
|
|
39
|
+
}`,
|
|
40
|
+
"vite.config.ts": `import { defineConfig } from 'vite';
|
|
41
|
+
import { emberkitVitePlugin } from '@emberkit/core/vite-plugin';
|
|
42
|
+
|
|
43
|
+
export default defineConfig({
|
|
44
|
+
plugins: [emberkitVitePlugin()],
|
|
45
|
+
server: {
|
|
46
|
+
port: 3000,
|
|
47
|
+
host: 'localhost',
|
|
48
|
+
},
|
|
49
|
+
esbuild: {
|
|
50
|
+
jsxImportSource: '@emberkit/core',
|
|
51
|
+
},
|
|
52
|
+
});`,
|
|
53
|
+
"index.html": `<!DOCTYPE html>
|
|
54
|
+
<html lang="en">
|
|
55
|
+
<head>
|
|
56
|
+
<meta charset="UTF-8">
|
|
57
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
58
|
+
<title>{{name}}</title>
|
|
59
|
+
</head>
|
|
60
|
+
<body id="app">
|
|
61
|
+
<script type="module" src="/src/index.tsx"></script>
|
|
62
|
+
</body>
|
|
63
|
+
</html>`,
|
|
64
|
+
"src/index.tsx": `import { render } from '@emberkit/core';
|
|
65
|
+
import { routes } from 'virtual:emberkit-routes';
|
|
66
|
+
import App from './routes/index';
|
|
67
|
+
|
|
68
|
+
const root = document.getElementById('app');
|
|
69
|
+
|
|
70
|
+
if (root) {
|
|
71
|
+
try {
|
|
72
|
+
render(App, root, { routes });
|
|
73
|
+
} catch (error) {
|
|
74
|
+
console.error('[entry] Render error:', error);
|
|
75
|
+
}
|
|
76
|
+
}`,
|
|
77
|
+
"src/routes/index.tsx": `import type { RouteComponent } from '@emberkit/core';
|
|
78
|
+
|
|
79
|
+
const Home: RouteComponent = () => {
|
|
80
|
+
return (
|
|
81
|
+
<div style={{ fontFamily: 'system-ui, sans-serif', maxWidth: '600px', margin: '2rem auto', padding: '0 1rem' }}>
|
|
82
|
+
<h1>{{name}}</h1>
|
|
83
|
+
<p>Built with EmberKit</p>
|
|
84
|
+
</div>
|
|
85
|
+
);
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
export default Home;`,
|
|
89
|
+
};
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared builders for project template boilerplate.
|
|
3
|
+
* Each template composes from these instead of duplicating identical config files.
|
|
4
|
+
*/
|
|
5
|
+
export function buildPackageJson(options = {}) {
|
|
6
|
+
const { hasTailwind = false, hasUI = false } = options;
|
|
7
|
+
const deps = { "@emberkit/core": "^0.2.4" };
|
|
8
|
+
if (hasUI)
|
|
9
|
+
deps["@emberkit/ui"] = "^0.2.3";
|
|
10
|
+
const devDeps = {
|
|
11
|
+
"@emberkit/cli": "^0.2.4",
|
|
12
|
+
typescript: "^5.7.0",
|
|
13
|
+
vite: "^6.0.0",
|
|
14
|
+
};
|
|
15
|
+
if (hasTailwind) {
|
|
16
|
+
devDeps["tailwindcss"] = "^4.0.0";
|
|
17
|
+
devDeps["@tailwindcss/vite"] = "^4.0.0";
|
|
18
|
+
}
|
|
19
|
+
return JSON.stringify({
|
|
20
|
+
name: "{{name}}",
|
|
21
|
+
version: "0.1.0",
|
|
22
|
+
private: true,
|
|
23
|
+
type: "module",
|
|
24
|
+
scripts: {
|
|
25
|
+
dev: "emberkit dev",
|
|
26
|
+
build: "emberkit build",
|
|
27
|
+
preview: "emberkit preview",
|
|
28
|
+
lint: "eslint src --ext .ts,.tsx",
|
|
29
|
+
format: 'prettier --write "src/**/*.{ts,tsx}"',
|
|
30
|
+
},
|
|
31
|
+
dependencies: deps,
|
|
32
|
+
devDependencies: devDeps,
|
|
33
|
+
}, null, 2);
|
|
34
|
+
}
|
|
35
|
+
export function buildTsConfig(hasPaths = true) {
|
|
36
|
+
const pathsEntry = hasPaths
|
|
37
|
+
? `,
|
|
38
|
+
"paths": {
|
|
39
|
+
"@/*": ["./src/*"]
|
|
40
|
+
}`
|
|
41
|
+
: "";
|
|
42
|
+
return `{
|
|
43
|
+
"compilerOptions": {
|
|
44
|
+
"target": "ES2022",
|
|
45
|
+
"module": "ESNext",
|
|
46
|
+
"moduleResolution": "bundler",
|
|
47
|
+
"jsx": "react-jsx",
|
|
48
|
+
"jsxImportSource": "@emberkit/core",
|
|
49
|
+
"strict": true,
|
|
50
|
+
"esModuleInterop": true,
|
|
51
|
+
"skipLibCheck": true,
|
|
52
|
+
"forceConsistentCasingInFileNames": true,
|
|
53
|
+
"resolveJsonModule": true,
|
|
54
|
+
"isolatedModules": true,
|
|
55
|
+
"noEmit": true,
|
|
56
|
+
"lib": ["ES2022", "DOM", "DOM.Iterable"]${pathsEntry}
|
|
57
|
+
},
|
|
58
|
+
"include": ["src"],
|
|
59
|
+
"exclude": ["node_modules", "dist"]
|
|
60
|
+
}`;
|
|
61
|
+
}
|
|
62
|
+
export function buildViteConfig(hasTailwind = false) {
|
|
63
|
+
if (hasTailwind) {
|
|
64
|
+
return `import { defineConfig } from 'vite';
|
|
65
|
+
import { emberkitVitePlugin } from '@emberkit/core/vite-plugin';
|
|
66
|
+
import tailwindcss from '@tailwindcss/vite';
|
|
67
|
+
|
|
68
|
+
export default defineConfig({
|
|
69
|
+
plugins: [emberkitVitePlugin(), tailwindcss()],
|
|
70
|
+
server: {
|
|
71
|
+
port: 3000,
|
|
72
|
+
host: 'localhost',
|
|
73
|
+
},
|
|
74
|
+
esbuild: {
|
|
75
|
+
jsxImportSource: '@emberkit/core',
|
|
76
|
+
},
|
|
77
|
+
});`;
|
|
78
|
+
}
|
|
79
|
+
return `import { defineConfig } from 'vite';
|
|
80
|
+
import { emberkitVitePlugin } from '@emberkit/core/vite-plugin';
|
|
81
|
+
|
|
82
|
+
export default defineConfig({
|
|
83
|
+
plugins: [emberkitVitePlugin()],
|
|
84
|
+
server: {
|
|
85
|
+
port: 3000,
|
|
86
|
+
host: 'localhost',
|
|
87
|
+
},
|
|
88
|
+
esbuild: {
|
|
89
|
+
jsxImportSource: '@emberkit/core',
|
|
90
|
+
},
|
|
91
|
+
});`;
|
|
92
|
+
}
|
|
93
|
+
export function buildIndexHtml(options = {}) {
|
|
94
|
+
const { title = "{{name}}", fonts = [] } = options;
|
|
95
|
+
const fontLinks = fonts.length > 0
|
|
96
|
+
? `\n <link rel="preconnect" href="https://fonts.googleapis.com">
|
|
97
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
98
|
+
${fonts.map((href) => ` <link href="${href}" rel="stylesheet">`).join("\n")}`
|
|
99
|
+
: "";
|
|
100
|
+
return `<!DOCTYPE html>
|
|
101
|
+
<html lang="en">
|
|
102
|
+
<head>
|
|
103
|
+
<meta charset="UTF-8">
|
|
104
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
105
|
+
<title>${title}</title>${fontLinks}
|
|
106
|
+
</head>
|
|
107
|
+
<body id="app">
|
|
108
|
+
<script type="module" src="/src/index.tsx"></script>
|
|
109
|
+
</body>
|
|
110
|
+
</html>`;
|
|
111
|
+
}
|
|
112
|
+
export function buildEntryFile(options = {}) {
|
|
113
|
+
const { hasLayout = false, hasCss = false } = options;
|
|
114
|
+
const appImport = hasLayout
|
|
115
|
+
? `import App from './routes/_layout';`
|
|
116
|
+
: `import App from './routes/index';`;
|
|
117
|
+
const cssImport = hasCss ? `\nimport './styles.css';` : "";
|
|
118
|
+
return `import { render } from '@emberkit/core';
|
|
119
|
+
import { routes } from 'virtual:emberkit-routes';
|
|
120
|
+
${appImport}${cssImport}
|
|
121
|
+
|
|
122
|
+
const root = document.getElementById('app');
|
|
123
|
+
|
|
124
|
+
if (root) {
|
|
125
|
+
try {
|
|
126
|
+
render(App, root, { routes });
|
|
127
|
+
} catch (error) {
|
|
128
|
+
console.error('[entry] Render error:', error);
|
|
129
|
+
}
|
|
130
|
+
}`;
|
|
131
|
+
}
|
|
132
|
+
export const GITIGNORE = `node_modules/
|
|
133
|
+
dist/
|
|
134
|
+
.env
|
|
135
|
+
.env.local
|
|
136
|
+
*.local
|
|
137
|
+
.DS_Store
|
|
138
|
+
*.tsbuildinfo
|
|
139
|
+
`;
|