@ahmadubaidillah/cli 1.1.4 → 1.1.5
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/templates/saas/files/package.json +1 -1
- package/package.json +2 -2
- package/dist/templates/templates/ai_wrapper/files/README.md +0 -3
- package/dist/templates/templates/ai_wrapper/files/package.json +0 -16
- package/dist/templates/templates/ai_wrapper/files/src/app.ts +0 -23
- package/dist/templates/templates/ai_wrapper/files/src/modules/prompts/prompts.routes.ts +0 -64
- package/dist/templates/templates/ai_wrapper/files/src/modules/usage/usage.routes.ts +0 -12
- package/dist/templates/templates/ai_wrapper/template.config.json +0 -16
- package/dist/templates/templates/booking/files/README.md +0 -3
- package/dist/templates/templates/booking/files/package.json +0 -16
- package/dist/templates/templates/booking/files/src/app.ts +0 -23
- package/dist/templates/templates/booking/files/src/modules/availability/availability.routes.ts +0 -12
- package/dist/templates/templates/booking/files/src/modules/calendar/calendar.routes.ts +0 -12
- package/dist/templates/templates/booking/template.config.json +0 -17
- package/dist/templates/templates/cms/files/frontend/src/components/editor/Editor.tsx +0 -36
- package/dist/templates/templates/cms/files/package.json +0 -22
- package/dist/templates/templates/cms/files/src/app.ts +0 -23
- package/dist/templates/templates/cms/files/src/modules/media/media.routes.ts +0 -26
- package/dist/templates/templates/cms/files/src/modules/posts/post.routes.ts +0 -33
- package/dist/templates/templates/cms/template.config.json +0 -17
- package/dist/templates/templates/crm/files/README.md +0 -3
- package/dist/templates/templates/crm/files/package.json +0 -16
- package/dist/templates/templates/crm/files/src/app.ts +0 -23
- package/dist/templates/templates/crm/files/src/modules/contacts/contacts.routes.ts +0 -12
- package/dist/templates/templates/crm/files/src/modules/pipelines/pipelines.routes.ts +0 -12
- package/dist/templates/templates/crm/template.config.json +0 -19
- package/dist/templates/templates/finance/files/README.md +0 -3
- package/dist/templates/templates/finance/files/package.json +0 -16
- package/dist/templates/templates/finance/files/src/app.ts +0 -23
- package/dist/templates/templates/finance/files/src/modules/reports/reports.routes.ts +0 -12
- package/dist/templates/templates/finance/files/src/modules/transactions/transactions.routes.ts +0 -12
- package/dist/templates/templates/finance/template.config.json +0 -15
- package/dist/templates/templates/landing/files/README.md +0 -10
- package/dist/templates/templates/landing/files/package.json +0 -17
- package/dist/templates/templates/landing/template.config.json +0 -15
- package/dist/templates/templates/marketplace/files/README.md +0 -3
- package/dist/templates/templates/marketplace/files/package.json +0 -16
- package/dist/templates/templates/marketplace/files/src/app.ts +0 -25
- package/dist/templates/templates/marketplace/files/src/modules/orders/orders.routes.ts +0 -12
- package/dist/templates/templates/marketplace/files/src/modules/products/products.routes.ts +0 -12
- package/dist/templates/templates/marketplace/files/src/modules/vendors/vendors.routes.ts +0 -12
- package/dist/templates/templates/marketplace/template.config.json +0 -25
- package/dist/templates/templates/preact/files/package.json +0 -18
- package/dist/templates/templates/preact/files/src/main.jsx +0 -4
- package/dist/templates/templates/preact/template.config.json +0 -11
- package/dist/templates/templates/saas/files/package.json +0 -24
- package/dist/templates/templates/saas/files/playwright.config.ts +0 -25
- package/dist/templates/templates/saas/files/src/app.ts +0 -32
- package/dist/templates/templates/saas/files/src/core/env.ts +0 -24
- package/dist/templates/templates/saas/files/src/core/errors.ts +0 -39
- package/dist/templates/templates/saas/files/src/modules/users/repositories/user.repository.ts +0 -25
- package/dist/templates/templates/saas/files/src/modules/users/routes/user.routes.ts +0 -33
- package/dist/templates/templates/saas/files/src/modules/users/services/user.service.ts +0 -24
- package/dist/templates/templates/saas/files/src/modules/users/validators/user.validator.ts +0 -17
- package/dist/templates/templates/saas/files/tests/e2e/basic.spec.ts +0 -13
- package/dist/templates/templates/saas/template.config.json +0 -26
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ahmadubaidillah/cli",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.5",
|
|
4
4
|
"description": "The elite modular boilerplate engine for agentic applications.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"devforge-cli": "dist/bin.js"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@ahmadubaidillah/core": "^1.1.
|
|
19
|
+
"@ahmadubaidillah/core": "^1.1.5",
|
|
20
20
|
"@inquirer/prompts": "latest",
|
|
21
21
|
"chalk": "latest",
|
|
22
22
|
"commander": "latest",
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "{{PROJECT_NAME}}-ai_wrapper",
|
|
3
|
-
"version": "1.0.0",
|
|
4
|
-
"type": "module",
|
|
5
|
-
"scripts": {
|
|
6
|
-
"dev": "bun run --hot src/app.ts",
|
|
7
|
-
"start": "bun run src/app.ts",
|
|
8
|
-
"build": "bun build ./src/app.ts --outdir ./dist"
|
|
9
|
-
},
|
|
10
|
-
"dependencies": {
|
|
11
|
-
"hono": "latest",
|
|
12
|
-
"zod": "latest",
|
|
13
|
-
"drizzle-orm": "latest",
|
|
14
|
-
"postgres": "latest"
|
|
15
|
-
}
|
|
16
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { Hono } from 'hono';
|
|
2
|
-
import { logger } from 'hono/logger';
|
|
3
|
-
import { promptsRoutes } from './modules/prompts/prompts.routes';
|
|
4
|
-
import { usageRoutes } from './modules/usage/usage.routes';
|
|
5
|
-
|
|
6
|
-
const app = new Hono();
|
|
7
|
-
|
|
8
|
-
app.use('*', logger());
|
|
9
|
-
|
|
10
|
-
app.get('/', (c) => {
|
|
11
|
-
return c.json({
|
|
12
|
-
message: 'Welcome to {{PROJECT_NAME}} AI_WRAPPER - Powered by DevForge',
|
|
13
|
-
status: 'running'
|
|
14
|
-
});
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
app.route('/prompts', promptsRoutes);
|
|
18
|
-
app.route('/usage', usageRoutes);
|
|
19
|
-
|
|
20
|
-
export default {
|
|
21
|
-
port: 3000,
|
|
22
|
-
fetch: app.fetch,
|
|
23
|
-
};
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { Hono } from 'hono';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Prompts Routes
|
|
5
|
-
*
|
|
6
|
-
* Handles AI prompt management for the AI Wrapper template.
|
|
7
|
-
*/
|
|
8
|
-
export const promptsRoutes = new Hono();
|
|
9
|
-
|
|
10
|
-
promptsRoutes.get('/', async (c) => {
|
|
11
|
-
try {
|
|
12
|
-
// Fetch logic would be implemented here
|
|
13
|
-
return c.json({
|
|
14
|
-
success: true,
|
|
15
|
-
data: [],
|
|
16
|
-
meta: {
|
|
17
|
-
module: 'prompts',
|
|
18
|
-
timestamp: new Date().toISOString()
|
|
19
|
-
}
|
|
20
|
-
});
|
|
21
|
-
} catch (error: any) {
|
|
22
|
-
return c.json({
|
|
23
|
-
success: false,
|
|
24
|
-
error: 'Failed to retrieve prompts',
|
|
25
|
-
message: error.message
|
|
26
|
-
}, 500);
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
promptsRoutes.post('/', async (c) => {
|
|
31
|
-
let body: any;
|
|
32
|
-
try {
|
|
33
|
-
body = await c.req.json();
|
|
34
|
-
} catch (e: any) {
|
|
35
|
-
return c.json({
|
|
36
|
-
success: false,
|
|
37
|
-
error: 'Malformed JSON',
|
|
38
|
-
message: 'The request body must be valid JSON'
|
|
39
|
-
}, 400);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
try {
|
|
43
|
-
if (!body || typeof body !== 'object' || Object.keys(body).length === 0) {
|
|
44
|
-
return c.json({
|
|
45
|
-
success: false,
|
|
46
|
-
error: 'Invalid Request',
|
|
47
|
-
message: 'Request body must be a non-empty object'
|
|
48
|
-
}, 400);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// Storage logic would be implemented here
|
|
52
|
-
return c.json({
|
|
53
|
-
success: true,
|
|
54
|
-
message: 'Prompt created successfully',
|
|
55
|
-
data: body
|
|
56
|
-
}, 201);
|
|
57
|
-
} catch (error: any) {
|
|
58
|
-
return c.json({
|
|
59
|
-
success: false,
|
|
60
|
-
error: 'Creation Failed',
|
|
61
|
-
message: error.message || 'An unexpected error occurred'
|
|
62
|
-
}, 400);
|
|
63
|
-
}
|
|
64
|
-
});
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { Hono } from 'hono';
|
|
2
|
-
|
|
3
|
-
export const usageRoutes = new Hono();
|
|
4
|
-
|
|
5
|
-
usageRoutes.get('/', (c) => {
|
|
6
|
-
return c.json({ data: [], module: 'usage' });
|
|
7
|
-
});
|
|
8
|
-
|
|
9
|
-
usageRoutes.post('/', async (c) => {
|
|
10
|
-
const body = await c.req.json();
|
|
11
|
-
return c.json({ message: 'usage created', data: body });
|
|
12
|
-
});
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "ai_wrapper",
|
|
3
|
-
"description": "Applications built on top of AI APIs with usage tracking and prompt management.",
|
|
4
|
-
"stack": {
|
|
5
|
-
"runtime": "bun",
|
|
6
|
-
"backend": "hono",
|
|
7
|
-
"frontend": "solidjs",
|
|
8
|
-
"database": "postgres"
|
|
9
|
-
},
|
|
10
|
-
"supportedPlugins": [
|
|
11
|
-
"auth",
|
|
12
|
-
"payment",
|
|
13
|
-
"analytics",
|
|
14
|
-
"github-actions"
|
|
15
|
-
]
|
|
16
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "{{PROJECT_NAME}}-booking",
|
|
3
|
-
"version": "1.0.0",
|
|
4
|
-
"type": "module",
|
|
5
|
-
"scripts": {
|
|
6
|
-
"dev": "bun run --hot src/app.ts",
|
|
7
|
-
"start": "bun run src/app.ts",
|
|
8
|
-
"build": "bun build ./src/app.ts --outdir ./dist"
|
|
9
|
-
},
|
|
10
|
-
"dependencies": {
|
|
11
|
-
"hono": "latest",
|
|
12
|
-
"zod": "latest",
|
|
13
|
-
"drizzle-orm": "latest",
|
|
14
|
-
"postgres": "latest"
|
|
15
|
-
}
|
|
16
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { Hono } from 'hono';
|
|
2
|
-
import { logger } from 'hono/logger';
|
|
3
|
-
import { calendarRoutes } from './modules/calendar/calendar.routes';
|
|
4
|
-
import { availabilityRoutes } from './modules/availability/availability.routes';
|
|
5
|
-
|
|
6
|
-
const app = new Hono();
|
|
7
|
-
|
|
8
|
-
app.use('*', logger());
|
|
9
|
-
|
|
10
|
-
app.get('/', (c) => {
|
|
11
|
-
return c.json({
|
|
12
|
-
message: 'Welcome to {{PROJECT_NAME}} BOOKING - Powered by DevForge',
|
|
13
|
-
status: 'running'
|
|
14
|
-
});
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
app.route('/calendar', calendarRoutes);
|
|
18
|
-
app.route('/availability', availabilityRoutes);
|
|
19
|
-
|
|
20
|
-
export default {
|
|
21
|
-
port: 3000,
|
|
22
|
-
fetch: app.fetch,
|
|
23
|
-
};
|
package/dist/templates/templates/booking/files/src/modules/availability/availability.routes.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { Hono } from 'hono';
|
|
2
|
-
|
|
3
|
-
export const availabilityRoutes = new Hono();
|
|
4
|
-
|
|
5
|
-
availabilityRoutes.get('/', (c) => {
|
|
6
|
-
return c.json({ data: [], module: 'availability' });
|
|
7
|
-
});
|
|
8
|
-
|
|
9
|
-
availabilityRoutes.post('/', async (c) => {
|
|
10
|
-
const body = await c.req.json();
|
|
11
|
-
return c.json({ message: 'availability created', data: body });
|
|
12
|
-
});
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { Hono } from 'hono';
|
|
2
|
-
|
|
3
|
-
export const calendarRoutes = new Hono();
|
|
4
|
-
|
|
5
|
-
calendarRoutes.get('/', (c) => {
|
|
6
|
-
return c.json({ data: [], module: 'calendar' });
|
|
7
|
-
});
|
|
8
|
-
|
|
9
|
-
calendarRoutes.post('/', async (c) => {
|
|
10
|
-
const body = await c.req.json();
|
|
11
|
-
return c.json({ message: 'calendar created', data: body });
|
|
12
|
-
});
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "booking",
|
|
3
|
-
"description": "Calendar and scheduling platform with availability rules.",
|
|
4
|
-
"stack": {
|
|
5
|
-
"runtime": "bun",
|
|
6
|
-
"backend": "hono",
|
|
7
|
-
"frontend": "solidjs",
|
|
8
|
-
"database": "postgres"
|
|
9
|
-
},
|
|
10
|
-
"supportedPlugins": [
|
|
11
|
-
"auth",
|
|
12
|
-
"email",
|
|
13
|
-
"payment",
|
|
14
|
-
"analytics",
|
|
15
|
-
"github-actions"
|
|
16
|
-
]
|
|
17
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { createSignal, onMount } from 'solid-js';
|
|
2
|
-
import { Editor } from '@tiptap/core';
|
|
3
|
-
import StarterKit from '@tiptap/starter-kit';
|
|
4
|
-
|
|
5
|
-
export function TipTapEditor(props: { initialContent: string; onSave: (content: string) => void }) {
|
|
6
|
-
let editorElement: HTMLDivElement;
|
|
7
|
-
const [editor, setEditor] = createSignal<Editor | null>(null);
|
|
8
|
-
|
|
9
|
-
onMount(() => {
|
|
10
|
-
const tiptapEditor = new Editor({
|
|
11
|
-
element: editorElement,
|
|
12
|
-
extensions: [StarterKit],
|
|
13
|
-
content: props.initialContent || '<p>Hello World!</p>',
|
|
14
|
-
onUpdate: ({ editor }) => {
|
|
15
|
-
props.onSave(editor.getHTML());
|
|
16
|
-
},
|
|
17
|
-
});
|
|
18
|
-
setEditor(tiptapEditor);
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
return (
|
|
22
|
-
<div class="tiptap-editor-container bg-white p-4 border rounded shadow-sm">
|
|
23
|
-
<div ref={editorElement!} class="prose max-w-none min-h-[300px] focus:outline-none" />
|
|
24
|
-
<button
|
|
25
|
-
class="mt-4 px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 font-semibold transition"
|
|
26
|
-
onClick={() => {
|
|
27
|
-
if (editor()) {
|
|
28
|
-
props.onSave(editor()!.getHTML());
|
|
29
|
-
}
|
|
30
|
-
}}
|
|
31
|
-
>
|
|
32
|
-
Save Post
|
|
33
|
-
</button>
|
|
34
|
-
</div>
|
|
35
|
-
);
|
|
36
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "{{PROJECT_NAME}}",
|
|
3
|
-
"version": "1.0.0",
|
|
4
|
-
"type": "module",
|
|
5
|
-
"scripts": {
|
|
6
|
-
"dev": "bun run --hot src/app.ts",
|
|
7
|
-
"start": "bun run src/app.ts",
|
|
8
|
-
"build": "bun build ./src/app.ts --outdir ./dist"
|
|
9
|
-
},
|
|
10
|
-
"dependencies": {
|
|
11
|
-
"hono": "latest",
|
|
12
|
-
"zod": "latest",
|
|
13
|
-
"drizzle-orm": "latest",
|
|
14
|
-
"postgres": "latest",
|
|
15
|
-
"@tiptap/core": "latest",
|
|
16
|
-
"@tiptap/pm": "latest",
|
|
17
|
-
"@tiptap/starter-kit": "latest"
|
|
18
|
-
},
|
|
19
|
-
"devDependencies": {
|
|
20
|
-
"drizzle-kit": "latest"
|
|
21
|
-
}
|
|
22
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { Hono } from 'hono';
|
|
2
|
-
import { logger } from 'hono/logger';
|
|
3
|
-
import { postRoutes } from './modules/posts/post.routes';
|
|
4
|
-
import { mediaRoutes } from './modules/media/media.routes';
|
|
5
|
-
|
|
6
|
-
const app = new Hono();
|
|
7
|
-
|
|
8
|
-
app.use('*', logger());
|
|
9
|
-
|
|
10
|
-
app.get('/', (c) => {
|
|
11
|
-
return c.json({
|
|
12
|
-
message: 'Welcome to {{PROJECT_NAME}} CMS - Powered by DevForge',
|
|
13
|
-
status: 'running'
|
|
14
|
-
});
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
app.route('/posts', postRoutes);
|
|
18
|
-
app.route('/media', mediaRoutes);
|
|
19
|
-
|
|
20
|
-
export default {
|
|
21
|
-
port: 3000,
|
|
22
|
-
fetch: app.fetch,
|
|
23
|
-
};
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { Hono } from 'hono';
|
|
2
|
-
|
|
3
|
-
export const mediaRoutes = new Hono();
|
|
4
|
-
|
|
5
|
-
// List all media
|
|
6
|
-
mediaRoutes.get('/', (c) => {
|
|
7
|
-
return c.json({ media: [] });
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
// Upload media
|
|
11
|
-
mediaRoutes.post('/upload', async (c) => {
|
|
12
|
-
const body = await c.req.parseBody();
|
|
13
|
-
const file = body['file'];
|
|
14
|
-
|
|
15
|
-
if (!file) {
|
|
16
|
-
return c.json({ error: 'File is required' }, 400);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
return c.json({ message: 'Media uploaded', filename: file });
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
// Delete media
|
|
23
|
-
mediaRoutes.delete('/:id', (c) => {
|
|
24
|
-
const id = c.req.param('id');
|
|
25
|
-
return c.json({ message: 'Media deleted', id });
|
|
26
|
-
});
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { Hono } from 'hono';
|
|
2
|
-
|
|
3
|
-
export const postRoutes = new Hono();
|
|
4
|
-
|
|
5
|
-
// List all posts
|
|
6
|
-
postRoutes.get('/', (c) => {
|
|
7
|
-
return c.json({ posts: [] });
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
// Create a new post
|
|
11
|
-
postRoutes.post('/', async (c) => {
|
|
12
|
-
const body = await c.req.json();
|
|
13
|
-
return c.json({ message: 'Post created', data: body });
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
// Get a single post by ID
|
|
17
|
-
postRoutes.get('/:id', (c) => {
|
|
18
|
-
const id = c.req.param('id');
|
|
19
|
-
return c.json({ id, title: 'Sample Post', content: '<p>Sample Content</p>' });
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
// Update a post
|
|
23
|
-
postRoutes.put('/:id', async (c) => {
|
|
24
|
-
const id = c.req.param('id');
|
|
25
|
-
const body = await c.req.json();
|
|
26
|
-
return c.json({ message: 'Post updated', id, data: body });
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
// Delete a post
|
|
30
|
-
postRoutes.delete('/:id', (c) => {
|
|
31
|
-
const id = c.req.param('id');
|
|
32
|
-
return c.json({ message: 'Post deleted', id });
|
|
33
|
-
});
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "cms",
|
|
3
|
-
"description": "Content Management System with TipTap editor, media library, and post management.",
|
|
4
|
-
"stack": {
|
|
5
|
-
"runtime": "bun",
|
|
6
|
-
"backend": "hono",
|
|
7
|
-
"frontend": "solidjs",
|
|
8
|
-
"database": "postgres"
|
|
9
|
-
},
|
|
10
|
-
"supportedPlugins": [
|
|
11
|
-
"auth",
|
|
12
|
-
"email",
|
|
13
|
-
"analytics",
|
|
14
|
-
"file-upload",
|
|
15
|
-
"github-actions"
|
|
16
|
-
]
|
|
17
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "{{PROJECT_NAME}}-crm",
|
|
3
|
-
"version": "1.0.0",
|
|
4
|
-
"type": "module",
|
|
5
|
-
"scripts": {
|
|
6
|
-
"dev": "bun run --hot src/app.ts",
|
|
7
|
-
"start": "bun run src/app.ts",
|
|
8
|
-
"build": "bun build ./src/app.ts --outdir ./dist"
|
|
9
|
-
},
|
|
10
|
-
"dependencies": {
|
|
11
|
-
"hono": "latest",
|
|
12
|
-
"zod": "latest",
|
|
13
|
-
"drizzle-orm": "latest",
|
|
14
|
-
"postgres": "latest"
|
|
15
|
-
}
|
|
16
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { Hono } from 'hono';
|
|
2
|
-
import { logger } from 'hono/logger';
|
|
3
|
-
import { contactsRoutes } from './modules/contacts/contacts.routes';
|
|
4
|
-
import { pipelinesRoutes } from './modules/pipelines/pipelines.routes';
|
|
5
|
-
|
|
6
|
-
const app = new Hono();
|
|
7
|
-
|
|
8
|
-
app.use('*', logger());
|
|
9
|
-
|
|
10
|
-
app.get('/', (c) => {
|
|
11
|
-
return c.json({
|
|
12
|
-
message: 'Welcome to {{PROJECT_NAME}} CRM - Powered by DevForge',
|
|
13
|
-
status: 'running'
|
|
14
|
-
});
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
app.route('/contacts', contactsRoutes);
|
|
18
|
-
app.route('/pipelines', pipelinesRoutes);
|
|
19
|
-
|
|
20
|
-
export default {
|
|
21
|
-
port: 3000,
|
|
22
|
-
fetch: app.fetch,
|
|
23
|
-
};
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { Hono } from 'hono';
|
|
2
|
-
|
|
3
|
-
export const contactsRoutes = new Hono();
|
|
4
|
-
|
|
5
|
-
contactsRoutes.get('/', (c) => {
|
|
6
|
-
return c.json({ data: [], module: 'contacts' });
|
|
7
|
-
});
|
|
8
|
-
|
|
9
|
-
contactsRoutes.post('/', async (c) => {
|
|
10
|
-
const body = await c.req.json();
|
|
11
|
-
return c.json({ message: 'contacts created', data: body });
|
|
12
|
-
});
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { Hono } from 'hono';
|
|
2
|
-
|
|
3
|
-
export const pipelinesRoutes = new Hono();
|
|
4
|
-
|
|
5
|
-
pipelinesRoutes.get('/', (c) => {
|
|
6
|
-
return c.json({ data: [], module: 'pipelines' });
|
|
7
|
-
});
|
|
8
|
-
|
|
9
|
-
pipelinesRoutes.post('/', async (c) => {
|
|
10
|
-
const body = await c.req.json();
|
|
11
|
-
return c.json({ message: 'pipelines created', data: body });
|
|
12
|
-
});
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "crm",
|
|
3
|
-
"description": "Customer Relationship Management system for leads and pipelines.",
|
|
4
|
-
"stack": {
|
|
5
|
-
"runtime": "bun",
|
|
6
|
-
"backend": "hono",
|
|
7
|
-
"frontend": "solidjs",
|
|
8
|
-
"database": "postgres"
|
|
9
|
-
},
|
|
10
|
-
"supportedPlugins": [
|
|
11
|
-
"openapi",
|
|
12
|
-
"websocket",
|
|
13
|
-
"queue",
|
|
14
|
-
"auth",
|
|
15
|
-
"email",
|
|
16
|
-
"analytics",
|
|
17
|
-
"github-actions"
|
|
18
|
-
]
|
|
19
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "{{PROJECT_NAME}}-finance",
|
|
3
|
-
"version": "1.0.0",
|
|
4
|
-
"type": "module",
|
|
5
|
-
"scripts": {
|
|
6
|
-
"dev": "bun run --hot src/app.ts",
|
|
7
|
-
"start": "bun run src/app.ts",
|
|
8
|
-
"build": "bun build ./src/app.ts --outdir ./dist"
|
|
9
|
-
},
|
|
10
|
-
"dependencies": {
|
|
11
|
-
"hono": "latest",
|
|
12
|
-
"zod": "latest",
|
|
13
|
-
"drizzle-orm": "latest",
|
|
14
|
-
"postgres": "latest"
|
|
15
|
-
}
|
|
16
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { Hono } from 'hono';
|
|
2
|
-
import { logger } from 'hono/logger';
|
|
3
|
-
import { transactionsRoutes } from './modules/transactions/transactions.routes';
|
|
4
|
-
import { reportsRoutes } from './modules/reports/reports.routes';
|
|
5
|
-
|
|
6
|
-
const app = new Hono();
|
|
7
|
-
|
|
8
|
-
app.use('*', logger());
|
|
9
|
-
|
|
10
|
-
app.get('/', (c) => {
|
|
11
|
-
return c.json({
|
|
12
|
-
message: 'Welcome to {{PROJECT_NAME}} FINANCE - Powered by DevForge',
|
|
13
|
-
status: 'running'
|
|
14
|
-
});
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
app.route('/transactions', transactionsRoutes);
|
|
18
|
-
app.route('/reports', reportsRoutes);
|
|
19
|
-
|
|
20
|
-
export default {
|
|
21
|
-
port: 3000,
|
|
22
|
-
fetch: app.fetch,
|
|
23
|
-
};
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { Hono } from 'hono';
|
|
2
|
-
|
|
3
|
-
export const reportsRoutes = new Hono();
|
|
4
|
-
|
|
5
|
-
reportsRoutes.get('/', (c) => {
|
|
6
|
-
return c.json({ data: [], module: 'reports' });
|
|
7
|
-
});
|
|
8
|
-
|
|
9
|
-
reportsRoutes.post('/', async (c) => {
|
|
10
|
-
const body = await c.req.json();
|
|
11
|
-
return c.json({ message: 'reports created', data: body });
|
|
12
|
-
});
|
package/dist/templates/templates/finance/files/src/modules/transactions/transactions.routes.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { Hono } from 'hono';
|
|
2
|
-
|
|
3
|
-
export const transactionsRoutes = new Hono();
|
|
4
|
-
|
|
5
|
-
transactionsRoutes.get('/', (c) => {
|
|
6
|
-
return c.json({ data: [], module: 'transactions' });
|
|
7
|
-
});
|
|
8
|
-
|
|
9
|
-
transactionsRoutes.post('/', async (c) => {
|
|
10
|
-
const body = await c.req.json();
|
|
11
|
-
return c.json({ message: 'transactions created', data: body });
|
|
12
|
-
});
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "finance",
|
|
3
|
-
"description": "Expense tracker and finance dashboard.",
|
|
4
|
-
"stack": {
|
|
5
|
-
"runtime": "bun",
|
|
6
|
-
"backend": "hono",
|
|
7
|
-
"frontend": "solidjs",
|
|
8
|
-
"database": "postgres"
|
|
9
|
-
},
|
|
10
|
-
"supportedPlugins": [
|
|
11
|
-
"auth",
|
|
12
|
-
"analytics",
|
|
13
|
-
"github-actions"
|
|
14
|
-
]
|
|
15
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "{{PROJECT_NAME}}",
|
|
3
|
-
"version": "1.0.0",
|
|
4
|
-
"scripts": {
|
|
5
|
-
"dev": "astro dev",
|
|
6
|
-
"start": "astro dev",
|
|
7
|
-
"build": "astro build",
|
|
8
|
-
"preview": "astro preview",
|
|
9
|
-
"astro": "astro"
|
|
10
|
-
},
|
|
11
|
-
"dependencies": {
|
|
12
|
-
"astro": "latest",
|
|
13
|
-
"@astrojs/tailwind": "latest",
|
|
14
|
-
"tailwindcss": "latest",
|
|
15
|
-
"alpinejs": "latest"
|
|
16
|
-
}
|
|
17
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "landing",
|
|
3
|
-
"description": "Marketing websites and product landing pages",
|
|
4
|
-
"stack": {
|
|
5
|
-
"runtime": "bun",
|
|
6
|
-
"frontend": "astro",
|
|
7
|
-
"css": "tailwindcss",
|
|
8
|
-
"interactivity": "alpinejs"
|
|
9
|
-
},
|
|
10
|
-
"supportedPlugins": [
|
|
11
|
-
"analytics",
|
|
12
|
-
"email",
|
|
13
|
-
"github-actions"
|
|
14
|
-
]
|
|
15
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "{{PROJECT_NAME}}-marketplace",
|
|
3
|
-
"version": "1.0.0",
|
|
4
|
-
"type": "module",
|
|
5
|
-
"scripts": {
|
|
6
|
-
"dev": "bun run --hot src/app.ts",
|
|
7
|
-
"start": "bun run src/app.ts",
|
|
8
|
-
"build": "bun build ./src/app.ts --outdir ./dist"
|
|
9
|
-
},
|
|
10
|
-
"dependencies": {
|
|
11
|
-
"hono": "latest",
|
|
12
|
-
"zod": "latest",
|
|
13
|
-
"drizzle-orm": "latest",
|
|
14
|
-
"postgres": "latest"
|
|
15
|
-
}
|
|
16
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { Hono } from 'hono';
|
|
2
|
-
import { logger } from 'hono/logger';
|
|
3
|
-
import { productsRoutes } from './modules/products/products.routes';
|
|
4
|
-
import { ordersRoutes } from './modules/orders/orders.routes';
|
|
5
|
-
import { vendorsRoutes } from './modules/vendors/vendors.routes';
|
|
6
|
-
|
|
7
|
-
const app = new Hono();
|
|
8
|
-
|
|
9
|
-
app.use('*', logger());
|
|
10
|
-
|
|
11
|
-
app.get('/', (c) => {
|
|
12
|
-
return c.json({
|
|
13
|
-
message: 'Welcome to {{PROJECT_NAME}} MARKETPLACE - Powered by DevForge',
|
|
14
|
-
status: 'running'
|
|
15
|
-
});
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
app.route('/products', productsRoutes);
|
|
19
|
-
app.route('/orders', ordersRoutes);
|
|
20
|
-
app.route('/vendors', vendorsRoutes);
|
|
21
|
-
|
|
22
|
-
export default {
|
|
23
|
-
port: 3000,
|
|
24
|
-
fetch: app.fetch,
|
|
25
|
-
};
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { Hono } from 'hono';
|
|
2
|
-
|
|
3
|
-
export const ordersRoutes = new Hono();
|
|
4
|
-
|
|
5
|
-
ordersRoutes.get('/', (c) => {
|
|
6
|
-
return c.json({ data: [], module: 'orders' });
|
|
7
|
-
});
|
|
8
|
-
|
|
9
|
-
ordersRoutes.post('/', async (c) => {
|
|
10
|
-
const body = await c.req.json();
|
|
11
|
-
return c.json({ message: 'orders created', data: body });
|
|
12
|
-
});
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { Hono } from 'hono';
|
|
2
|
-
|
|
3
|
-
export const productsRoutes = new Hono();
|
|
4
|
-
|
|
5
|
-
productsRoutes.get('/', (c) => {
|
|
6
|
-
return c.json({ data: [], module: 'products' });
|
|
7
|
-
});
|
|
8
|
-
|
|
9
|
-
productsRoutes.post('/', async (c) => {
|
|
10
|
-
const body = await c.req.json();
|
|
11
|
-
return c.json({ message: 'products created', data: body });
|
|
12
|
-
});
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { Hono } from 'hono';
|
|
2
|
-
|
|
3
|
-
export const vendorsRoutes = new Hono();
|
|
4
|
-
|
|
5
|
-
vendorsRoutes.get('/', (c) => {
|
|
6
|
-
return c.json({ data: [], module: 'vendors' });
|
|
7
|
-
});
|
|
8
|
-
|
|
9
|
-
vendorsRoutes.post('/', async (c) => {
|
|
10
|
-
const body = await c.req.json();
|
|
11
|
-
return c.json({ message: 'vendors created', data: body });
|
|
12
|
-
});
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "marketplace",
|
|
3
|
-
"description": "Multi-vendor ecommerce / digital marketplace platform.",
|
|
4
|
-
"stack": {
|
|
5
|
-
"runtime": "bun",
|
|
6
|
-
"backend": "hono",
|
|
7
|
-
"frontend": "solidjs",
|
|
8
|
-
"database": "postgres"
|
|
9
|
-
},
|
|
10
|
-
"supportedPlugins": [
|
|
11
|
-
"admin-panel",
|
|
12
|
-
"openapi",
|
|
13
|
-
"websocket",
|
|
14
|
-
"queue",
|
|
15
|
-
"openapi",
|
|
16
|
-
"websocket",
|
|
17
|
-
"queue",
|
|
18
|
-
"auth",
|
|
19
|
-
"payment",
|
|
20
|
-
"email",
|
|
21
|
-
"search",
|
|
22
|
-
"file-upload",
|
|
23
|
-
"github-actions"
|
|
24
|
-
]
|
|
25
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "devforge-preact-app",
|
|
3
|
-
"private": true,
|
|
4
|
-
"version": "0.0.0",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"scripts": {
|
|
7
|
-
"dev": "vite",
|
|
8
|
-
"build": "vite build",
|
|
9
|
-
"preview": "vite preview"
|
|
10
|
-
},
|
|
11
|
-
"dependencies": {
|
|
12
|
-
"preact": "latest"
|
|
13
|
-
},
|
|
14
|
-
"devDependencies": {
|
|
15
|
-
"@preact/preset-vite": "latest",
|
|
16
|
-
"vite": "latest"
|
|
17
|
-
}
|
|
18
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "devforge-saas-app",
|
|
3
|
-
"version": "1.0.0",
|
|
4
|
-
"type": "module",
|
|
5
|
-
"scripts": {
|
|
6
|
-
"dev": "bun run --hot src/app.ts",
|
|
7
|
-
"start": "bun run src/app.ts",
|
|
8
|
-
"build": "bun build ./src/app.ts --outdir ./dist",
|
|
9
|
-
"db:push": "drizzle-kit push",
|
|
10
|
-
"db:studio": "drizzle-kit studio",
|
|
11
|
-
"test:e2e": "playwright test"
|
|
12
|
-
},
|
|
13
|
-
"dependencies": {
|
|
14
|
-
"hono": "latest",
|
|
15
|
-
"zod": "latest",
|
|
16
|
-
"drizzle-orm": "latest",
|
|
17
|
-
"postgres": "latest",
|
|
18
|
-
"better-auth": "latest"
|
|
19
|
-
},
|
|
20
|
-
"devDependencies": {
|
|
21
|
-
"drizzle-kit": "latest",
|
|
22
|
-
"@playwright/test": "latest"
|
|
23
|
-
}
|
|
24
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { defineConfig, devices } from '@playwright/test';
|
|
2
|
-
|
|
3
|
-
export default defineConfig({
|
|
4
|
-
testDir: './tests/e2e',
|
|
5
|
-
fullyParallel: true,
|
|
6
|
-
forbidOnly: !!process.env.CI,
|
|
7
|
-
retries: process.env.CI ? 2 : 0,
|
|
8
|
-
workers: process.env.CI ? 1 : undefined,
|
|
9
|
-
reporter: 'html',
|
|
10
|
-
use: {
|
|
11
|
-
baseURL: 'http://localhost:3000',
|
|
12
|
-
trace: 'on-first-retry',
|
|
13
|
-
},
|
|
14
|
-
projects: [
|
|
15
|
-
{
|
|
16
|
-
name: 'chromium',
|
|
17
|
-
use: { ...devices['Desktop Chrome'] },
|
|
18
|
-
},
|
|
19
|
-
],
|
|
20
|
-
webServer: {
|
|
21
|
-
command: 'bun run dev',
|
|
22
|
-
url: 'http://localhost:3000',
|
|
23
|
-
reuseExistingServer: !process.env.CI,
|
|
24
|
-
},
|
|
25
|
-
});
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { Hono } from 'hono';
|
|
2
|
-
import { logger } from 'hono/logger';
|
|
3
|
-
import { cors } from 'hono/cors';
|
|
4
|
-
import { env } from './core/env';
|
|
5
|
-
import { errorHandler } from './core/errors';
|
|
6
|
-
import { userRoutes } from './modules/users/routes/user.routes';
|
|
7
|
-
|
|
8
|
-
const app = new Hono();
|
|
9
|
-
|
|
10
|
-
// Global Middleware
|
|
11
|
-
app.use('*', logger());
|
|
12
|
-
app.use('*', cors());
|
|
13
|
-
|
|
14
|
-
// Health Check
|
|
15
|
-
app.get('/', (c) => {
|
|
16
|
-
return c.json({
|
|
17
|
-
message: 'Welcome to {{PROJECT_NAME}} - Powered by DevForge',
|
|
18
|
-
status: 'running',
|
|
19
|
-
version: '1.0.0'
|
|
20
|
-
});
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
// Feature Routes
|
|
24
|
-
app.route('/api/users', userRoutes);
|
|
25
|
-
|
|
26
|
-
// Error Handling
|
|
27
|
-
app.onError(errorHandler);
|
|
28
|
-
|
|
29
|
-
export default {
|
|
30
|
-
port: parseInt(env.PORT),
|
|
31
|
-
fetch: app.fetch,
|
|
32
|
-
};
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
|
|
3
|
-
const envSchema = z.object({
|
|
4
|
-
DATABASE_URL: z.string().url(),
|
|
5
|
-
BETTER_AUTH_SECRET: z.string().min(32),
|
|
6
|
-
BETTER_AUTH_URL: z.string().url(),
|
|
7
|
-
NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),
|
|
8
|
-
PORT: z.string().default('3000'),
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
export type Env = z.infer<typeof envSchema>;
|
|
12
|
-
|
|
13
|
-
export function validateEnv() {
|
|
14
|
-
const result = envSchema.safeParse(process.env);
|
|
15
|
-
|
|
16
|
-
if (!result.success) {
|
|
17
|
-
console.error('❌ Invalid environment variables:', result.error.format());
|
|
18
|
-
process.exit(1);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
return result.data;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export const env = validateEnv();
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { Context } from 'hono';
|
|
2
|
-
import { HTTPException } from 'hono/http-exception';
|
|
3
|
-
|
|
4
|
-
export class AppError extends Error {
|
|
5
|
-
constructor(
|
|
6
|
-
public message: string,
|
|
7
|
-
public statusCode: number = 400,
|
|
8
|
-
public code?: string
|
|
9
|
-
) {
|
|
10
|
-
super(message);
|
|
11
|
-
this.name = 'AppError';
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export const errorHandler = (err: Error, c: Context) => {
|
|
16
|
-
if (err instanceof AppError) {
|
|
17
|
-
return c.json({
|
|
18
|
-
success: false,
|
|
19
|
-
error: {
|
|
20
|
-
message: err.message,
|
|
21
|
-
code: err.code,
|
|
22
|
-
}
|
|
23
|
-
}, err.statusCode as any);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
if (err instanceof HTTPException) {
|
|
27
|
-
return err.getResponse();
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
console.error('[Unhandled Error]:', err);
|
|
31
|
-
|
|
32
|
-
return c.json({
|
|
33
|
-
success: false,
|
|
34
|
-
error: {
|
|
35
|
-
message: 'Internal Server Error',
|
|
36
|
-
code: 'INTERNAL_ERROR',
|
|
37
|
-
}
|
|
38
|
-
}, 500);
|
|
39
|
-
};
|
package/dist/templates/templates/saas/files/src/modules/users/repositories/user.repository.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { User, CreateUserInput } from '../validators/user.validator';
|
|
2
|
-
|
|
3
|
-
export class UserRepository {
|
|
4
|
-
// In a real app, this would use Drizzle or Prisma
|
|
5
|
-
// For the template, we show the pattern
|
|
6
|
-
|
|
7
|
-
async findById(id: string): Promise<User | null> {
|
|
8
|
-
console.log(`[UserRepository] Finding user by id: ${id}`);
|
|
9
|
-
return null;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
async findByEmail(email: string): Promise<User | null> {
|
|
13
|
-
console.log(`[UserRepository] Finding user by email: ${email}`);
|
|
14
|
-
return null;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
async create(data: CreateUserInput): Promise<User> {
|
|
18
|
-
console.log(`[UserRepository] Creating user:`, data);
|
|
19
|
-
return {
|
|
20
|
-
id: crypto.randomUUID(),
|
|
21
|
-
...data,
|
|
22
|
-
createdAt: new Date(),
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { Hono } from 'hono';
|
|
2
|
-
import { zValidator } from '@hono/zod-validator';
|
|
3
|
-
import { createUserSchema } from '../validators/user.validator';
|
|
4
|
-
import { UserService } from '../services/user.service';
|
|
5
|
-
import { UserRepository } from '../repositories/user.repository';
|
|
6
|
-
|
|
7
|
-
const userRoutes = new Hono();
|
|
8
|
-
|
|
9
|
-
// Dependency Injection (Pattern manual for template)
|
|
10
|
-
const userRepository = new UserRepository();
|
|
11
|
-
const userService = new UserService(userRepository);
|
|
12
|
-
|
|
13
|
-
userRoutes.post('/register', zValidator('json', createUserSchema), async (c) => {
|
|
14
|
-
const data = c.req.valid('json');
|
|
15
|
-
const user = await userService.registerUser(data);
|
|
16
|
-
|
|
17
|
-
return c.json({
|
|
18
|
-
success: true,
|
|
19
|
-
data: user
|
|
20
|
-
}, 201);
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
userRoutes.get('/:id', async (c) => {
|
|
24
|
-
const id = c.req.param('id');
|
|
25
|
-
const user = await userService.getUserProfile(id);
|
|
26
|
-
|
|
27
|
-
return c.json({
|
|
28
|
-
success: true,
|
|
29
|
-
data: user
|
|
30
|
-
});
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
export { userRoutes };
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { UserRepository } from '../repositories/user.repository';
|
|
2
|
-
import { CreateUserInput, User } from '../validators/user.validator';
|
|
3
|
-
import { AppError } from '../../../core/errors';
|
|
4
|
-
|
|
5
|
-
export class UserService {
|
|
6
|
-
constructor(private userRepository: UserRepository) {}
|
|
7
|
-
|
|
8
|
-
async registerUser(data: CreateUserInput): Promise<User> {
|
|
9
|
-
const existing = await this.userRepository.findByEmail(data.email);
|
|
10
|
-
if (existing) {
|
|
11
|
-
throw new AppError('User with this email already exists', 409, 'USER_EXISTS');
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
return this.userRepository.create(data);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
async getUserProfile(id: string): Promise<User> {
|
|
18
|
-
const user = await this.userRepository.findById(id);
|
|
19
|
-
if (!user) {
|
|
20
|
-
throw new AppError('User not found', 404, 'USER_NOT_FOUND');
|
|
21
|
-
}
|
|
22
|
-
return user;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
|
|
3
|
-
export const userSchema = z.object({
|
|
4
|
-
id: z.string().uuid(),
|
|
5
|
-
email: z.string().email(),
|
|
6
|
-
name: z.string().min(2),
|
|
7
|
-
createdAt: z.date(),
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
export type User = z.infer<typeof userSchema>;
|
|
11
|
-
|
|
12
|
-
export const createUserSchema = userSchema.pick({
|
|
13
|
-
email: true,
|
|
14
|
-
name: true,
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
export type CreateUserInput = z.infer<typeof createUserSchema>;
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { test, expect } from '@playwright/test';
|
|
2
|
-
|
|
3
|
-
test('has title', async ({ page }) => {
|
|
4
|
-
await page.goto('/');
|
|
5
|
-
await expect(page).toHaveTitle(/DevForge/);
|
|
6
|
-
});
|
|
7
|
-
|
|
8
|
-
test('api is running', async ({ request }) => {
|
|
9
|
-
const response = await request.get('/');
|
|
10
|
-
expect(response.ok()).toBeTruthy();
|
|
11
|
-
const body = await response.json();
|
|
12
|
-
expect(body.status).toBe('running');
|
|
13
|
-
});
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "saas",
|
|
3
|
-
"description": "Multi-tenant SaaS application",
|
|
4
|
-
"stack": {
|
|
5
|
-
"runtime": "bun",
|
|
6
|
-
"backend": "hono",
|
|
7
|
-
"frontend": "solidjs",
|
|
8
|
-
"database": "postgres"
|
|
9
|
-
},
|
|
10
|
-
"supportedPlugins": [
|
|
11
|
-
"admin-panel",
|
|
12
|
-
"openapi",
|
|
13
|
-
"websocket",
|
|
14
|
-
"queue",
|
|
15
|
-
"openapi",
|
|
16
|
-
"websocket",
|
|
17
|
-
"queue",
|
|
18
|
-
"auth",
|
|
19
|
-
"payment",
|
|
20
|
-
"email",
|
|
21
|
-
"analytics",
|
|
22
|
-
"search",
|
|
23
|
-
"file-upload",
|
|
24
|
-
"github-actions"
|
|
25
|
-
]
|
|
26
|
-
}
|