@kevinmarrec/create-app 0.15.0 → 0.17.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/index.mjs CHANGED
@@ -8,7 +8,7 @@ import { x } from "tinyexec";
8
8
  import fs from "node:fs/promises";
9
9
 
10
10
  //#region package.json
11
- var version = "0.15.0";
11
+ var version = "0.17.0";
12
12
 
13
13
  //#endregion
14
14
  //#region src/utils/fs.ts
@@ -79,7 +79,7 @@ async function run() {
79
79
  message: "Project name",
80
80
  placeholder: "my-app",
81
81
  validate: (value) => {
82
- if (!value.trim()) return "Project name cannot be empty";
82
+ if (!value?.trim()) return "Project name cannot be empty";
83
83
  }
84
84
  });
85
85
  maybeCancel(projectName);
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@kevinmarrec/create-app",
3
3
  "type": "module",
4
- "version": "0.15.0",
5
- "packageManager": "bun@1.3.5",
4
+ "version": "0.17.0",
5
+ "packageManager": "bun@1.3.9",
6
6
  "description": "CLI that scaffolds an opinionated Bun & Vue fullstack application.",
7
7
  "author": "Kevin Marrec <kevin@marrec.io>",
8
8
  "license": "MIT",
@@ -44,25 +44,25 @@
44
44
  "test:coverage": "vitest --coverage"
45
45
  },
46
46
  "dependencies": {
47
- "@clack/prompts": "^0.11.0",
47
+ "@clack/prompts": "^1.0.1",
48
48
  "ansis": "^4.2.0",
49
49
  "pathe": "^2.0.3",
50
50
  "tinyexec": "^1.0.2"
51
51
  },
52
52
  "devDependencies": {
53
- "@faker-js/faker": "^10.2.0",
54
- "@kevinmarrec/eslint-config": "^1.8.1",
55
- "@kevinmarrec/stylelint-config": "^1.8.1",
56
- "@kevinmarrec/tsconfig": "^1.8.1",
57
- "@types/bun": "^1.3.6",
58
- "@vitest/coverage-v8": "^4.0.17",
59
- "bumpp": "^10.4.0",
53
+ "@faker-js/faker": "^10.3.0",
54
+ "@kevinmarrec/eslint-config": "^1.11.0",
55
+ "@kevinmarrec/stylelint-config": "^1.11.0",
56
+ "@kevinmarrec/tsconfig": "^1.11.0",
57
+ "@types/bun": "^1.3.9",
58
+ "@vitest/coverage-v8": "^4.0.18",
59
+ "bumpp": "^10.4.1",
60
60
  "eslint": "^9.39.2",
61
- "knip": "^5.81.0",
62
- "stylelint": "^16.26.1",
63
- "tsdown": "^0.19.0",
61
+ "knip": "^5.84.1",
62
+ "stylelint": "^17.3.0",
63
+ "tsdown": "^0.20.3",
64
64
  "typescript": "^5.9.3",
65
- "vitest": "^4.0.17",
66
- "vue-tsc": "^3.2.2"
65
+ "vitest": "^4.0.18",
66
+ "vue-tsc": "^3.2.4"
67
67
  }
68
68
  }
@@ -1,5 +1,6 @@
1
1
  services:
2
2
  analytics:
3
+ profiles: [analytics]
3
4
  image: umamisoftware/umami:3.0.3
4
5
  container_name: analytics
5
6
  depends_on:
@@ -1,6 +1,7 @@
1
1
  services:
2
2
  mailpit:
3
- image: axllent/mailpit:v1.28.2
3
+ profiles: [mail]
4
+ image: axllent/mailpit:v1.29.1
4
5
  container_name: mailpit
5
6
  depends_on:
6
7
  traefik:
@@ -1,6 +1,7 @@
1
1
  services:
2
2
  metabase:
3
- image: metabase/metabase:v0.58.2
3
+ profiles: [metabase]
4
+ image: metabase/metabase:v0.58.7
4
5
  container_name: metabase
5
6
  depends_on:
6
7
  traefik:
@@ -1,6 +1,6 @@
1
1
  services:
2
2
  postgres:
3
- image: postgres:18.1-alpine
3
+ image: postgres:18.2-alpine
4
4
  container_name: postgres
5
5
  environment:
6
6
  - POSTGRES_USER=user
@@ -1,5 +1,6 @@
1
1
  services:
2
2
  studio:
3
+ profiles: [studio]
3
4
  image: ghcr.io/drizzle-team/gateway:1.2.0
4
5
  container_name: studio
5
6
  depends_on:
@@ -1,6 +1,6 @@
1
1
  services:
2
2
  traefik:
3
- image: traefik:v3.6.7
3
+ image: traefik:v3.6.8
4
4
  container_name: traefik
5
5
  restart: unless-stopped
6
6
  security_opt:
@@ -0,0 +1,6 @@
1
+ .docker*
2
+ .github
3
+ .vscode
4
+ **/dist
5
+ **/node_modules
6
+ **/Dockerfile
@@ -14,7 +14,7 @@ jobs:
14
14
  runs-on: ubuntu-latest
15
15
  steps:
16
16
  - name: Setup Bun
17
- uses: kevinmarrec/workflows/setup-bun@4886894d0abcc5c6dd0b292aa0a53cdd94cc6dc1 # main
17
+ uses: kevinmarrec/workflows/setup-bun@9d2e32941c6fbf76894926019c66ef428ddcc4d2 # main
18
18
 
19
19
  - name: Lint
20
20
  run: bun run lint
@@ -32,12 +32,12 @@ jobs:
32
32
  pull-requests: write
33
33
  steps:
34
34
  - name: Setup Bun
35
- uses: kevinmarrec/workflows/setup-bun@4886894d0abcc5c6dd0b292aa0a53cdd94cc6dc1 # main
35
+ uses: kevinmarrec/workflows/setup-bun@9d2e32941c6fbf76894926019c66ef428ddcc4d2 # main
36
36
 
37
37
  - name: Build project
38
38
  run: bun run build
39
39
 
40
40
  - name: Analyze project build size differences
41
- uses: kevinmarrec/workflows/filesize-diff@4886894d0abcc5c6dd0b292aa0a53cdd94cc6dc1 # main
41
+ uses: kevinmarrec/workflows/filesize-diff@9d2e32941c6fbf76894926019c66ef428ddcc4d2 # main
42
42
  with:
43
43
  directories: app/dist,api/dist
@@ -0,0 +1 @@
1
+ 24.13.1
@@ -2,4 +2,4 @@ ALLOWED_ORIGINS="https://app.dev.localhost"
2
2
  AUTH_SECRET="D0QykrmzDgVrP4GCKkFPT1CB1UplFk4bhIJk92SUtSQ="
3
3
  DATABASE_URL="postgresql://user:password@postgres:5432/app"
4
4
  LOG_LEVEL=info
5
- NODE_ENV="development"
5
+ SERVER_URL="https://api.dev.localhost"
@@ -1,6 +1,6 @@
1
- ARG TARGETARCH
1
+ FROM --platform=$BUILDPLATFORM oven/bun:1.3.9-slim AS build
2
2
 
3
- FROM oven/bun:1.3.6-slim AS build
3
+ ARG TARGETARCH
4
4
 
5
5
  WORKDIR /build
6
6
 
@@ -12,7 +12,7 @@ RUN bun install --filter api --frozen-lockfile
12
12
 
13
13
  COPY api/ ./api/
14
14
 
15
- RUN bun --cwd api build --target bun-linux-$TARGETARCH-modern
15
+ RUN bun -F ./api build --target bun-linux-$TARGETARCH-modern
16
16
 
17
17
  FROM gcr.io/distroless/base-debian13:nonroot AS runner
18
18
 
@@ -10,17 +10,17 @@
10
10
  },
11
11
  "dependencies": {
12
12
  "@libsql/client": "^0.17.0",
13
- "@orpc/server": "^1.13.4",
14
- "better-auth": "^1.4.12",
13
+ "@orpc/server": "^1.13.5",
14
+ "better-auth": "^1.4.18",
15
15
  "drizzle-orm": "^0.45.1",
16
- "pino": "^10.2.0",
16
+ "pino": "^10.3.1",
17
17
  "valibot": "^1.2.0"
18
18
  },
19
19
  "devDependencies": {
20
- "@kevinmarrec/tsconfig": "^1.8.1",
21
- "@types/bun": "^1.3.6",
22
- "drizzle-kit": "^0.31.8",
23
- "pg": "^8.17.0",
20
+ "@kevinmarrec/tsconfig": "^1.11.0",
21
+ "@types/bun": "^1.3.9",
22
+ "drizzle-kit": "^0.31.9",
23
+ "pg": "^8.18.0",
24
24
  "pino-pretty": "^13.1.3",
25
25
  "typescript": "~5.9.3"
26
26
  }
@@ -6,6 +6,7 @@ import { env } from '../env'
6
6
 
7
7
  export function createBetterAuth({ db, logger }: { db: DB, logger: Logger }) {
8
8
  return betterAuth({
9
+ baseURL: env.server.url,
9
10
  basePath: '/auth',
10
11
  secret: env.auth.secret,
11
12
  trustedOrigins: env.cors.allowedOrigins,
@@ -27,14 +27,14 @@ const schema = v.object({
27
27
  ),
28
28
  }),
29
29
  log: v.object({
30
- level: v.optional(v.union([
31
- v.literal('fatal'),
32
- v.literal('error'),
33
- v.literal('warn'),
34
- v.literal('info'),
35
- v.literal('debug'),
36
- v.literal('trace'),
37
- v.literal('silent'),
30
+ level: v.optional(v.picklist([
31
+ 'fatal',
32
+ 'error',
33
+ 'warn',
34
+ 'info',
35
+ 'debug',
36
+ 'trace',
37
+ 'silent',
38
38
  ]), 'info'),
39
39
  }),
40
40
  server: v.object({
@@ -44,6 +44,11 @@ const schema = v.object({
44
44
  v.digits(),
45
45
  v.toNumber(),
46
46
  ),
47
+ url: v.pipe(
48
+ v.string(),
49
+ v.trim(),
50
+ v.startsWith('https://'),
51
+ ),
47
52
  }),
48
53
  })
49
54
 
@@ -63,6 +68,7 @@ const parsed = v.safeParse(schema, {
63
68
  server: {
64
69
  host: import.meta.env.HOST,
65
70
  port: import.meta.env.PORT,
71
+ url: import.meta.env.SERVER_URL,
66
72
  },
67
73
  })
68
74
 
@@ -5,11 +5,10 @@ import { createRpc } from './orpc'
5
5
  import { router } from './orpc/router'
6
6
  import { cors } from './utils/cors'
7
7
  import { logger } from './utils/logger'
8
- import { createStopper } from './utils/stopper'
8
+ import { bindGracefulShutdown } from './utils/stopper'
9
9
 
10
10
  const auth = createBetterAuth({ db, logger })
11
11
  const rpc = createRpc({ auth, db, logger }, router)
12
- const stopper = createStopper({ logger })
13
12
 
14
13
  const server = Bun.serve({
15
14
  hostname: env.server.host,
@@ -25,6 +24,6 @@ const server = Bun.serve({
25
24
  },
26
25
  })
27
26
 
28
- stopper.bind(server)
27
+ bindGracefulShutdown(server, logger)
29
28
 
30
29
  logger.info(`Listening on ${server.url}`)
@@ -1,5 +1,4 @@
1
1
  import { os } from '@orpc/server'
2
- import * as v from 'valibot'
3
2
 
4
3
  import type { Context } from '../context'
5
4
  import { authMiddleware } from '../middlewares/auth'
@@ -17,15 +16,9 @@ const authed = pub
17
16
 
18
17
  export const router = {
19
18
  public: pub
20
- .input(v.any())
21
- .handler(async () => {
22
- return 'public'
23
- }),
19
+ .handler(async () => 'public'),
24
20
  private: authed
25
- .input(v.any())
26
- .handler(async () => {
27
- return 'private'
28
- }),
21
+ .handler(async () => 'private'),
29
22
  }
30
23
 
31
24
  export type Router = typeof router
@@ -2,18 +2,14 @@ import process from 'node:process'
2
2
 
3
3
  import type { Logger } from './logger'
4
4
 
5
- export function createStopper({ logger }: { logger: Logger }) {
6
- return {
7
- bind: (server: Bun.Server<unknown>) => {
8
- async function gracefulShutdown() {
9
- logger.info('Received termination signal. Gracefully shutting down...')
10
- await server.stop()
11
- logger.info('Server stopped. Exiting process.')
12
- process.exit(0)
13
- }
14
-
15
- process.on('SIGINT', gracefulShutdown)
16
- process.on('SIGTERM', gracefulShutdown)
17
- },
5
+ export function bindGracefulShutdown(server: Bun.Server<unknown>, logger: Logger) {
6
+ async function gracefulShutdown() {
7
+ logger.info('Received termination signal. Gracefully shutting down...')
8
+ await server.stop()
9
+ logger.info('Server stopped. Exiting process.')
10
+ process.exit(0)
18
11
  }
12
+
13
+ process.on('SIGINT', gracefulShutdown)
14
+ process.on('SIGTERM', gracefulShutdown)
19
15
  }
@@ -0,0 +1,21 @@
1
+ FROM --platform=$BUILDPLATFORM imbios/bun-node:1.3.9-24.13.1-alpine AS build
2
+
3
+ ARG TARGETARCH
4
+
5
+ WORKDIR /build
6
+
7
+ COPY package.json bun.lock ./
8
+ COPY api/package.json ./api/package.json
9
+ COPY app/package.json ./app/package.json
10
+
11
+ RUN bun install --filter app --frozen-lockfile
12
+
13
+ COPY app/ ./app/
14
+
15
+ RUN bun -F ./app build
16
+
17
+ FROM nginx:1.29.5-alpine AS serve
18
+
19
+ COPY --from=build --chown=nonroot:nonroot /build/app/dist/ /usr/share/nginx/html
20
+
21
+ EXPOSE 80
@@ -9,32 +9,32 @@
9
9
  "preview": "vite preview --open"
10
10
  },
11
11
  "dependencies": {
12
- "@kevinmarrec/vue-i18n": "^1.2.0",
13
- "@orpc/client": "^1.13.4",
14
- "@orpc/vue-colada": "^1.13.4",
15
- "@pinia/colada": "^0.21.1",
16
- "@unhead/vue": "^2.1.2",
17
- "@vueuse/core": "^14.1.0",
18
- "better-auth": "^1.4.12",
12
+ "@kevinmarrec/vue-i18n": "^1.2.1",
13
+ "@orpc/client": "^1.13.5",
14
+ "@orpc/vue-colada": "^1.13.5",
15
+ "@pinia/colada": "^0.21.4",
16
+ "@unhead/vue": "^2.1.4",
17
+ "@vueuse/core": "^14.2.1",
18
+ "better-auth": "^1.4.18",
19
19
  "pinia": "^3.0.4",
20
20
  "unocss": "^66.6.0",
21
- "vue": "^3.5.26"
21
+ "vue": "^3.5.28"
22
22
  },
23
23
  "devDependencies": {
24
- "@kevinmarrec/tsconfig": "^1.8.1",
25
- "@kevinmarrec/unocss-config": "^1.8.1",
26
- "@kevinmarrec/vite-plugin-dark-mode": "^1.2.0",
24
+ "@kevinmarrec/tsconfig": "^1.11.0",
25
+ "@kevinmarrec/unocss-config": "^1.11.0",
26
+ "@kevinmarrec/vite-plugin-dark-mode": "^1.2.1",
27
27
  "@modyfi/vite-plugin-yaml": "^1.1.1",
28
- "@unhead/addons": "^2.1.2",
29
- "@vitejs/plugin-vue": "^6.0.3",
30
- "beasties": "^0.3.5",
28
+ "@unhead/addons": "^2.1.4",
29
+ "@vitejs/plugin-vue": "^6.0.4",
30
+ "beasties": "^0.4.1",
31
31
  "rollup-plugin-visualizer": "^6.0.5",
32
32
  "typescript": "~5.9.3",
33
33
  "valibot": "^1.2.0",
34
34
  "vite": "^7.3.1",
35
35
  "vite-plugin-valibot-env": "^1.0.1",
36
- "vite-plugin-vue-devtools": "^8.0.5",
37
- "vite-ssg": "^28.2.2",
38
- "vite-tsconfig-paths": "^6.0.4"
36
+ "vite-plugin-vue-devtools": "^8.0.6",
37
+ "vite-ssg": "^28.3.0",
38
+ "vite-tsconfig-paths": "^6.1.1"
39
39
  }
40
40
  }
@@ -1,5 +1,4 @@
1
1
  import { defineMutation } from '@pinia/colada'
2
- import { set } from '@vueuse/core'
3
2
  import { computed, ref } from 'vue'
4
3
 
5
4
  import { authClient, type AuthError } from '../lib/auth'
@@ -10,10 +9,10 @@ function defineAuthMutation<TVars, TData>(mutation: (vars: TVars) => Promise<TDa
10
9
  return defineMutation({
11
10
  mutation,
12
11
  onMutate: () => {
13
- set(authError, undefined)
12
+ authError.value = undefined
14
13
  },
15
14
  onSettled: (_, error) => {
16
- set(authError, error)
15
+ authError.value = error as AuthError
17
16
  },
18
17
  })
19
18
  }
@@ -16,7 +16,7 @@ services:
16
16
 
17
17
  api:
18
18
  <<: *common
19
- image: oven/bun:1.3.6-alpine
19
+ image: oven/bun:1.3.9-alpine
20
20
  container_name: api
21
21
  init: true
22
22
  depends_on:
@@ -36,7 +36,7 @@ services:
36
36
 
37
37
  app:
38
38
  <<: *common
39
- image: imbios/bun-node:1.3.6-24-alpine
39
+ image: imbios/bun-node:1.3.9-24.13.1-alpine
40
40
  container_name: app
41
41
  init: true
42
42
  depends_on:
@@ -5,6 +5,7 @@ Object.assign(import.meta.env, {
5
5
  ALLOWED_ORIGINS: 'https://foo.bar',
6
6
  AUTH_SECRET: 'foo',
7
7
  DATABASE_URL: 'postgresql://foo:bar@localhost:5432/foo',
8
+ SERVER_URL: 'https://foo.bar',
8
9
  })
9
10
 
10
11
  export default {
@@ -19,7 +20,8 @@ export default {
19
20
  },
20
21
  },
21
22
  'app': {
22
- entry: ['src/main.ts'],
23
+ // Remove this when using VueUse
24
+ ignoreDependencies: ['@vueuse/core'],
23
25
  },
24
26
  },
25
27
  } satisfies KnipConfig
@@ -2,9 +2,9 @@
2
2
  "name": "project",
3
3
  "type": "module",
4
4
  "private": true,
5
- "packageManager": "bun@1.3.5",
5
+ "packageManager": "bun@1.3.9",
6
6
  "engines": {
7
- "node": "lts/*"
7
+ "node": ">=24.13.1"
8
8
  },
9
9
  "workspaces": [
10
10
  "api",
@@ -23,13 +23,13 @@
23
23
  "update": "bunx taze -I -rwi"
24
24
  },
25
25
  "devDependencies": {
26
- "@kevinmarrec/eslint-config": "^1.8.1",
27
- "@kevinmarrec/stylelint-config": "^1.8.1",
28
- "@kevinmarrec/tsconfig": "^1.8.1",
26
+ "@kevinmarrec/eslint-config": "^1.11.0",
27
+ "@kevinmarrec/stylelint-config": "^1.11.0",
28
+ "@kevinmarrec/tsconfig": "^1.11.0",
29
29
  "eslint": "^9.39.2",
30
- "knip": "^5.81.0",
31
- "stylelint": "^16.26.1",
30
+ "knip": "^5.84.1",
31
+ "stylelint": "^17.3.0",
32
32
  "typescript": "~5.9.3",
33
- "vue-tsc": "^3.2.2"
33
+ "vue-tsc": "^3.2.4"
34
34
  }
35
35
  }