vasp-cli 0.4.0 → 1.0.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.
Files changed (137) hide show
  1. package/README.md +57 -2
  2. package/dist/vasp +201 -35
  3. package/package.json +2 -2
  4. package/starters/minimal.vasp +1 -1
  5. package/starters/recipe.vasp +11 -20
  6. package/starters/todo-auth-ssr.vasp +33 -20
  7. package/starters/todo.vasp +15 -8
  8. package/templates/shared/.gitignore.hbs +1 -0
  9. package/templates/shared/auth/server/index.hbs +4 -8
  10. package/templates/shared/auth/server/middleware.hbs +33 -15
  11. package/templates/{templates/shared → shared}/auth/server/plugin.hbs +0 -2
  12. package/templates/shared/auth/server/providers/github.hbs +1 -1
  13. package/templates/shared/auth/server/providers/google.hbs +1 -1
  14. package/templates/shared/auth/server/providers/usernameAndPassword.hbs +3 -6
  15. package/templates/shared/bunfig.toml.hbs +3 -0
  16. package/templates/shared/drizzle/schema.hbs +38 -19
  17. package/templates/shared/package.json.hbs +11 -3
  18. package/templates/shared/server/db/client.hbs +19 -1
  19. package/templates/shared/server/db/seed.hbs +16 -0
  20. package/templates/shared/server/index.hbs +47 -0
  21. package/templates/shared/server/middleware/errorHandler.hbs +75 -0
  22. package/templates/shared/server/middleware/logger.hbs +74 -0
  23. package/templates/shared/server/middleware/rateLimit.hbs +2 -2
  24. package/templates/shared/server/routes/_vasp.hbs +37 -0
  25. package/templates/shared/server/routes/actions/_action.hbs +5 -1
  26. package/templates/shared/server/routes/api/_api.hbs +24 -0
  27. package/templates/shared/server/routes/crud/_crud.hbs +58 -10
  28. package/templates/shared/server/routes/queries/_query.hbs +5 -1
  29. package/templates/shared/shared/types.hbs +58 -0
  30. package/templates/shared/shared/validation.hbs +20 -0
  31. package/templates/shared/tests/actions/_action.test.js.hbs +7 -0
  32. package/templates/shared/tests/actions/_action.test.ts.hbs +7 -0
  33. package/templates/shared/tests/auth/login.test.js.hbs +7 -0
  34. package/templates/shared/tests/auth/login.test.ts.hbs +7 -0
  35. package/templates/shared/tests/crud/_entity.test.js.hbs +7 -0
  36. package/templates/shared/tests/crud/_entity.test.ts.hbs +7 -0
  37. package/templates/shared/tests/queries/_query.test.js.hbs +7 -0
  38. package/templates/shared/tests/queries/_query.test.ts.hbs +7 -0
  39. package/templates/shared/tests/setup.js.hbs +5 -0
  40. package/templates/shared/tests/setup.ts.hbs +5 -0
  41. package/templates/shared/tests/vitest.config.js.hbs +8 -0
  42. package/templates/shared/tests/vitest.config.ts.hbs +8 -0
  43. package/templates/shared/tsconfig.json.hbs +2 -1
  44. package/templates/spa/js/src/App.vue.hbs +9 -1
  45. package/templates/spa/js/src/components/VaspErrorBoundary.vue.hbs +33 -0
  46. package/templates/spa/js/src/components/VaspNotifications.vue.hbs +60 -0
  47. package/templates/spa/js/src/vasp/auth.js.hbs +31 -15
  48. package/templates/spa/js/src/vasp/client/actions.js.hbs +7 -1
  49. package/templates/spa/js/src/vasp/client/crud.js.hbs +94 -5
  50. package/templates/spa/js/src/vasp/useVaspNotifications.js.hbs +35 -0
  51. package/templates/spa/js/vite.config.js.hbs +1 -0
  52. package/templates/spa/ts/src/App.vue.hbs +9 -1
  53. package/templates/spa/ts/src/components/VaspErrorBoundary.vue.hbs +33 -0
  54. package/templates/spa/ts/src/components/VaspNotifications.vue.hbs +60 -0
  55. package/templates/spa/ts/src/vasp/auth.ts.hbs +31 -15
  56. package/templates/spa/ts/src/vasp/client/actions.ts.hbs +7 -1
  57. package/templates/spa/ts/src/vasp/client/crud.ts.hbs +96 -10
  58. package/templates/spa/ts/src/vasp/client/types.ts.hbs +14 -28
  59. package/templates/spa/ts/src/vasp/useVaspNotifications.ts.hbs +41 -0
  60. package/templates/spa/ts/vite.config.ts.hbs +1 -0
  61. package/templates/ssr/js/error.vue.hbs +23 -0
  62. package/templates/ssr/js/nuxt.config.js.hbs +1 -0
  63. package/templates/ssr/ts/error.vue.hbs +26 -0
  64. package/templates/ssr/ts/nuxt.config.ts.hbs +1 -0
  65. package/templates/starters/minimal.vasp +15 -0
  66. package/templates/starters/recipe.vasp +70 -0
  67. package/templates/starters/todo-auth-ssr.vasp +65 -0
  68. package/templates/starters/todo.vasp +42 -0
  69. package/templates/templates/shared/.env.example.hbs +0 -14
  70. package/templates/templates/shared/.gitignore.hbs +0 -8
  71. package/templates/templates/shared/auth/client/Login.vue.hbs +0 -46
  72. package/templates/templates/shared/auth/client/Register.vue.hbs +0 -42
  73. package/templates/templates/shared/auth/server/index.hbs +0 -46
  74. package/templates/templates/shared/auth/server/middleware.hbs +0 -33
  75. package/templates/templates/shared/auth/server/providers/github.hbs +0 -48
  76. package/templates/templates/shared/auth/server/providers/google.hbs +0 -53
  77. package/templates/templates/shared/auth/server/providers/usernameAndPassword.hbs +0 -66
  78. package/templates/templates/shared/bunfig.toml.hbs +0 -5
  79. package/templates/templates/shared/drizzle/drizzle.config.hbs +0 -10
  80. package/templates/templates/shared/drizzle/schema.hbs +0 -48
  81. package/templates/templates/shared/jobs/_job.hbs +0 -34
  82. package/templates/templates/shared/jobs/boss.hbs +0 -15
  83. package/templates/templates/shared/package.json.hbs +0 -38
  84. package/templates/templates/shared/server/db/client.hbs +0 -12
  85. package/templates/templates/shared/server/index.hbs +0 -73
  86. package/templates/templates/shared/server/middleware/csrf.hbs +0 -34
  87. package/templates/templates/shared/server/middleware/rateLimit.hbs +0 -44
  88. package/templates/templates/shared/server/routes/actions/_action.hbs +0 -20
  89. package/templates/templates/shared/server/routes/crud/_crud.hbs +0 -86
  90. package/templates/templates/shared/server/routes/jobs/_schedule.hbs +0 -12
  91. package/templates/templates/shared/server/routes/queries/_query.hbs +0 -20
  92. package/templates/templates/shared/server/routes/realtime/_channel.hbs +0 -78
  93. package/templates/templates/shared/server/routes/realtime/index.hbs +0 -9
  94. package/templates/templates/shared/tsconfig.json.hbs +0 -21
  95. package/templates/templates/spa/js/index.html.hbs +0 -12
  96. package/templates/templates/spa/js/src/App.vue.hbs +0 -3
  97. package/templates/templates/spa/js/src/main.js.hbs +0 -9
  98. package/templates/templates/spa/js/src/router/index.js.hbs +0 -41
  99. package/templates/templates/spa/js/src/vasp/auth.js.hbs +0 -45
  100. package/templates/templates/spa/js/src/vasp/client/actions.js.hbs +0 -15
  101. package/templates/templates/spa/js/src/vasp/client/crud.js.hbs +0 -30
  102. package/templates/templates/spa/js/src/vasp/client/index.js.hbs +0 -16
  103. package/templates/templates/spa/js/src/vasp/client/queries.js.hbs +0 -15
  104. package/templates/templates/spa/js/src/vasp/client/realtime.js.hbs +0 -51
  105. package/templates/templates/spa/js/src/vasp/plugin.js.hbs +0 -11
  106. package/templates/templates/spa/js/vite.config.js.hbs +0 -26
  107. package/templates/templates/spa/ts/index.html.hbs +0 -12
  108. package/templates/templates/spa/ts/src/App.vue.hbs +0 -3
  109. package/templates/templates/spa/ts/src/main.ts.hbs +0 -9
  110. package/templates/templates/spa/ts/src/router/index.ts.hbs +0 -41
  111. package/templates/templates/spa/ts/src/vasp/auth.ts.hbs +0 -53
  112. package/templates/templates/spa/ts/src/vasp/client/actions.ts.hbs +0 -19
  113. package/templates/templates/spa/ts/src/vasp/client/crud.ts.hbs +0 -37
  114. package/templates/templates/spa/ts/src/vasp/client/index.ts.hbs +0 -17
  115. package/templates/templates/spa/ts/src/vasp/client/queries.ts.hbs +0 -19
  116. package/templates/templates/spa/ts/src/vasp/client/realtime.ts.hbs +0 -56
  117. package/templates/templates/spa/ts/src/vasp/client/types.ts.hbs +0 -33
  118. package/templates/templates/spa/ts/src/vasp/plugin.ts.hbs +0 -12
  119. package/templates/templates/spa/ts/vite.config.ts.hbs +0 -26
  120. package/templates/templates/ssr/js/_page.vue.hbs +0 -10
  121. package/templates/templates/ssr/js/app.vue.hbs +0 -3
  122. package/templates/templates/ssr/js/composables/useAuth.js.hbs +0 -52
  123. package/templates/templates/ssr/js/composables/useVasp.js.hbs +0 -6
  124. package/templates/templates/ssr/js/middleware/auth.js.hbs +0 -8
  125. package/templates/templates/ssr/js/nuxt.config.js.hbs +0 -15
  126. package/templates/templates/ssr/js/plugins/vasp.client.js.hbs +0 -27
  127. package/templates/templates/ssr/js/plugins/vasp.server.js.hbs +0 -33
  128. package/templates/templates/ssr/ts/_page.vue.hbs +0 -10
  129. package/templates/templates/ssr/ts/app.vue.hbs +0 -3
  130. package/templates/templates/ssr/ts/composables/useAuth.ts.hbs +0 -56
  131. package/templates/templates/ssr/ts/composables/useVasp.ts.hbs +0 -10
  132. package/templates/templates/ssr/ts/middleware/auth.ts.hbs +0 -8
  133. package/templates/templates/ssr/ts/nuxt.config.ts.hbs +0 -19
  134. package/templates/templates/ssr/ts/plugins/vasp.client.ts.hbs +0 -27
  135. package/templates/templates/ssr/ts/plugins/vasp.server.ts.hbs +0 -33
  136. /package/templates/{templates/shared → shared}/.env.hbs +0 -0
  137. /package/templates/{templates/shared → shared}/README.md.hbs +0 -0
@@ -1,45 +0,0 @@
1
- import { ref } from 'vue'
2
- import { $fetch } from 'ofetch'
3
-
4
- const user = ref(null)
5
- let checked = false
6
-
7
- const API = import.meta.env.VITE_API_URL || '/api'
8
-
9
- export function useAuth() {
10
- async function checkAuth() {
11
- if (checked) return
12
- checked = true
13
- try {
14
- user.value = await $fetch(`${API}/auth/me`, { credentials: 'include' })
15
- } catch {
16
- user.value = null
17
- }
18
- }
19
-
20
- async function login(username, password) {
21
- user.value = await $fetch(`${API}/auth/login`, {
22
- method: 'POST',
23
- body: { username, password },
24
- credentials: 'include',
25
- })
26
- return user.value
27
- }
28
-
29
- async function register(username, password, email) {
30
- user.value = await $fetch(`${API}/auth/register`, {
31
- method: 'POST',
32
- body: { username, password, email },
33
- credentials: 'include',
34
- })
35
- return user.value
36
- }
37
-
38
- async function logout() {
39
- await $fetch(`${API}/auth/logout`, { method: 'POST', credentials: 'include' })
40
- user.value = null
41
- checked = false
42
- }
43
-
44
- return { user, checkAuth, login, register, logout }
45
- }
@@ -1,15 +0,0 @@
1
- // Auto-generated by Vasp — do not edit
2
- import { useVasp } from '@vasp-framework/runtime'
3
-
4
- {{#each actions}}
5
- /**
6
- * Call the '{{name}}' action on the Vasp backend.
7
- * @param {unknown} args - Arguments to pass to the action function
8
- * @returns {Promise<unknown>}
9
- */
10
- export async function {{camelCase name}}(args) {
11
- const { $vasp } = useVasp()
12
- return $vasp.action('{{camelCase name}}', args)
13
- }
14
-
15
- {{/each}}
@@ -1,30 +0,0 @@
1
- // Auto-generated by Vasp — do not edit
2
- import { $fetch } from 'ofetch'
3
-
4
- const API = import.meta.env.VITE_API_URL || '/api'
5
-
6
- {{#each cruds}}
7
- /**
8
- * CRUD helpers for the '{{entity}}' entity.
9
- */
10
- export function use{{pascalCase entity}}Crud() {
11
- const base = `${API}/crud/{{camelCase entity}}`
12
-
13
- return {
14
- {{#if (includes operations "list")}}
15
- list: () => $fetch(base, { credentials: 'include' }),
16
- {{/if}}
17
- {{#if (includes operations "create")}}
18
- create: (data) => $fetch(base, { method: 'POST', body: data, credentials: 'include' }),
19
- {{/if}}
20
- get: (id) => $fetch(`${base}/${id}`, { credentials: 'include' }),
21
- {{#if (includes operations "update")}}
22
- update: (id, data) => $fetch(`${base}/${id}`, { method: 'PUT', body: data, credentials: 'include' }),
23
- {{/if}}
24
- {{#if (includes operations "delete")}}
25
- remove: (id) => $fetch(`${base}/${id}`, { method: 'DELETE', credentials: 'include' }),
26
- {{/if}}
27
- }
28
- }
29
-
30
- {{/each}}
@@ -1,16 +0,0 @@
1
- // Auto-generated by Vasp — do not edit directly
2
- // Re-run `vasp build` or restart `vasp start` to regenerate
3
-
4
- export { useVasp } from '@vasp-framework/runtime'
5
- {{#each queries}}
6
- export { {{camelCase name}} } from './queries.js'
7
- {{/each}}
8
- {{#each actions}}
9
- export { {{camelCase name}} } from './actions.js'
10
- {{/each}}
11
- {{#each cruds}}
12
- export { use{{pascalCase entity}}Crud } from './crud.js'
13
- {{/each}}
14
- {{#if hasRealtime}}
15
- export { useRealtime } from './realtime.js'
16
- {{/if}}
@@ -1,15 +0,0 @@
1
- // Auto-generated by Vasp — do not edit
2
- import { useVasp } from '@vasp-framework/runtime'
3
-
4
- {{#each queries}}
5
- /**
6
- * Call the '{{name}}' query on the Vasp backend.
7
- * @param {unknown} [args] - Arguments to pass to the query function
8
- * @returns {Promise<unknown>}
9
- */
10
- export async function {{camelCase name}}(args) {
11
- const { $vasp } = useVasp()
12
- return $vasp.query('{{camelCase name}}', args)
13
- }
14
-
15
- {{/each}}
@@ -1,51 +0,0 @@
1
- // Auto-generated by Vasp — do not edit
2
- import { ref, onUnmounted } from 'vue'
3
-
4
- const WS_BASE = import.meta.env.VITE_WS_URL || `ws://${location.host}`
5
-
6
- /**
7
- * useRealtime — subscribe to a Vasp realtime channel.
8
- *
9
- * @example
10
- * const { on } = useRealtime('todoChannel')
11
- * on('created', (todo) => todos.value.push(todo))
12
- */
13
- export function useRealtime(channelName) {
14
- const connected = ref(false)
15
- const handlers = new Map()
16
- let ws = null
17
- let reconnectTimer = null
18
-
19
- function connect() {
20
- ws = new WebSocket(`${WS_BASE}/ws/${channelName}`)
21
-
22
- ws.onopen = () => { connected.value = true }
23
- ws.onclose = () => {
24
- connected.value = false
25
- reconnectTimer = setTimeout(connect, 3000) // auto-reconnect
26
- }
27
- ws.onerror = () => ws.close()
28
- ws.onmessage = ({ data }) => {
29
- try {
30
- const msg = JSON.parse(data)
31
- if (msg.channel === channelName && handlers.has(msg.event)) {
32
- handlers.get(msg.event)(msg.data)
33
- }
34
- } catch {}
35
- }
36
- }
37
-
38
- function on(event, handler) {
39
- handlers.set(event, handler)
40
- }
41
-
42
- function disconnect() {
43
- clearTimeout(reconnectTimer)
44
- ws?.close()
45
- }
46
-
47
- connect()
48
- onUnmounted(disconnect)
49
-
50
- return { connected, on, disconnect }
51
- }
@@ -1,11 +0,0 @@
1
- import { createVaspClient } from '@vasp-framework/runtime'
2
-
3
- export const vaspPlugin = {
4
- install(app) {
5
- const client = createVaspClient({
6
- baseURL: import.meta.env.VITE_API_URL || '/api',
7
- })
8
- app.provide('$vasp', client)
9
- app.config.globalProperties.$vasp = client
10
- },
11
- }
@@ -1,26 +0,0 @@
1
- import { defineConfig } from 'vite'
2
- import vue from '@vitejs/plugin-vue'
3
- import { fileURLToPath, URL } from 'node:url'
4
-
5
- export default defineConfig({
6
- plugins: [vue()],
7
- resolve: {
8
- alias: {
9
- '@src': fileURLToPath(new URL('./src', import.meta.url)),
10
- '@vasp-framework/client': fileURLToPath(new URL('./src/vasp/client', import.meta.url)),
11
- },
12
- },
13
- server: {
14
- port: {{frontendPort}},
15
- proxy: {
16
- '/api': {
17
- target: 'http://localhost:{{backendPort}}',
18
- changeOrigin: true,
19
- },
20
- '/ws': {
21
- target: 'ws://localhost:{{backendPort}}',
22
- ws: true,
23
- },
24
- },
25
- },
26
- })
@@ -1,12 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <title>{{appTitle}}</title>
7
- </head>
8
- <body>
9
- <div id="app"></div>
10
- <script type="module" src="/src/main.ts"></script>
11
- </body>
12
- </html>
@@ -1,3 +0,0 @@
1
- <template>
2
- <RouterView />
3
- </template>
@@ -1,9 +0,0 @@
1
- import { createApp } from 'vue'
2
- import App from './App.vue'
3
- import router from './router/index.js'
4
- import { vaspPlugin } from './vasp/plugin.js'
5
-
6
- const app = createApp(App)
7
- app.use(router)
8
- app.use(vaspPlugin)
9
- app.mount('#app')
@@ -1,41 +0,0 @@
1
- import { createRouter, createWebHistory, type RouteRecordRaw } from 'vue-router'
2
- {{#if hasAuth}}
3
- import { useAuth } from '../vasp/auth.js'
4
- {{/if}}
5
-
6
- const routes: RouteRecordRaw[] = [
7
- {{#each routes}}
8
- {
9
- path: '{{path}}',
10
- component: () => import('{{lookup ../pagesMap to}}'),
11
- },
12
- {{/each}}
13
- {{#if hasAuth}}
14
- {
15
- path: '/login',
16
- component: () => import('../pages/Login.vue'),
17
- },
18
- {
19
- path: '/register',
20
- component: () => import('../pages/Register.vue'),
21
- },
22
- {{/if}}
23
- ]
24
-
25
- const router = createRouter({
26
- history: createWebHistory(),
27
- routes,
28
- })
29
-
30
- {{#if hasAuth}}
31
- router.beforeEach(async (to) => {
32
- const { user, checkAuth } = useAuth()
33
- await checkAuth()
34
- const publicPaths = ['/login', '/register']
35
- if (!user.value && !publicPaths.includes(to.path)) {
36
- return '/login'
37
- }
38
- })
39
- {{/if}}
40
-
41
- export default router
@@ -1,53 +0,0 @@
1
- import { ref, type Ref } from 'vue'
2
- import { $fetch } from 'ofetch'
3
-
4
- export interface AuthUser {
5
- id: number
6
- username: string
7
- email: string | null
8
- createdAt: Date
9
- updatedAt: Date
10
- }
11
-
12
- const user: Ref<AuthUser | null> = ref(null)
13
- let checked = false
14
-
15
- const API = import.meta.env.VITE_API_URL || '/api'
16
-
17
- export function useAuth() {
18
- async function checkAuth(): Promise<void> {
19
- if (checked) return
20
- checked = true
21
- try {
22
- user.value = await $fetch<AuthUser>(`${API}/auth/me`, { credentials: 'include' })
23
- } catch {
24
- user.value = null
25
- }
26
- }
27
-
28
- async function login(username: string, password: string): Promise<AuthUser> {
29
- user.value = await $fetch<AuthUser>(`${API}/auth/login`, {
30
- method: 'POST',
31
- body: { username, password },
32
- credentials: 'include',
33
- })
34
- return user.value!
35
- }
36
-
37
- async function register(username: string, password: string, email?: string): Promise<AuthUser> {
38
- user.value = await $fetch<AuthUser>(`${API}/auth/register`, {
39
- method: 'POST',
40
- body: { username, password, email },
41
- credentials: 'include',
42
- })
43
- return user.value!
44
- }
45
-
46
- async function logout(): Promise<void> {
47
- await $fetch(`${API}/auth/logout`, { method: 'POST', credentials: 'include' })
48
- user.value = null
49
- checked = false
50
- }
51
-
52
- return { user, checkAuth, login, register, logout }
53
- }
@@ -1,19 +0,0 @@
1
- // Auto-generated by Vasp — do not edit
2
- import { useVasp } from '@vasp-framework/runtime'
3
- import type {
4
- {{#each actions}}
5
- {{pascalCase name}}Args,
6
- {{pascalCase name}}Return,
7
- {{/each}}
8
- } from './types.js'
9
-
10
- {{#each actions}}
11
- /**
12
- * Call the '{{name}}' action on the Vasp backend.
13
- */
14
- export async function {{camelCase name}}(args: {{pascalCase name}}Args): Promise<{{pascalCase name}}Return> {
15
- const { $vasp } = useVasp()
16
- return $vasp.action('{{camelCase name}}', args) as Promise<{{pascalCase name}}Return>
17
- }
18
-
19
- {{/each}}
@@ -1,37 +0,0 @@
1
- // Auto-generated by Vasp — do not edit
2
- import { $fetch } from 'ofetch'
3
- import type {
4
- {{#each cruds}}
5
- {{pascalCase entity}},
6
- New{{pascalCase entity}},
7
- {{/each}}
8
- } from './types.js'
9
-
10
- const API = import.meta.env.VITE_API_URL || '/api'
11
-
12
- {{#each cruds}}
13
- export function use{{pascalCase entity}}Crud() {
14
- const base = `${API}/crud/{{camelCase entity}}`
15
-
16
- return {
17
- {{#if (includes operations "list")}}
18
- list: (): Promise<{{pascalCase entity}}[]> => $fetch(base, { credentials: 'include' }),
19
- {{/if}}
20
- {{#if (includes operations "create")}}
21
- create: (data: New{{pascalCase entity}}): Promise<{{pascalCase entity}}> =>
22
- $fetch(base, { method: 'POST', body: data, credentials: 'include' }),
23
- {{/if}}
24
- get: (id: number): Promise<{{pascalCase entity}}> =>
25
- $fetch(`${base}/${id}`, { credentials: 'include' }),
26
- {{#if (includes operations "update")}}
27
- update: (id: number, data: Partial<New{{pascalCase entity}}>): Promise<{{pascalCase entity}}> =>
28
- $fetch(`${base}/${id}`, { method: 'PUT', body: data, credentials: 'include' }),
29
- {{/if}}
30
- {{#if (includes operations "delete")}}
31
- remove: (id: number): Promise<{ ok: boolean }> =>
32
- $fetch(`${base}/${id}`, { method: 'DELETE', credentials: 'include' }),
33
- {{/if}}
34
- }
35
- }
36
-
37
- {{/each}}
@@ -1,17 +0,0 @@
1
- // Auto-generated by Vasp — do not edit directly
2
- // Re-run `vasp build` or restart `vasp start` to regenerate
3
-
4
- export { useVasp } from '@vasp-framework/runtime'
5
- {{#each queries}}
6
- export { {{camelCase name}} } from './queries.js'
7
- {{/each}}
8
- {{#each actions}}
9
- export { {{camelCase name}} } from './actions.js'
10
- {{/each}}
11
- {{#each cruds}}
12
- export { use{{pascalCase entity}}Crud } from './crud.js'
13
- {{/each}}
14
- {{#if hasRealtime}}
15
- export { useRealtime } from './realtime.js'
16
- {{/if}}
17
- export type * from './types.js'
@@ -1,19 +0,0 @@
1
- // Auto-generated by Vasp — do not edit
2
- import { useVasp } from '@vasp-framework/runtime'
3
- import type {
4
- {{#each queries}}
5
- {{pascalCase name}}Args,
6
- {{pascalCase name}}Return,
7
- {{/each}}
8
- } from './types.js'
9
-
10
- {{#each queries}}
11
- /**
12
- * Call the '{{name}}' query on the Vasp backend.
13
- */
14
- export async function {{camelCase name}}(args?: {{pascalCase name}}Args): Promise<{{pascalCase name}}Return> {
15
- const { $vasp } = useVasp()
16
- return $vasp.query('{{camelCase name}}', args) as Promise<{{pascalCase name}}Return>
17
- }
18
-
19
- {{/each}}
@@ -1,56 +0,0 @@
1
- // Auto-generated by Vasp — do not edit
2
- import { ref, onUnmounted, type Ref } from 'vue'
3
-
4
- const WS_BASE = import.meta.env.VITE_WS_URL || `ws://${location.host}`
5
-
6
- export interface RealtimeMessage {
7
- channel: string
8
- event: string
9
- data: unknown
10
- }
11
-
12
- export interface UseRealtimeResult {
13
- connected: Ref<boolean>
14
- on: (event: string, handler: (data: unknown) => void) => void
15
- disconnect: () => void
16
- }
17
-
18
- export function useRealtime(channelName: string): UseRealtimeResult {
19
- const connected = ref(false)
20
- const handlers = new Map<string, (data: unknown) => void>()
21
- let ws: WebSocket | null = null
22
- let reconnectTimer: ReturnType<typeof setTimeout> | null = null
23
-
24
- function connect() {
25
- ws = new WebSocket(`${WS_BASE}/ws/${channelName}`)
26
-
27
- ws.onopen = () => { connected.value = true }
28
- ws.onclose = () => {
29
- connected.value = false
30
- reconnectTimer = setTimeout(connect, 3000)
31
- }
32
- ws.onerror = () => ws?.close()
33
- ws.onmessage = ({ data }: MessageEvent<string>) => {
34
- try {
35
- const msg = JSON.parse(data) as RealtimeMessage
36
- if (msg.channel === channelName) {
37
- handlers.get(msg.event)?.(msg.data)
38
- }
39
- } catch {}
40
- }
41
- }
42
-
43
- function on(event: string, handler: (data: unknown) => void) {
44
- handlers.set(event, handler)
45
- }
46
-
47
- function disconnect() {
48
- if (reconnectTimer) clearTimeout(reconnectTimer)
49
- ws?.close()
50
- }
51
-
52
- connect()
53
- onUnmounted(disconnect)
54
-
55
- return { connected, on, disconnect }
56
- }
@@ -1,33 +0,0 @@
1
- // Auto-generated by Vasp — entity types inferred from Drizzle schema
2
- import type {
3
- {{#each cruds}}
4
- {{pascalCase entity}},
5
- New{{pascalCase entity}},
6
- {{/each}}
7
- {{#if hasAuth}}
8
- User,
9
- {{/if}}
10
- } from '../../../../../../drizzle/schema.js'
11
-
12
- {{#each queries}}
13
- // Arguments and return type for '{{name}}' — customize as needed
14
- export type {{pascalCase name}}Args = Record<string, unknown>
15
- export type {{pascalCase name}}Return = unknown
16
-
17
- {{/each}}
18
- {{#each actions}}
19
- // Arguments and return type for '{{name}}' — customize as needed
20
- export type {{pascalCase name}}Args = Record<string, unknown>
21
- export type {{pascalCase name}}Return = unknown
22
-
23
- {{/each}}
24
- // Re-export entity types for convenience
25
- export type {
26
- {{#each cruds}}
27
- {{pascalCase entity}},
28
- New{{pascalCase entity}},
29
- {{/each}}
30
- {{#if hasAuth}}
31
- User,
32
- {{/if}}
33
- }
@@ -1,12 +0,0 @@
1
- import type { App } from 'vue'
2
- import { createVaspClient } from '@vasp-framework/runtime'
3
-
4
- export const vaspPlugin = {
5
- install(app: App) {
6
- const client = createVaspClient({
7
- baseURL: import.meta.env.VITE_API_URL || '/api',
8
- })
9
- app.provide('$vasp', client)
10
- app.config.globalProperties.$vasp = client
11
- },
12
- }
@@ -1,26 +0,0 @@
1
- import { defineConfig } from 'vite'
2
- import vue from '@vitejs/plugin-vue'
3
- import { fileURLToPath, URL } from 'node:url'
4
-
5
- export default defineConfig({
6
- plugins: [vue()],
7
- resolve: {
8
- alias: {
9
- '@src': fileURLToPath(new URL('./src', import.meta.url)),
10
- '@vasp-framework/client': fileURLToPath(new URL('./src/vasp/client', import.meta.url)),
11
- },
12
- },
13
- server: {
14
- port: {{frontendPort}},
15
- proxy: {
16
- '/api': {
17
- target: 'http://localhost:{{backendPort}}',
18
- changeOrigin: true,
19
- },
20
- '/ws': {
21
- target: 'ws://localhost:{{backendPort}}',
22
- ws: true,
23
- },
24
- },
25
- },
26
- })
@@ -1,10 +0,0 @@
1
- <template>
2
- <{{componentName}} />
3
- </template>
4
-
5
- <script setup>
6
- import {{componentName}} from '{{componentSource}}'
7
- {{#if hasAuth}}
8
- definePageMeta({ middleware: 'auth' })
9
- {{/if}}
10
- </script>
@@ -1,3 +0,0 @@
1
- <template>
2
- <NuxtPage />
3
- </template>
@@ -1,52 +0,0 @@
1
- // Auto-generated by Vasp — do not edit directly
2
- // SSR-aware auth composable — uses cookies (httpOnly) and Nuxt's useRequestHeaders for server-side access
3
- import { $fetch } from 'ofetch'
4
-
5
- const _user = ref(null)
6
- let _checked = false
7
-
8
- export function useAuth() {
9
- const config = useRuntimeConfig()
10
- const baseURL = config.public.apiBase
11
-
12
- // On server, forward cookies from the incoming request
13
- const headers = import.meta.server ? useRequestHeaders(['cookie']) : {}
14
-
15
- async function checkAuth() {
16
- if (_checked) return
17
- _checked = true
18
- try {
19
- _user.value = await $fetch(`${baseURL}/auth/me`, { headers, credentials: 'include' })
20
- } catch {
21
- _user.value = null
22
- }
23
- }
24
-
25
- async function login(username, password) {
26
- _user.value = await $fetch(`${baseURL}/auth/login`, {
27
- method: 'POST',
28
- body: { username, password },
29
- credentials: 'include',
30
- })
31
- _checked = true
32
- return _user.value
33
- }
34
-
35
- async function register(username, password, email) {
36
- _user.value = await $fetch(`${baseURL}/auth/register`, {
37
- method: 'POST',
38
- body: { username, password, email },
39
- credentials: 'include',
40
- })
41
- _checked = true
42
- return _user.value
43
- }
44
-
45
- async function logout() {
46
- await $fetch(`${baseURL}/auth/logout`, { method: 'POST', credentials: 'include' })
47
- _user.value = null
48
- _checked = false
49
- }
50
-
51
- return { user: _user, checkAuth, login, register, logout }
52
- }
@@ -1,6 +0,0 @@
1
- // Auto-generated by Vasp — do not edit directly
2
- // Thin wrapper — the actual $vasp client is provided by vasp.server.js or vasp.client.js plugin
3
- export const useVasp = () => {
4
- const { $vasp } = useNuxtApp()
5
- return { $vasp }
6
- }
@@ -1,8 +0,0 @@
1
- // Auto-generated by Vasp — do not edit directly
2
- export default defineNuxtRouteMiddleware((to) => {
3
- const { user } = useAuth()
4
- const publicPaths = ['/login', '/register']
5
- if (!user.value && !publicPaths.includes(to.path)) {
6
- return navigateTo('/login')
7
- }
8
- })
@@ -1,15 +0,0 @@
1
- // Auto-generated by Vasp — do not edit directly
2
- // https://nuxt.com/docs/api/configuration/nuxt-config
3
- export default defineNuxtConfig({
4
- compatibilityDate: '2024-11-01',
5
- devtools: { enabled: true },
6
- alias: {
7
- '@src': '~/src',
8
- },
9
- runtimeConfig: {
10
- backendUrl: process.env.BACKEND_URL || 'http://localhost:{{backendPort}}',
11
- public: {
12
- apiBase: process.env.API_BASE || 'http://localhost:{{backendPort}}/api',
13
- },
14
- },
15
- })