@murumets-ee/create 0.1.3 → 0.1.4

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 (3) hide show
  1. package/dist/cli.js +152 -30
  2. package/dist/index.js +149 -27
  3. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{a as e,b as p,c as d,d as u,e as A}from"./chunk-ZAX4VH4C.js";import*as c from"@clack/prompts";import b from"picocolors";import*as s from"@clack/prompts";async function N(t){s.intro("@murumets-ee/create");let n=t??await s.text({message:"Project name:",placeholder:"my-project",validate:l=>{if(!l)return"Project name is required";if(!/^[a-z0-9-]+$/.test(l))return"Use lowercase letters, numbers, and hyphens only"}});if(s.isCancel(n))return s.cancel("Cancelled."),null;let r=await s.select({message:"App setup:",options:[{value:"single",label:"Single app",hint:"everything in one Next.js project"},{value:"multi",label:"Admin + Frontend",hint:"two apps in a pnpm workspace"}]});if(s.isCancel(r))return s.cancel("Cancelled."),null;let o=await s.confirm({message:"Install dependencies?",initialValue:!0});return s.isCancel(o)?(s.cancel("Cancelled."),null):{name:n,mode:r,installDeps:o}}import{join as k}from"path";import{join as m}from"path";async function T(t,n){await e(m(t,"lib/auth.ts"),`import { getToolkitApp } from './app'
2
+ import{a as e,b as d,c as g,d as u,e as A}from"./chunk-ZAX4VH4C.js";import*as c from"@clack/prompts";import v from"picocolors";import*as s from"@clack/prompts";async function N(t){s.intro("@murumets-ee/create");let n=t??await s.text({message:"Project name:",placeholder:"my-project",validate:l=>{if(!l)return"Project name is required";if(!/^[a-z0-9-]+$/.test(l))return"Use lowercase letters, numbers, and hyphens only"}});if(s.isCancel(n))return s.cancel("Cancelled."),null;let r=await s.select({message:"App setup:",options:[{value:"single",label:"Single app",hint:"everything in one Next.js project"},{value:"multi",label:"Admin + Frontend",hint:"two apps in a pnpm workspace"}]});if(s.isCancel(r))return s.cancel("Cancelled."),null;let o=await s.confirm({message:"Install dependencies?",initialValue:!0});return s.isCancel(o)?(s.cancel("Cancelled."),null):{name:n,mode:r,installDeps:o}}import{join as k}from"path";import{join as m}from"path";async function T(t,n){await e(m(t,"lib/auth.ts"),`import { getToolkitApp } from './app'
3
3
  import { getAuth } from '@murumets-ee/auth'
4
4
 
5
5
  await getToolkitApp()
@@ -249,7 +249,7 @@ export async function createFirstAdmin(formData: FormData) {
249
249
 
250
250
  return { ok: true, email: adminUser.user.email }
251
251
  }
252
- `)}import{join as v}from"path";async function z(t,n){let{name:r}=n;await e(v(t,".env.example"),`DATABASE_URL=postgresql://${r}:${r}_dev_password@localhost:5432/${r}_dev
252
+ `)}import{join as p}from"path";async function S(t,n){let{name:r}=n;await e(p(t,".env.example"),`DATABASE_URL=postgresql://${r}:${r}_dev_password@localhost:5432/${r}_dev
253
253
  BETTER_AUTH_SECRET=dev-secret-change-me-in-production-min-32-chars
254
254
  BETTER_AUTH_URL=http://localhost:3000
255
255
  LOG_LEVEL=debug
@@ -259,14 +259,94 @@ RESEND_API_KEY=
259
259
  RESEND_WEBHOOK_SECRET=
260
260
  MAIL_FROM=noreply@example.com
261
261
  CSAT_SECRET=
262
- `),await A(v(t,".gitignore"),`
263
- # Toolkit generated files
264
- generated/
262
+ `),await e(p(t,".dockerignore"),`# Dependencies (installed inside Docker)
263
+ node_modules/
264
+ .pnpm-store/
265
265
 
266
- # Environment
267
- .env*
266
+ # Build outputs (rebuilt inside Docker)
267
+ .next/
268
+ out/
269
+ dist/
270
+
271
+ # Git
272
+ .git/
273
+ .gitignore
274
+
275
+ # Environment files (pass via docker run --env-file)
276
+ .env
277
+ .env.*
268
278
  !.env.example
269
- `),await e(v(t,"docker-compose.yml"),`services:
279
+
280
+ # Docker files
281
+ Dockerfile*
282
+ .dockerignore
283
+ docker-compose*.yml
284
+
285
+ # Tests
286
+ coverage/
287
+ **/*.test.*
288
+ **/*.spec.*
289
+ **/vitest.config.*
290
+ docker-compose.test.yml
291
+
292
+ # Development tooling
293
+ .vscode/
294
+ .idea/
295
+ .turbo/
296
+ .cache/
297
+ *.tsbuildinfo
298
+
299
+ # Documentation
300
+ *.md
301
+ docs/
302
+
303
+ # OS files
304
+ .DS_Store
305
+ Thumbs.db
306
+ `),await e(p(t,"Dockerfile"),`# --- Base image ---
307
+ # Node 22 LTS (Debian slim \u2014 glibc required for sharp image optimization)
308
+ FROM node:22-slim AS base
309
+
310
+ # --- Stage 1: Install dependencies ---
311
+ FROM base AS deps
312
+ WORKDIR /app
313
+ RUN corepack enable pnpm
314
+ COPY package.json pnpm-lock.yaml ./
315
+ RUN --mount=type=cache,id=pnpm,target=/root/.local/share/pnpm/store \\
316
+ pnpm install --frozen-lockfile
317
+
318
+ # --- Stage 2: Build the application ---
319
+ FROM base AS builder
320
+ WORKDIR /app
321
+ RUN corepack enable pnpm
322
+ COPY --from=deps /app/node_modules ./node_modules
323
+ COPY . .
324
+ ENV NODE_ENV=production
325
+ ENV NEXT_TELEMETRY_DISABLED=1
326
+ RUN pnpm build
327
+
328
+ # --- Stage 3: Production runner ---
329
+ FROM base AS runner
330
+ WORKDIR /app
331
+ ENV NODE_ENV=production
332
+ ENV PORT=3000
333
+ ENV HOSTNAME=0.0.0.0
334
+ ENV NEXT_TELEMETRY_DISABLED=1
335
+
336
+ # Copy standalone output (includes server.js + traced node_modules)
337
+ COPY --from=builder --chown=node:node /app/.next/standalone ./
338
+ # Copy static assets (JS/CSS chunks \u2014 excluded from standalone trace)
339
+ COPY --from=builder --chown=node:node /app/.next/static ./.next/static
340
+ # Copy public assets (favicon, robots.txt, images)
341
+ COPY --from=builder --chown=node:node /app/public ./public
342
+ # Copy migrations (applied at app startup by the toolkit migration runner)
343
+ COPY --from=builder --chown=node:node /app/migrations ./migrations
344
+
345
+ # Run as non-root user
346
+ USER node
347
+ EXPOSE 3000
348
+ CMD ["node", "server.js"]
349
+ `),await e(p(t,"docker-compose.yml"),`services:
270
350
  postgres:
271
351
  image: postgres:17-alpine
272
352
  container_name: ${r}-postgres
@@ -288,7 +368,49 @@ generated/
288
368
  volumes:
289
369
  postgres_data:
290
370
  name: ${r}_postgres_data
291
- `)}import{join as y}from"path";async function P(t,n){await e(y(t,"entities/index.ts"),`export { Article } from './article'
371
+ `),await e(p(t,"docker-compose.prod.yml"),`services:
372
+ app:
373
+ build: .
374
+ restart: unless-stopped
375
+ env_file: .env
376
+ depends_on:
377
+ postgres:
378
+ condition: service_healthy
379
+ ports:
380
+ - "3000:3000"
381
+ networks:
382
+ - internal
383
+
384
+ postgres:
385
+ image: postgres:17-alpine
386
+ restart: unless-stopped
387
+ environment:
388
+ POSTGRES_USER: ${r}
389
+ POSTGRES_PASSWORD: \${DB_PASSWORD}
390
+ POSTGRES_DB: ${r}
391
+ volumes:
392
+ - postgres_data:/var/lib/postgresql/data
393
+ healthcheck:
394
+ test: ["CMD-SHELL", "pg_isready -U ${r} -d ${r}"]
395
+ interval: 10s
396
+ timeout: 5s
397
+ retries: 5
398
+ networks:
399
+ - internal
400
+
401
+ volumes:
402
+ postgres_data:
403
+
404
+ networks:
405
+ internal:
406
+ `),await A(p(t,".gitignore"),`
407
+ # Toolkit generated files
408
+ generated/
409
+
410
+ # Environment
411
+ .env*
412
+ !.env.example
413
+ `)}import{join as y}from"path";async function E(t,n){await e(y(t,"entities/index.ts"),`export { Article } from './article'
292
414
  export { Category } from './category'
293
415
  `),await e(y(t,"entities/article.ts"),`import { behavior, defineEntity, field } from '@murumets-ee/entity'
294
416
 
@@ -338,13 +460,13 @@ export const Category = defineEntity({
338
460
  delete: 'group.admin',
339
461
  },
340
462
  })
341
- `)}import{join as S}from"path";async function E(t,n){await e(S(t,"i18n/routing.ts"),`import { defineRouting } from 'next-intl/routing'
463
+ `)}import{join as P}from"path";async function z(t,n){await e(P(t,"i18n/routing.ts"),`import { defineRouting } from 'next-intl/routing'
342
464
 
343
465
  export const routing = defineRouting({
344
466
  locales: ['en'],
345
467
  defaultLocale: 'en',
346
468
  })
347
- `),await e(S(t,"i18n/request.ts"),`import { getRequestConfig } from 'next-intl/server'
469
+ `),await e(P(t,"i18n/request.ts"),`import { getRequestConfig } from 'next-intl/server'
348
470
  import { hasLocale } from 'next-intl'
349
471
  import { routing } from './routing'
350
472
  import { getAuthMessages } from '@murumets-ee/auth-ui/i18n'
@@ -364,7 +486,7 @@ export default getRequestConfig(async ({ requestLocale }) => {
364
486
  },
365
487
  }
366
488
  })
367
- `)}import{mkdir as C}from"fs/promises";import{join as a}from"path";var i={myorgCore:"0.1.0",myorgDb:"0.1.0",myorgEntity:"0.1.0",myorgLogging:"0.1.0",myorgAuth:"0.1.0",myorgAuthUi:"0.1.0",myorgAdminUi:"0.1.0",myorgContent:"0.1.0",myorgContentApi:"0.1.0",myorgSettings:"0.1.0",myorgStorage:"0.1.0",myorgMedia:"0.1.0",myorgTaxonomy:"0.1.0",myorgQueue:"0.1.0",myorgMail:"0.1.0",myorgTicketing:"0.1.0",myorgTicketingUi:"0.1.0",myorgEditor:"0.1.0",myorgBlocks:"0.1.0",myorgTokens:"0.1.0",myorgUi:"0.1.0",myorgCli:"0.1.0",betterAuth:"1.4.0",drizzleOrm:"0.45.1",nextIntl:"4.8.2",nextThemes:"0.4.6",lucideReact:"0.563.0",postgres:"3.4.5",reactHookForm:"7.71.1",hookformResolvers:"5.2.2",zod:"3.24.1",drizzleKit:"0.27.2",tsx:"4.19.2",babelReactCompiler:"1.0.0"};async function R(t,n,r){await U(t,n),r?.("Workspace root created"),r?.("Creating admin app..."),await F(t,n),r?.("Admin app created"),r?.("Creating web app..."),await D(t,n),r?.("Web app created"),await I(t,n),r?.("Shared config package created")}async function U(t,n){let{name:r}=n;await C(t,{recursive:!0}),await e(a(t,"pnpm-workspace.yaml"),`packages:
489
+ `)}import{mkdir as R}from"fs/promises";import{join as a}from"path";var i={myorgCore:"0.1.0",myorgDb:"0.1.0",myorgEntity:"0.1.0",myorgLogging:"0.1.0",myorgAuth:"0.1.0",myorgAuthUi:"0.1.0",myorgAdminUi:"0.1.0",myorgContent:"0.1.0",myorgContentApi:"0.1.0",myorgSettings:"0.1.0",myorgStorage:"0.1.0",myorgMedia:"0.1.0",myorgTaxonomy:"0.1.0",myorgQueue:"0.1.0",myorgMail:"0.1.0",myorgTicketing:"0.1.0",myorgTicketingUi:"0.1.0",myorgEditor:"0.1.0",myorgBlocks:"0.1.0",myorgTokens:"0.1.0",myorgUi:"0.1.0",myorgCli:"0.1.0",betterAuth:"1.4.0",drizzleOrm:"0.45.1",nextIntl:"4.8.2",nextThemes:"0.4.6",lucideReact:"0.563.0",postgres:"3.4.5",reactHookForm:"7.71.1",hookformResolvers:"5.2.2",zod:"3.24.1",drizzleKit:"0.27.2",tsx:"4.19.2",babelReactCompiler:"1.0.0"};async function C(t,n,r){await U(t,n),r?.("Workspace root created"),r?.("Creating admin app..."),await F(t,n),r?.("Admin app created"),r?.("Creating web app..."),await D(t,n),r?.("Web app created"),await I(t,n),r?.("Shared config package created")}async function U(t,n){let{name:r}=n;await R(t,{recursive:!0}),await e(a(t,"pnpm-workspace.yaml"),`packages:
368
490
  - 'packages/*'
369
491
  - 'apps/*'
370
492
 
@@ -703,7 +825,7 @@ async function resetDb() {
703
825
  }
704
826
 
705
827
  resetDb().catch(console.error)
706
- `)}async function F(t,n){let{name:r}=n,o=a(t,"apps/admin");await C(a(t,"apps"),{recursive:!0}),u(`pnpm create next-app@${"16"} ${o} --typescript --tailwind --no-eslint --app --no-src-dir --turbopack --react-compiler --skip-install --import-alias "@/*"`),await d(o,["app/page.tsx","app/page.module.css","app/fonts","README.md","pnpm-workspace.yaml"]),await p(a(o,"package.json"),{dependencies:{[`@${r}/config`]:"workspace:*","@murumets-ee/auth-ui":`^${i.myorgAuthUi}`,"better-auth":`^${i.betterAuth}`,"next-intl":`^${i.nextIntl}`,"next-themes":`^${i.nextThemes}`,"lucide-react":`^${i.lucideReact}`,"react-hook-form":`^${i.reactHookForm}`,"@hookform/resolvers":`^${i.hookformResolvers}`,zod:`^${i.zod}`},devDependencies:{"babel-plugin-react-compiler":i.babelReactCompiler}});let{appendToFile:l}=await import("./utils-VX57GKZX.js");await l(a(o,".gitignore"),`
828
+ `)}async function F(t,n){let{name:r}=n,o=a(t,"apps/admin");await R(a(t,"apps"),{recursive:!0}),u(`pnpm create next-app@${"16"} ${o} --typescript --tailwind --no-eslint --app --no-src-dir --turbopack --react-compiler --skip-install --import-alias "@/*"`),await g(o,["app/page.tsx","app/page.module.css","app/fonts","README.md","pnpm-workspace.yaml"]),await d(a(o,"package.json"),{dependencies:{[`@${r}/config`]:"workspace:*","@murumets-ee/auth-ui":`^${i.myorgAuthUi}`,"better-auth":`^${i.betterAuth}`,"next-intl":`^${i.nextIntl}`,"next-themes":`^${i.nextThemes}`,"lucide-react":`^${i.lucideReact}`,"react-hook-form":`^${i.reactHookForm}`,"@hookform/resolvers":`^${i.hookformResolvers}`,zod:`^${i.zod}`},devDependencies:{"babel-plugin-react-compiler":i.babelReactCompiler}});let{appendToFile:l}=await import("./utils-VX57GKZX.js");await l(a(o,".gitignore"),`
707
829
  # Environment
708
830
  .env*
709
831
  !.env.example
@@ -1251,7 +1373,7 @@ export async function createFirstAdmin(formData: FormData) {
1251
1373
 
1252
1374
  return { ok: true, email: adminUser.user.email }
1253
1375
  }
1254
- `)}async function D(t,n){let{name:r}=n,o=a(t,"apps/web");u(`pnpm create next-app@${"16"} ${o} --typescript --tailwind --no-eslint --app --no-src-dir --turbopack --react-compiler --skip-install --import-alias "@/*"`),await d(o,["app/page.tsx","app/page.module.css","app/fonts","README.md","pnpm-workspace.yaml"]),await p(a(o,"package.json"),{dependencies:{[`@${r}/config`]:"workspace:*","@murumets-ee/core":`^${i.myorgCore}`,"@murumets-ee/auth-ui":`^${i.myorgAuthUi}`,"next-intl":`^${i.nextIntl}`,"next-themes":`^${i.nextThemes}`,"lucide-react":`^${i.lucideReact}`},devDependencies:{"babel-plugin-react-compiler":i.babelReactCompiler}});let{appendToFile:l}=await import("./utils-VX57GKZX.js");await l(a(o,".gitignore"),`
1376
+ `)}async function D(t,n){let{name:r}=n,o=a(t,"apps/web");u(`pnpm create next-app@${"16"} ${o} --typescript --tailwind --no-eslint --app --no-src-dir --turbopack --react-compiler --skip-install --import-alias "@/*"`),await g(o,["app/page.tsx","app/page.module.css","app/fonts","README.md","pnpm-workspace.yaml"]),await d(a(o,"package.json"),{dependencies:{[`@${r}/config`]:"workspace:*","@murumets-ee/core":`^${i.myorgCore}`,"@murumets-ee/auth-ui":`^${i.myorgAuthUi}`,"next-intl":`^${i.nextIntl}`,"next-themes":`^${i.nextThemes}`,"lucide-react":`^${i.lucideReact}`},devDependencies:{"babel-plugin-react-compiler":i.babelReactCompiler}});let{appendToFile:l}=await import("./utils-VX57GKZX.js");await l(a(o,".gitignore"),`
1255
1377
  # Environment
1256
1378
  .env*
1257
1379
  !.env.example
@@ -1539,7 +1661,7 @@ export default async function HomePage() {
1539
1661
  </div>
1540
1662
  )
1541
1663
  }
1542
- `)}import{join as g}from"path";async function L(t,n){let{name:r}=n;await e(g(t,"next.config.ts"),`import type { NextConfig } from 'next'
1664
+ `)}import{join as f}from"path";async function L(t,n){let{name:r}=n;await e(f(t,"next.config.ts"),`import type { NextConfig } from 'next'
1543
1665
  import createNextIntlPlugin from 'next-intl/plugin'
1544
1666
 
1545
1667
  const withNextIntl = createNextIntlPlugin('./i18n/request.ts')
@@ -1564,7 +1686,7 @@ const nextConfig: NextConfig = {
1564
1686
  }
1565
1687
 
1566
1688
  export default withNextIntl(nextConfig)
1567
- `),await e(g(t,"proxy.ts"),`import { NextRequest, NextResponse } from 'next/server'
1689
+ `),await e(f(t,"proxy.ts"),`import { NextRequest, NextResponse } from 'next/server'
1568
1690
  import createMiddleware from 'next-intl/middleware'
1569
1691
  import { routing } from './i18n/routing'
1570
1692
 
@@ -1595,12 +1717,12 @@ export function proxy(request: NextRequest) {
1595
1717
  export const config = {
1596
1718
  matcher: '/((?!api|_next|_vercel|.*\\\\..*).*)',
1597
1719
  }
1598
- `),await e(g(t,"app/layout.tsx"),`import './globals.css'
1720
+ `),await e(f(t,"app/layout.tsx"),`import './globals.css'
1599
1721
 
1600
1722
  export default function RootLayout({ children }: { children: React.ReactNode }) {
1601
1723
  return children
1602
1724
  }
1603
- `),await e(g(t,"app/[locale]/layout.tsx"),`import type { Metadata } from 'next'
1725
+ `),await e(f(t,"app/[locale]/layout.tsx"),`import type { Metadata } from 'next'
1604
1726
  import { Geist, Geist_Mono } from 'next/font/google'
1605
1727
  import { NextIntlClientProvider } from 'next-intl'
1606
1728
  import { getMessages } from 'next-intl/server'
@@ -1649,7 +1771,7 @@ export default async function LocaleLayout({
1649
1771
  </html>
1650
1772
  )
1651
1773
  }
1652
- `),await e(g(t,"app/[locale]/page.tsx"),`import { createQueryClient } from '@murumets-ee/core/clients'
1774
+ `),await e(f(t,"app/[locale]/page.tsx"),`import { createQueryClient } from '@murumets-ee/core/clients'
1653
1775
  import { Article, Category } from '@/entities'
1654
1776
  import { getToolkitApp } from '@/lib/app'
1655
1777
 
@@ -1719,7 +1841,7 @@ execSync('npx @murumets-ee/cli generate', { stdio: 'inherit', cwd: import.meta.d
1719
1841
  execSync('npx @murumets-ee/cli migrate', { stdio: 'inherit', cwd: import.meta.dirname + '/..' })
1720
1842
  `),await e(w(t,"scripts/reset-db.ts"),`import { execSync } from 'node:child_process'
1721
1843
  execSync('npx @murumets-ee/cli reset --force', { stdio: 'inherit', cwd: import.meta.dirname + '/..' })
1722
- `)}import{join as x}from"path";async function $(t,n){let{name:r}=n;await e(x(t,"app/globals.css"),`@import "tailwindcss";
1844
+ `)}import{join as b}from"path";async function $(t,n){let{name:r}=n;await e(b(t,"app/globals.css"),`@import "tailwindcss";
1723
1845
  @source "../node_modules/@murumets-ee/auth-ui/dist";
1724
1846
 
1725
1847
  @custom-variant dark (&:where(.dark, .dark *));
@@ -1746,7 +1868,7 @@ body {
1746
1868
  color: var(--foreground);
1747
1869
  font-family: Arial, Helvetica, sans-serif;
1748
1870
  }
1749
- `),await e(x(t,"app/theme-provider.tsx"),`'use client'
1871
+ `),await e(b(t,"app/theme-provider.tsx"),`'use client'
1750
1872
 
1751
1873
  import { ThemeProvider as NextThemesProvider } from 'next-themes'
1752
1874
  import type { ReactNode } from 'react'
@@ -1763,7 +1885,7 @@ export function ThemeProvider({ children }: { children: ReactNode }) {
1763
1885
  </NextThemesProvider>
1764
1886
  )
1765
1887
  }
1766
- `),await e(x(t,"app/theme-toggle.tsx"),`'use client'
1888
+ `),await e(b(t,"app/theme-toggle.tsx"),`'use client'
1767
1889
 
1768
1890
  import { useTheme } from 'next-themes'
1769
1891
  import { useState, useEffect } from 'react'
@@ -1790,7 +1912,7 @@ export function ThemeToggle() {
1790
1912
  </button>
1791
1913
  )
1792
1914
  }
1793
- `),await e(x(t,"app/nav-header.tsx"),`'use client'
1915
+ `),await e(b(t,"app/nav-header.tsx"),`'use client'
1794
1916
 
1795
1917
  import Link from 'next/link'
1796
1918
  import { usePathname } from 'next/navigation'
@@ -1834,7 +1956,7 @@ export function NavHeader() {
1834
1956
  </header>
1835
1957
  )
1836
1958
  }
1837
- `)}import{join as f}from"path";async function M(t,n){let{name:r}=n;await e(f(t,"toolkit.config.ts"),`import { auth } from '@murumets-ee/auth/plugin'
1959
+ `)}import{join as h}from"path";async function M(t,n){let{name:r}=n;await e(h(t,"toolkit.config.ts"),`import { auth } from '@murumets-ee/auth/plugin'
1838
1960
  import { content } from '@murumets-ee/content/plugin'
1839
1961
  import { defineConfig } from '@murumets-ee/core'
1840
1962
  import { mail, ResendMailProvider } from '@murumets-ee/mail'
@@ -1886,7 +2008,7 @@ export default defineConfig({
1886
2008
  ],
1887
2009
  projectRoot: import.meta.dirname,
1888
2010
  })
1889
- `),await e(f(t,"lib/app.ts"),`import { createApp, setApp, type ToolkitApp } from '@murumets-ee/core'
2011
+ `),await e(h(t,"lib/app.ts"),`import { createApp, setApp, type ToolkitApp } from '@murumets-ee/core'
1890
2012
  import config from '../toolkit.config'
1891
2013
 
1892
2014
  let appInstance: ToolkitApp | null = null
@@ -1900,7 +2022,7 @@ export async function getToolkitApp(): Promise<ToolkitApp> {
1900
2022
  }
1901
2023
  return appInstance
1902
2024
  }
1903
- `),await e(f(t,"drizzle.config.ts"),`import type { Config } from 'drizzle-kit'
2025
+ `),await e(h(t,"drizzle.config.ts"),`import type { Config } from 'drizzle-kit'
1904
2026
 
1905
2027
  if (!process.env.DATABASE_URL) {
1906
2028
  throw new Error('DATABASE_URL environment variable is required')
@@ -1914,7 +2036,7 @@ export default {
1914
2036
  url: process.env.DATABASE_URL,
1915
2037
  },
1916
2038
  } satisfies Config
1917
- `),await e(f(t,"auth.config.ts"),`import { betterAuth } from 'better-auth'
2039
+ `),await e(h(t,"auth.config.ts"),`import { betterAuth } from 'better-auth'
1918
2040
  import { drizzleAdapter } from 'better-auth/adapters/drizzle'
1919
2041
  import { admin } from 'better-auth/plugins'
1920
2042
  import { organization } from 'better-auth/plugins/organization'
@@ -1932,8 +2054,8 @@ export const auth = betterAuth({
1932
2054
  organization(),
1933
2055
  ],
1934
2056
  })
1935
- `),await e(f(t,"generated/auth-schema.ts"),`// This file is generated by better-auth CLI.
2057
+ `),await e(h(t,"generated/auth-schema.ts"),`// This file is generated by better-auth CLI.
1936
2058
  // Run: npx @better-auth/cli generate --config auth.config.ts -y
1937
2059
  export {}
1938
- `)}async function q(t,n){t.mode==="single"?await B(t,n):await H(t,n)}async function B(t,n){let r=k(process.cwd(),t.name);n?.("Creating Next.js app..."),u(`pnpm create next-app@${"16"} ${t.name} --typescript --tailwind --no-eslint --app --no-src-dir --turbopack --react-compiler --skip-install --import-alias "@/*"`),await d(r,["app/page.tsx","app/page.module.css","app/fonts","README.md"]),await p(k(r,"package.json"),{type:"module",dependencies:{"@murumets-ee/core":`^${i.myorgCore}`,"@murumets-ee/db":`^${i.myorgDb}`,"@murumets-ee/entity":`^${i.myorgEntity}`,"@murumets-ee/logging":`^${i.myorgLogging}`,"@murumets-ee/auth":`^${i.myorgAuth}`,"@murumets-ee/auth-ui":`^${i.myorgAuthUi}`,"@murumets-ee/admin-ui":`^${i.myorgAdminUi}`,"@murumets-ee/content":`^${i.myorgContent}`,"@murumets-ee/settings":`^${i.myorgSettings}`,"@murumets-ee/storage":`^${i.myorgStorage}`,"@murumets-ee/media":`^${i.myorgMedia}`,"@murumets-ee/taxonomy":`^${i.myorgTaxonomy}`,"@murumets-ee/queue":`^${i.myorgQueue}`,"@murumets-ee/mail":`^${i.myorgMail}`,"@murumets-ee/ticketing":`^${i.myorgTicketing}`,"@murumets-ee/ticketing-ui":`^${i.myorgTicketingUi}`,"@murumets-ee/tokens":`^${i.myorgTokens}`,"better-auth":`^${i.betterAuth}`,"drizzle-orm":`^${i.drizzleOrm}`,"next-intl":`^${i.nextIntl}`,"next-themes":`^${i.nextThemes}`,"lucide-react":`^${i.lucideReact}`,postgres:`^${i.postgres}`,"react-hook-form":`^${i.reactHookForm}`,"@hookform/resolvers":`^${i.hookformResolvers}`,zod:`^${i.zod}`},devDependencies:{"drizzle-kit":`^${i.drizzleKit}`,tsx:`^${i.tsx}`,"babel-plugin-react-compiler":i.babelReactCompiler},scripts:{"db:generate":"tsx --env-file=.env scripts/generate-schema.ts","db:migrate:generate":"drizzle-kit generate","db:migrate":"tsx --env-file=.env scripts/migrate.ts","db:reset":"tsx --env-file=.env scripts/reset-db.ts"}}),n?.("Adding toolkit files..."),await z(r,t),await P(r,t),await M(r,t),await T(r,t),await E(r,t),await L(r,t),await $(r,t),await _(r,t),t.installDeps&&(n?.("Installing dependencies..."),u("pnpm install",{cwd:r}))}async function H(t,n){let r=k(process.cwd(),t.name);n?.("Creating workspace..."),await R(r,t,n),t.installDeps&&(n?.("Installing dependencies..."),u("pnpm install",{cwd:r}))}async function j(){let t=process.argv[2],n=await N(t);if(!n)return;let r=c.spinner();try{r.start("Creating Next.js app..."),await q(n,O=>{r.stop(`${b.green("\u2713")} Done`),r.start(O)}),r.stop(`${b.green("\u2713")} Done`);let l=n.mode==="multi"?[`cd ${n.name}`,"docker compose up -d","cp .env.example .env","npx @better-auth/cli generate --config packages/config/auth.config.ts -y","pnpm db:generate","pnpm db:migrate:generate","pnpm db:migrate","pnpm dev","# Visit /setup to create your first admin user"]:[`cd ${n.name}`,"docker compose up -d","cp .env.example .env","npx @better-auth/cli generate --config auth.config.ts -y","pnpm db:generate","pnpm db:migrate:generate","pnpm db:migrate","pnpm dev","# Visit /setup to create your first admin user"];c.note(l.join(`
1939
- `),"Next steps"),c.outro(`${b.green("Success!")} Your project is ready.`)}catch(o){r.stop(b.red("Failed.")),c.log.error(o instanceof Error?o.message:String(o)),process.exit(1)}}j();
2060
+ `)}async function O(t,n){t.mode==="single"?await B(t,n):await H(t,n)}async function B(t,n){let r=k(process.cwd(),t.name);n?.("Creating Next.js app..."),u(`pnpm create next-app@${"16"} ${t.name} --typescript --tailwind --no-eslint --app --no-src-dir --turbopack --react-compiler --skip-install --import-alias "@/*"`),await g(r,["app/page.tsx","app/page.module.css","app/fonts","README.md"]),await d(k(r,"package.json"),{type:"module",dependencies:{"@murumets-ee/core":`^${i.myorgCore}`,"@murumets-ee/db":`^${i.myorgDb}`,"@murumets-ee/entity":`^${i.myorgEntity}`,"@murumets-ee/logging":`^${i.myorgLogging}`,"@murumets-ee/auth":`^${i.myorgAuth}`,"@murumets-ee/auth-ui":`^${i.myorgAuthUi}`,"@murumets-ee/admin-ui":`^${i.myorgAdminUi}`,"@murumets-ee/content":`^${i.myorgContent}`,"@murumets-ee/settings":`^${i.myorgSettings}`,"@murumets-ee/storage":`^${i.myorgStorage}`,"@murumets-ee/media":`^${i.myorgMedia}`,"@murumets-ee/taxonomy":`^${i.myorgTaxonomy}`,"@murumets-ee/queue":`^${i.myorgQueue}`,"@murumets-ee/mail":`^${i.myorgMail}`,"@murumets-ee/ticketing":`^${i.myorgTicketing}`,"@murumets-ee/ticketing-ui":`^${i.myorgTicketingUi}`,"@murumets-ee/tokens":`^${i.myorgTokens}`,"better-auth":`^${i.betterAuth}`,"drizzle-orm":`^${i.drizzleOrm}`,"next-intl":`^${i.nextIntl}`,"next-themes":`^${i.nextThemes}`,"lucide-react":`^${i.lucideReact}`,postgres:`^${i.postgres}`,"react-hook-form":`^${i.reactHookForm}`,"@hookform/resolvers":`^${i.hookformResolvers}`,zod:`^${i.zod}`},devDependencies:{"drizzle-kit":`^${i.drizzleKit}`,tsx:`^${i.tsx}`,"babel-plugin-react-compiler":i.babelReactCompiler},scripts:{"db:generate":"tsx --env-file=.env scripts/generate-schema.ts","db:migrate:generate":"drizzle-kit generate","db:migrate":"tsx --env-file=.env scripts/migrate.ts","db:reset":"tsx --env-file=.env scripts/reset-db.ts"}}),n?.("Adding toolkit files..."),await S(r,t),await E(r,t),await M(r,t),await T(r,t),await z(r,t),await L(r,t),await $(r,t),await _(r,t),t.installDeps&&(n?.("Installing dependencies..."),u("pnpm install",{cwd:r}))}async function H(t,n){let r=k(process.cwd(),t.name);n?.("Creating workspace..."),await C(r,t,n),t.installDeps&&(n?.("Installing dependencies..."),u("pnpm install",{cwd:r}))}async function W(){let t=process.argv[2],n=await N(t);if(!n)return;let r=c.spinner();try{r.start("Creating Next.js app..."),await O(n,q=>{r.stop(`${v.green("\u2713")} Done`),r.start(q)}),r.stop(`${v.green("\u2713")} Done`);let l=n.mode==="multi"?[`cd ${n.name}`,"docker compose up -d","cp .env.example .env","npx @better-auth/cli generate --config packages/config/auth.config.ts -y","pnpm db:generate","pnpm db:migrate:generate","pnpm db:migrate","pnpm dev","# Visit /setup to create your first admin user"]:[`cd ${n.name}`,"docker compose up -d","cp .env.example .env","npx @better-auth/cli generate --config auth.config.ts -y","pnpm db:generate","pnpm db:migrate:generate","pnpm db:migrate","pnpm dev","# Visit /setup to create your first admin user"];c.note(l.join(`
2061
+ `),"Next steps"),c.outro(`${v.green("Success!")} Your project is ready.`)}catch(o){r.stop(v.red("Failed.")),c.log.error(o instanceof Error?o.message:String(o)),process.exit(1)}}W();
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import{a as e,b as l,c,d as m,e as y}from"./chunk-CUB6XFPE.js";import{join as v}from"path";import{join as s}from"path";async function w(t,n){await e(s(t,"lib/auth.ts"),`import { getToolkitApp } from './app'
1
+ import{a as e,b as c,c as u,d as l,e as y}from"./chunk-CUB6XFPE.js";import{join as v}from"path";import{join as s}from"path";async function w(t,n){await e(s(t,"lib/auth.ts"),`import { getToolkitApp } from './app'
2
2
  import { getAuth } from '@murumets-ee/auth'
3
3
 
4
4
  await getToolkitApp()
@@ -248,7 +248,7 @@ export async function createFirstAdmin(formData: FormData) {
248
248
 
249
249
  return { ok: true, email: adminUser.user.email }
250
250
  }
251
- `)}import{join as h}from"path";async function k(t,n){let{name:r}=n;await e(h(t,".env.example"),`DATABASE_URL=postgresql://${r}:${r}_dev_password@localhost:5432/${r}_dev
251
+ `)}import{join as m}from"path";async function k(t,n){let{name:r}=n;await e(m(t,".env.example"),`DATABASE_URL=postgresql://${r}:${r}_dev_password@localhost:5432/${r}_dev
252
252
  BETTER_AUTH_SECRET=dev-secret-change-me-in-production-min-32-chars
253
253
  BETTER_AUTH_URL=http://localhost:3000
254
254
  LOG_LEVEL=debug
@@ -258,14 +258,94 @@ RESEND_API_KEY=
258
258
  RESEND_WEBHOOK_SECRET=
259
259
  MAIL_FROM=noreply@example.com
260
260
  CSAT_SECRET=
261
- `),await y(h(t,".gitignore"),`
262
- # Toolkit generated files
263
- generated/
261
+ `),await e(m(t,".dockerignore"),`# Dependencies (installed inside Docker)
262
+ node_modules/
263
+ .pnpm-store/
264
264
 
265
- # Environment
266
- .env*
265
+ # Build outputs (rebuilt inside Docker)
266
+ .next/
267
+ out/
268
+ dist/
269
+
270
+ # Git
271
+ .git/
272
+ .gitignore
273
+
274
+ # Environment files (pass via docker run --env-file)
275
+ .env
276
+ .env.*
267
277
  !.env.example
268
- `),await e(h(t,"docker-compose.yml"),`services:
278
+
279
+ # Docker files
280
+ Dockerfile*
281
+ .dockerignore
282
+ docker-compose*.yml
283
+
284
+ # Tests
285
+ coverage/
286
+ **/*.test.*
287
+ **/*.spec.*
288
+ **/vitest.config.*
289
+ docker-compose.test.yml
290
+
291
+ # Development tooling
292
+ .vscode/
293
+ .idea/
294
+ .turbo/
295
+ .cache/
296
+ *.tsbuildinfo
297
+
298
+ # Documentation
299
+ *.md
300
+ docs/
301
+
302
+ # OS files
303
+ .DS_Store
304
+ Thumbs.db
305
+ `),await e(m(t,"Dockerfile"),`# --- Base image ---
306
+ # Node 22 LTS (Debian slim \u2014 glibc required for sharp image optimization)
307
+ FROM node:22-slim AS base
308
+
309
+ # --- Stage 1: Install dependencies ---
310
+ FROM base AS deps
311
+ WORKDIR /app
312
+ RUN corepack enable pnpm
313
+ COPY package.json pnpm-lock.yaml ./
314
+ RUN --mount=type=cache,id=pnpm,target=/root/.local/share/pnpm/store \\
315
+ pnpm install --frozen-lockfile
316
+
317
+ # --- Stage 2: Build the application ---
318
+ FROM base AS builder
319
+ WORKDIR /app
320
+ RUN corepack enable pnpm
321
+ COPY --from=deps /app/node_modules ./node_modules
322
+ COPY . .
323
+ ENV NODE_ENV=production
324
+ ENV NEXT_TELEMETRY_DISABLED=1
325
+ RUN pnpm build
326
+
327
+ # --- Stage 3: Production runner ---
328
+ FROM base AS runner
329
+ WORKDIR /app
330
+ ENV NODE_ENV=production
331
+ ENV PORT=3000
332
+ ENV HOSTNAME=0.0.0.0
333
+ ENV NEXT_TELEMETRY_DISABLED=1
334
+
335
+ # Copy standalone output (includes server.js + traced node_modules)
336
+ COPY --from=builder --chown=node:node /app/.next/standalone ./
337
+ # Copy static assets (JS/CSS chunks \u2014 excluded from standalone trace)
338
+ COPY --from=builder --chown=node:node /app/.next/static ./.next/static
339
+ # Copy public assets (favicon, robots.txt, images)
340
+ COPY --from=builder --chown=node:node /app/public ./public
341
+ # Copy migrations (applied at app startup by the toolkit migration runner)
342
+ COPY --from=builder --chown=node:node /app/migrations ./migrations
343
+
344
+ # Run as non-root user
345
+ USER node
346
+ EXPOSE 3000
347
+ CMD ["node", "server.js"]
348
+ `),await e(m(t,"docker-compose.yml"),`services:
269
349
  postgres:
270
350
  image: postgres:17-alpine
271
351
  container_name: ${r}-postgres
@@ -287,6 +367,48 @@ generated/
287
367
  volumes:
288
368
  postgres_data:
289
369
  name: ${r}_postgres_data
370
+ `),await e(m(t,"docker-compose.prod.yml"),`services:
371
+ app:
372
+ build: .
373
+ restart: unless-stopped
374
+ env_file: .env
375
+ depends_on:
376
+ postgres:
377
+ condition: service_healthy
378
+ ports:
379
+ - "3000:3000"
380
+ networks:
381
+ - internal
382
+
383
+ postgres:
384
+ image: postgres:17-alpine
385
+ restart: unless-stopped
386
+ environment:
387
+ POSTGRES_USER: ${r}
388
+ POSTGRES_PASSWORD: \${DB_PASSWORD}
389
+ POSTGRES_DB: ${r}
390
+ volumes:
391
+ - postgres_data:/var/lib/postgresql/data
392
+ healthcheck:
393
+ test: ["CMD-SHELL", "pg_isready -U ${r} -d ${r}"]
394
+ interval: 10s
395
+ timeout: 5s
396
+ retries: 5
397
+ networks:
398
+ - internal
399
+
400
+ volumes:
401
+ postgres_data:
402
+
403
+ networks:
404
+ internal:
405
+ `),await y(m(t,".gitignore"),`
406
+ # Toolkit generated files
407
+ generated/
408
+
409
+ # Environment
410
+ .env*
411
+ !.env.example
290
412
  `)}import{join as x}from"path";async function A(t,n){await e(x(t,"entities/index.ts"),`export { Article } from './article'
291
413
  export { Category } from './category'
292
414
  `),await e(x(t,"entities/article.ts"),`import { behavior, defineEntity, field } from '@murumets-ee/entity'
@@ -363,7 +485,7 @@ export default getRequestConfig(async ({ requestLocale }) => {
363
485
  },
364
486
  }
365
487
  })
366
- `)}import{mkdir as z}from"fs/promises";import{join as o}from"path";var i={myorgCore:"0.1.0",myorgDb:"0.1.0",myorgEntity:"0.1.0",myorgLogging:"0.1.0",myorgAuth:"0.1.0",myorgAuthUi:"0.1.0",myorgAdminUi:"0.1.0",myorgContent:"0.1.0",myorgContentApi:"0.1.0",myorgSettings:"0.1.0",myorgStorage:"0.1.0",myorgMedia:"0.1.0",myorgTaxonomy:"0.1.0",myorgQueue:"0.1.0",myorgMail:"0.1.0",myorgTicketing:"0.1.0",myorgTicketingUi:"0.1.0",myorgEditor:"0.1.0",myorgBlocks:"0.1.0",myorgTokens:"0.1.0",myorgUi:"0.1.0",myorgCli:"0.1.0",betterAuth:"1.4.0",drizzleOrm:"0.45.1",nextIntl:"4.8.2",nextThemes:"0.4.6",lucideReact:"0.563.0",postgres:"3.4.5",reactHookForm:"7.71.1",hookformResolvers:"5.2.2",zod:"3.24.1",drizzleKit:"0.27.2",tsx:"4.19.2",babelReactCompiler:"1.0.0"};async function P(t,n,r){await L(t,n),r?.("Workspace root created"),r?.("Creating admin app..."),await $(t,n),r?.("Admin app created"),r?.("Creating web app..."),await M(t,n),r?.("Web app created"),await _(t,n),r?.("Shared config package created")}async function L(t,n){let{name:r}=n;await z(t,{recursive:!0}),await e(o(t,"pnpm-workspace.yaml"),`packages:
488
+ `)}import{mkdir as S}from"fs/promises";import{join as o}from"path";var i={myorgCore:"0.1.0",myorgDb:"0.1.0",myorgEntity:"0.1.0",myorgLogging:"0.1.0",myorgAuth:"0.1.0",myorgAuthUi:"0.1.0",myorgAdminUi:"0.1.0",myorgContent:"0.1.0",myorgContentApi:"0.1.0",myorgSettings:"0.1.0",myorgStorage:"0.1.0",myorgMedia:"0.1.0",myorgTaxonomy:"0.1.0",myorgQueue:"0.1.0",myorgMail:"0.1.0",myorgTicketing:"0.1.0",myorgTicketingUi:"0.1.0",myorgEditor:"0.1.0",myorgBlocks:"0.1.0",myorgTokens:"0.1.0",myorgUi:"0.1.0",myorgCli:"0.1.0",betterAuth:"1.4.0",drizzleOrm:"0.45.1",nextIntl:"4.8.2",nextThemes:"0.4.6",lucideReact:"0.563.0",postgres:"3.4.5",reactHookForm:"7.71.1",hookformResolvers:"5.2.2",zod:"3.24.1",drizzleKit:"0.27.2",tsx:"4.19.2",babelReactCompiler:"1.0.0"};async function E(t,n,r){await L(t,n),r?.("Workspace root created"),r?.("Creating admin app..."),await $(t,n),r?.("Admin app created"),r?.("Creating web app..."),await M(t,n),r?.("Web app created"),await _(t,n),r?.("Shared config package created")}async function L(t,n){let{name:r}=n;await S(t,{recursive:!0}),await e(o(t,"pnpm-workspace.yaml"),`packages:
367
489
  - 'packages/*'
368
490
  - 'apps/*'
369
491
 
@@ -702,7 +824,7 @@ async function resetDb() {
702
824
  }
703
825
 
704
826
  resetDb().catch(console.error)
705
- `)}async function $(t,n){let{name:r}=n,a=o(t,"apps/admin");await z(o(t,"apps"),{recursive:!0}),m(`pnpm create next-app@${"16"} ${a} --typescript --tailwind --no-eslint --app --no-src-dir --turbopack --react-compiler --skip-install --import-alias "@/*"`),await c(a,["app/page.tsx","app/page.module.css","app/fonts","README.md","pnpm-workspace.yaml"]),await l(o(a,"package.json"),{dependencies:{[`@${r}/config`]:"workspace:*","@murumets-ee/auth-ui":`^${i.myorgAuthUi}`,"better-auth":`^${i.betterAuth}`,"next-intl":`^${i.nextIntl}`,"next-themes":`^${i.nextThemes}`,"lucide-react":`^${i.lucideReact}`,"react-hook-form":`^${i.reactHookForm}`,"@hookform/resolvers":`^${i.hookformResolvers}`,zod:`^${i.zod}`},devDependencies:{"babel-plugin-react-compiler":i.babelReactCompiler}});let{appendToFile:f}=await import("./utils-42K2ZGUL.js");await f(o(a,".gitignore"),`
827
+ `)}async function $(t,n){let{name:r}=n,a=o(t,"apps/admin");await S(o(t,"apps"),{recursive:!0}),l(`pnpm create next-app@${"16"} ${a} --typescript --tailwind --no-eslint --app --no-src-dir --turbopack --react-compiler --skip-install --import-alias "@/*"`),await u(a,["app/page.tsx","app/page.module.css","app/fonts","README.md","pnpm-workspace.yaml"]),await c(o(a,"package.json"),{dependencies:{[`@${r}/config`]:"workspace:*","@murumets-ee/auth-ui":`^${i.myorgAuthUi}`,"better-auth":`^${i.betterAuth}`,"next-intl":`^${i.nextIntl}`,"next-themes":`^${i.nextThemes}`,"lucide-react":`^${i.lucideReact}`,"react-hook-form":`^${i.reactHookForm}`,"@hookform/resolvers":`^${i.hookformResolvers}`,zod:`^${i.zod}`},devDependencies:{"babel-plugin-react-compiler":i.babelReactCompiler}});let{appendToFile:h}=await import("./utils-42K2ZGUL.js");await h(o(a,".gitignore"),`
706
828
  # Environment
707
829
  .env*
708
830
  !.env.example
@@ -1250,7 +1372,7 @@ export async function createFirstAdmin(formData: FormData) {
1250
1372
 
1251
1373
  return { ok: true, email: adminUser.user.email }
1252
1374
  }
1253
- `)}async function M(t,n){let{name:r}=n,a=o(t,"apps/web");m(`pnpm create next-app@${"16"} ${a} --typescript --tailwind --no-eslint --app --no-src-dir --turbopack --react-compiler --skip-install --import-alias "@/*"`),await c(a,["app/page.tsx","app/page.module.css","app/fonts","README.md","pnpm-workspace.yaml"]),await l(o(a,"package.json"),{dependencies:{[`@${r}/config`]:"workspace:*","@murumets-ee/core":`^${i.myorgCore}`,"@murumets-ee/auth-ui":`^${i.myorgAuthUi}`,"next-intl":`^${i.nextIntl}`,"next-themes":`^${i.nextThemes}`,"lucide-react":`^${i.lucideReact}`},devDependencies:{"babel-plugin-react-compiler":i.babelReactCompiler}});let{appendToFile:f}=await import("./utils-42K2ZGUL.js");await f(o(a,".gitignore"),`
1375
+ `)}async function M(t,n){let{name:r}=n,a=o(t,"apps/web");l(`pnpm create next-app@${"16"} ${a} --typescript --tailwind --no-eslint --app --no-src-dir --turbopack --react-compiler --skip-install --import-alias "@/*"`),await u(a,["app/page.tsx","app/page.module.css","app/fonts","README.md","pnpm-workspace.yaml"]),await c(o(a,"package.json"),{dependencies:{[`@${r}/config`]:"workspace:*","@murumets-ee/core":`^${i.myorgCore}`,"@murumets-ee/auth-ui":`^${i.myorgAuthUi}`,"next-intl":`^${i.nextIntl}`,"next-themes":`^${i.nextThemes}`,"lucide-react":`^${i.lucideReact}`},devDependencies:{"babel-plugin-react-compiler":i.babelReactCompiler}});let{appendToFile:h}=await import("./utils-42K2ZGUL.js");await h(o(a,".gitignore"),`
1254
1376
  # Environment
1255
1377
  .env*
1256
1378
  !.env.example
@@ -1538,7 +1660,7 @@ export default async function HomePage() {
1538
1660
  </div>
1539
1661
  )
1540
1662
  }
1541
- `)}import{join as u}from"path";async function S(t,n){let{name:r}=n;await e(u(t,"next.config.ts"),`import type { NextConfig } from 'next'
1663
+ `)}import{join as p}from"path";async function P(t,n){let{name:r}=n;await e(p(t,"next.config.ts"),`import type { NextConfig } from 'next'
1542
1664
  import createNextIntlPlugin from 'next-intl/plugin'
1543
1665
 
1544
1666
  const withNextIntl = createNextIntlPlugin('./i18n/request.ts')
@@ -1563,7 +1685,7 @@ const nextConfig: NextConfig = {
1563
1685
  }
1564
1686
 
1565
1687
  export default withNextIntl(nextConfig)
1566
- `),await e(u(t,"proxy.ts"),`import { NextRequest, NextResponse } from 'next/server'
1688
+ `),await e(p(t,"proxy.ts"),`import { NextRequest, NextResponse } from 'next/server'
1567
1689
  import createMiddleware from 'next-intl/middleware'
1568
1690
  import { routing } from './i18n/routing'
1569
1691
 
@@ -1594,12 +1716,12 @@ export function proxy(request: NextRequest) {
1594
1716
  export const config = {
1595
1717
  matcher: '/((?!api|_next|_vercel|.*\\\\..*).*)',
1596
1718
  }
1597
- `),await e(u(t,"app/layout.tsx"),`import './globals.css'
1719
+ `),await e(p(t,"app/layout.tsx"),`import './globals.css'
1598
1720
 
1599
1721
  export default function RootLayout({ children }: { children: React.ReactNode }) {
1600
1722
  return children
1601
1723
  }
1602
- `),await e(u(t,"app/[locale]/layout.tsx"),`import type { Metadata } from 'next'
1724
+ `),await e(p(t,"app/[locale]/layout.tsx"),`import type { Metadata } from 'next'
1603
1725
  import { Geist, Geist_Mono } from 'next/font/google'
1604
1726
  import { NextIntlClientProvider } from 'next-intl'
1605
1727
  import { getMessages } from 'next-intl/server'
@@ -1648,7 +1770,7 @@ export default async function LocaleLayout({
1648
1770
  </html>
1649
1771
  )
1650
1772
  }
1651
- `),await e(u(t,"app/[locale]/page.tsx"),`import { createQueryClient } from '@murumets-ee/core/clients'
1773
+ `),await e(p(t,"app/[locale]/page.tsx"),`import { createQueryClient } from '@murumets-ee/core/clients'
1652
1774
  import { Article, Category } from '@/entities'
1653
1775
  import { getToolkitApp } from '@/lib/app'
1654
1776
 
@@ -1712,13 +1834,13 @@ export default async function HomePage() {
1712
1834
  </div>
1713
1835
  )
1714
1836
  }
1715
- `)}import{join as b}from"path";async function E(t,n){await e(b(t,"scripts/generate-schema.ts"),`import { execSync } from 'node:child_process'
1837
+ `)}import{join as b}from"path";async function z(t,n){await e(b(t,"scripts/generate-schema.ts"),`import { execSync } from 'node:child_process'
1716
1838
  execSync('npx @murumets-ee/cli generate', { stdio: 'inherit', cwd: import.meta.dirname + '/..' })
1717
1839
  `),await e(b(t,"scripts/migrate.ts"),`import { execSync } from 'node:child_process'
1718
1840
  execSync('npx @murumets-ee/cli migrate', { stdio: 'inherit', cwd: import.meta.dirname + '/..' })
1719
1841
  `),await e(b(t,"scripts/reset-db.ts"),`import { execSync } from 'node:child_process'
1720
1842
  execSync('npx @murumets-ee/cli reset --force', { stdio: 'inherit', cwd: import.meta.dirname + '/..' })
1721
- `)}import{join as g}from"path";async function R(t,n){let{name:r}=n;await e(g(t,"app/globals.css"),`@import "tailwindcss";
1843
+ `)}import{join as f}from"path";async function R(t,n){let{name:r}=n;await e(f(t,"app/globals.css"),`@import "tailwindcss";
1722
1844
  @source "../node_modules/@murumets-ee/auth-ui/dist";
1723
1845
 
1724
1846
  @custom-variant dark (&:where(.dark, .dark *));
@@ -1745,7 +1867,7 @@ body {
1745
1867
  color: var(--foreground);
1746
1868
  font-family: Arial, Helvetica, sans-serif;
1747
1869
  }
1748
- `),await e(g(t,"app/theme-provider.tsx"),`'use client'
1870
+ `),await e(f(t,"app/theme-provider.tsx"),`'use client'
1749
1871
 
1750
1872
  import { ThemeProvider as NextThemesProvider } from 'next-themes'
1751
1873
  import type { ReactNode } from 'react'
@@ -1762,7 +1884,7 @@ export function ThemeProvider({ children }: { children: ReactNode }) {
1762
1884
  </NextThemesProvider>
1763
1885
  )
1764
1886
  }
1765
- `),await e(g(t,"app/theme-toggle.tsx"),`'use client'
1887
+ `),await e(f(t,"app/theme-toggle.tsx"),`'use client'
1766
1888
 
1767
1889
  import { useTheme } from 'next-themes'
1768
1890
  import { useState, useEffect } from 'react'
@@ -1789,7 +1911,7 @@ export function ThemeToggle() {
1789
1911
  </button>
1790
1912
  )
1791
1913
  }
1792
- `),await e(g(t,"app/nav-header.tsx"),`'use client'
1914
+ `),await e(f(t,"app/nav-header.tsx"),`'use client'
1793
1915
 
1794
1916
  import Link from 'next/link'
1795
1917
  import { usePathname } from 'next/navigation'
@@ -1833,7 +1955,7 @@ export function NavHeader() {
1833
1955
  </header>
1834
1956
  )
1835
1957
  }
1836
- `)}import{join as p}from"path";async function C(t,n){let{name:r}=n;await e(p(t,"toolkit.config.ts"),`import { auth } from '@murumets-ee/auth/plugin'
1958
+ `)}import{join as d}from"path";async function C(t,n){let{name:r}=n;await e(d(t,"toolkit.config.ts"),`import { auth } from '@murumets-ee/auth/plugin'
1837
1959
  import { content } from '@murumets-ee/content/plugin'
1838
1960
  import { defineConfig } from '@murumets-ee/core'
1839
1961
  import { mail, ResendMailProvider } from '@murumets-ee/mail'
@@ -1885,7 +2007,7 @@ export default defineConfig({
1885
2007
  ],
1886
2008
  projectRoot: import.meta.dirname,
1887
2009
  })
1888
- `),await e(p(t,"lib/app.ts"),`import { createApp, setApp, type ToolkitApp } from '@murumets-ee/core'
2010
+ `),await e(d(t,"lib/app.ts"),`import { createApp, setApp, type ToolkitApp } from '@murumets-ee/core'
1889
2011
  import config from '../toolkit.config'
1890
2012
 
1891
2013
  let appInstance: ToolkitApp | null = null
@@ -1899,7 +2021,7 @@ export async function getToolkitApp(): Promise<ToolkitApp> {
1899
2021
  }
1900
2022
  return appInstance
1901
2023
  }
1902
- `),await e(p(t,"drizzle.config.ts"),`import type { Config } from 'drizzle-kit'
2024
+ `),await e(d(t,"drizzle.config.ts"),`import type { Config } from 'drizzle-kit'
1903
2025
 
1904
2026
  if (!process.env.DATABASE_URL) {
1905
2027
  throw new Error('DATABASE_URL environment variable is required')
@@ -1913,7 +2035,7 @@ export default {
1913
2035
  url: process.env.DATABASE_URL,
1914
2036
  },
1915
2037
  } satisfies Config
1916
- `),await e(p(t,"auth.config.ts"),`import { betterAuth } from 'better-auth'
2038
+ `),await e(d(t,"auth.config.ts"),`import { betterAuth } from 'better-auth'
1917
2039
  import { drizzleAdapter } from 'better-auth/adapters/drizzle'
1918
2040
  import { admin } from 'better-auth/plugins'
1919
2041
  import { organization } from 'better-auth/plugins/organization'
@@ -1931,7 +2053,7 @@ export const auth = betterAuth({
1931
2053
  organization(),
1932
2054
  ],
1933
2055
  })
1934
- `),await e(p(t,"generated/auth-schema.ts"),`// This file is generated by better-auth CLI.
2056
+ `),await e(d(t,"generated/auth-schema.ts"),`// This file is generated by better-auth CLI.
1935
2057
  // Run: npx @better-auth/cli generate --config auth.config.ts -y
1936
2058
  export {}
1937
- `)}async function q(t,n){t.mode==="single"?await O(t,n):await U(t,n)}async function O(t,n){let r=v(process.cwd(),t.name);n?.("Creating Next.js app..."),m(`pnpm create next-app@${"16"} ${t.name} --typescript --tailwind --no-eslint --app --no-src-dir --turbopack --react-compiler --skip-install --import-alias "@/*"`),await c(r,["app/page.tsx","app/page.module.css","app/fonts","README.md"]),await l(v(r,"package.json"),{type:"module",dependencies:{"@murumets-ee/core":`^${i.myorgCore}`,"@murumets-ee/db":`^${i.myorgDb}`,"@murumets-ee/entity":`^${i.myorgEntity}`,"@murumets-ee/logging":`^${i.myorgLogging}`,"@murumets-ee/auth":`^${i.myorgAuth}`,"@murumets-ee/auth-ui":`^${i.myorgAuthUi}`,"@murumets-ee/admin-ui":`^${i.myorgAdminUi}`,"@murumets-ee/content":`^${i.myorgContent}`,"@murumets-ee/settings":`^${i.myorgSettings}`,"@murumets-ee/storage":`^${i.myorgStorage}`,"@murumets-ee/media":`^${i.myorgMedia}`,"@murumets-ee/taxonomy":`^${i.myorgTaxonomy}`,"@murumets-ee/queue":`^${i.myorgQueue}`,"@murumets-ee/mail":`^${i.myorgMail}`,"@murumets-ee/ticketing":`^${i.myorgTicketing}`,"@murumets-ee/ticketing-ui":`^${i.myorgTicketingUi}`,"@murumets-ee/tokens":`^${i.myorgTokens}`,"better-auth":`^${i.betterAuth}`,"drizzle-orm":`^${i.drizzleOrm}`,"next-intl":`^${i.nextIntl}`,"next-themes":`^${i.nextThemes}`,"lucide-react":`^${i.lucideReact}`,postgres:`^${i.postgres}`,"react-hook-form":`^${i.reactHookForm}`,"@hookform/resolvers":`^${i.hookformResolvers}`,zod:`^${i.zod}`},devDependencies:{"drizzle-kit":`^${i.drizzleKit}`,tsx:`^${i.tsx}`,"babel-plugin-react-compiler":i.babelReactCompiler},scripts:{"db:generate":"tsx --env-file=.env scripts/generate-schema.ts","db:migrate:generate":"drizzle-kit generate","db:migrate":"tsx --env-file=.env scripts/migrate.ts","db:reset":"tsx --env-file=.env scripts/reset-db.ts"}}),n?.("Adding toolkit files..."),await k(r,t),await A(r,t),await C(r,t),await w(r,t),await T(r,t),await S(r,t),await R(r,t),await E(r,t),t.installDeps&&(n?.("Installing dependencies..."),m("pnpm install",{cwd:r}))}async function U(t,n){let r=v(process.cwd(),t.name);n?.("Creating workspace..."),await P(r,t,n),t.installDeps&&(n?.("Installing dependencies..."),m("pnpm install",{cwd:r}))}export{q as scaffold};
2059
+ `)}async function O(t,n){t.mode==="single"?await q(t,n):await U(t,n)}async function q(t,n){let r=v(process.cwd(),t.name);n?.("Creating Next.js app..."),l(`pnpm create next-app@${"16"} ${t.name} --typescript --tailwind --no-eslint --app --no-src-dir --turbopack --react-compiler --skip-install --import-alias "@/*"`),await u(r,["app/page.tsx","app/page.module.css","app/fonts","README.md"]),await c(v(r,"package.json"),{type:"module",dependencies:{"@murumets-ee/core":`^${i.myorgCore}`,"@murumets-ee/db":`^${i.myorgDb}`,"@murumets-ee/entity":`^${i.myorgEntity}`,"@murumets-ee/logging":`^${i.myorgLogging}`,"@murumets-ee/auth":`^${i.myorgAuth}`,"@murumets-ee/auth-ui":`^${i.myorgAuthUi}`,"@murumets-ee/admin-ui":`^${i.myorgAdminUi}`,"@murumets-ee/content":`^${i.myorgContent}`,"@murumets-ee/settings":`^${i.myorgSettings}`,"@murumets-ee/storage":`^${i.myorgStorage}`,"@murumets-ee/media":`^${i.myorgMedia}`,"@murumets-ee/taxonomy":`^${i.myorgTaxonomy}`,"@murumets-ee/queue":`^${i.myorgQueue}`,"@murumets-ee/mail":`^${i.myorgMail}`,"@murumets-ee/ticketing":`^${i.myorgTicketing}`,"@murumets-ee/ticketing-ui":`^${i.myorgTicketingUi}`,"@murumets-ee/tokens":`^${i.myorgTokens}`,"better-auth":`^${i.betterAuth}`,"drizzle-orm":`^${i.drizzleOrm}`,"next-intl":`^${i.nextIntl}`,"next-themes":`^${i.nextThemes}`,"lucide-react":`^${i.lucideReact}`,postgres:`^${i.postgres}`,"react-hook-form":`^${i.reactHookForm}`,"@hookform/resolvers":`^${i.hookformResolvers}`,zod:`^${i.zod}`},devDependencies:{"drizzle-kit":`^${i.drizzleKit}`,tsx:`^${i.tsx}`,"babel-plugin-react-compiler":i.babelReactCompiler},scripts:{"db:generate":"tsx --env-file=.env scripts/generate-schema.ts","db:migrate:generate":"drizzle-kit generate","db:migrate":"tsx --env-file=.env scripts/migrate.ts","db:reset":"tsx --env-file=.env scripts/reset-db.ts"}}),n?.("Adding toolkit files..."),await k(r,t),await A(r,t),await C(r,t),await w(r,t),await T(r,t),await P(r,t),await R(r,t),await z(r,t),t.installDeps&&(n?.("Installing dependencies..."),l("pnpm install",{cwd:r}))}async function U(t,n){let r=v(process.cwd(),t.name);n?.("Creating workspace..."),await E(r,t,n),t.installDeps&&(n?.("Installing dependencies..."),l("pnpm install",{cwd:r}))}export{O as scaffold};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@murumets-ee/create",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "license": "Elastic-2.0",
5
5
  "type": "module",
6
6
  "bin": {