@murumets-ee/create 0.1.2 → 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 +158 -142
  2. package/dist/index.js +156 -140
  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 T(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 N(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 S(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 z(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 E}from"path";async function P(t,n){await e(E(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(E(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 D(t,n),r?.("Admin app created"),r?.("Creating web app..."),await F(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 D(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 F(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
 
@@ -1713,119 +1835,13 @@ export default async function HomePage() {
1713
1835
  </div>
1714
1836
  )
1715
1837
  }
1716
- `)}import{join as w}from"path";async function _(t,n){await e(w(t,"scripts/generate-schema.ts"),`/**
1717
- * Generate Drizzle schemas from entity definitions
1718
- * This script reads entity definitions and outputs Drizzle schema files
1719
- */
1720
-
1721
- import { mkdir, writeFile } from 'node:fs/promises'
1722
- import { join } from 'node:path'
1723
- import { generateSchemaCode, generateTranslationSchemaCode } from '@murumets-ee/entity'
1724
- import config from '../toolkit.config'
1725
-
1726
- async function generateSchemas() {
1727
- console.log('Generating Drizzle schemas from entity definitions...')
1728
-
1729
- const schemaDir = join(import.meta.dirname, '..', 'generated')
1730
- await mkdir(schemaDir, { recursive: true })
1731
-
1732
- const imports: string[] = []
1733
- const schemas: string[] = []
1734
- let hasTranslations = false
1735
-
1736
- for (const entity of config.entities) {
1737
- console.log(\` - Generating schema for \${entity.name}\`)
1738
-
1739
- // Generate main table (returns TypeScript code string)
1740
- const schemaCode = generateSchemaCode(entity)
1741
- schemas.push(\`\\n// \${entity.name} table\`)
1742
- schemas.push(schemaCode)
1743
-
1744
- // Generate translation table if needed (returns TypeScript code string or null)
1745
- const translationCode = generateTranslationSchemaCode(entity)
1746
- if (translationCode) {
1747
- hasTranslations = true
1748
- schemas.push(\`\\n// \${entity.name} translations\`)
1749
- schemas.push(translationCode)
1750
- }
1751
- }
1752
-
1753
- // Add imports \u2014 include all pg-core types that entities might use
1754
- const pgCoreTypes = ['pgTable', 'varchar', 'text', 'boolean', 'timestamp', 'integer', 'doublePrecision', 'jsonb', 'uuid', 'index']
1755
- if (hasTranslations) pgCoreTypes.push('unique')
1756
- const pgCoreImports = \`import { \${pgCoreTypes.join(', ')} } from 'drizzle-orm/pg-core'\\n\`
1757
- imports.push(pgCoreImports)
1758
-
1759
- const schemaFile = join(schemaDir, 'schema.ts')
1760
- await writeFile(schemaFile, [...imports, ...schemas].join('\\n'))
1761
-
1762
- console.log(\`\\nSchemas written to: \${schemaFile}\`)
1763
- console.log('Run \\\`pnpm db:migrate:generate\\\` to create migrations')
1764
- }
1765
-
1766
- generateSchemas().catch(console.error)
1767
- `),await e(w(t,"scripts/migrate.ts"),`/**
1768
- * Run pending migrations
1769
- * Applies both toolkit migrations (.toolkit/) and project migrations
1770
- */
1771
-
1772
- import { createDbClient, runMigrations } from '@murumets-ee/db'
1773
-
1774
- async function migrate() {
1775
- console.log('Running migrations...')
1776
-
1777
- try {
1778
- if (!process.env.DATABASE_URL) {
1779
- throw new Error('DATABASE_URL environment variable is required')
1780
- }
1781
-
1782
- const db = createDbClient({ url: process.env.DATABASE_URL })
1783
- await runMigrations(db, import.meta.dirname + '/..')
1784
-
1785
- console.log('Migrations completed successfully')
1786
- process.exit(0)
1787
- } catch (error) {
1788
- console.error('Migration failed:', error)
1789
- process.exit(1)
1790
- }
1791
- }
1792
-
1793
- migrate()
1794
- `),await e(w(t,"scripts/reset-db.ts"),`/**
1795
- * Reset database (DROP all tables)
1796
- * WARNING: Only for development
1797
- */
1798
-
1799
- import postgres from 'postgres'
1800
-
1801
- async function resetDb() {
1802
- const DATABASE_URL = process.env.DATABASE_URL
1803
-
1804
- if (!DATABASE_URL) {
1805
- throw new Error('DATABASE_URL not set')
1806
- }
1807
-
1808
- console.warn('WARNING: This will DROP ALL TABLES')
1809
- console.log('Database:', DATABASE_URL.split('@')[1])
1810
-
1811
- const sql = postgres(DATABASE_URL)
1812
-
1813
- try {
1814
- // Drop all tables (cascade to handle foreign keys)
1815
- await sql\`
1816
- DROP SCHEMA public CASCADE;
1817
- CREATE SCHEMA public;
1818
- GRANT ALL ON SCHEMA public TO PUBLIC;
1819
- \`
1820
-
1821
- console.log('Database reset complete')
1822
- } finally {
1823
- await sql.end()
1824
- }
1825
- }
1826
-
1827
- resetDb().catch(console.error)
1828
- `)}import{join as x}from"path";async function $(t,n){let{name:r}=n;await e(x(t,"app/globals.css"),`@import "tailwindcss";
1838
+ `)}import{join as w}from"path";async function _(t,n){await e(w(t,"scripts/generate-schema.ts"),`import { execSync } from 'node:child_process'
1839
+ execSync('npx @murumets-ee/cli generate', { stdio: 'inherit', cwd: import.meta.dirname + '/..' })
1840
+ `),await e(w(t,"scripts/migrate.ts"),`import { execSync } from 'node:child_process'
1841
+ execSync('npx @murumets-ee/cli migrate', { stdio: 'inherit', cwd: import.meta.dirname + '/..' })
1842
+ `),await e(w(t,"scripts/reset-db.ts"),`import { execSync } from 'node:child_process'
1843
+ execSync('npx @murumets-ee/cli reset --force', { stdio: 'inherit', cwd: import.meta.dirname + '/..' })
1844
+ `)}import{join as b}from"path";async function $(t,n){let{name:r}=n;await e(b(t,"app/globals.css"),`@import "tailwindcss";
1829
1845
  @source "../node_modules/@murumets-ee/auth-ui/dist";
1830
1846
 
1831
1847
  @custom-variant dark (&:where(.dark, .dark *));
@@ -1852,7 +1868,7 @@ body {
1852
1868
  color: var(--foreground);
1853
1869
  font-family: Arial, Helvetica, sans-serif;
1854
1870
  }
1855
- `),await e(x(t,"app/theme-provider.tsx"),`'use client'
1871
+ `),await e(b(t,"app/theme-provider.tsx"),`'use client'
1856
1872
 
1857
1873
  import { ThemeProvider as NextThemesProvider } from 'next-themes'
1858
1874
  import type { ReactNode } from 'react'
@@ -1869,7 +1885,7 @@ export function ThemeProvider({ children }: { children: ReactNode }) {
1869
1885
  </NextThemesProvider>
1870
1886
  )
1871
1887
  }
1872
- `),await e(x(t,"app/theme-toggle.tsx"),`'use client'
1888
+ `),await e(b(t,"app/theme-toggle.tsx"),`'use client'
1873
1889
 
1874
1890
  import { useTheme } from 'next-themes'
1875
1891
  import { useState, useEffect } from 'react'
@@ -1896,7 +1912,7 @@ export function ThemeToggle() {
1896
1912
  </button>
1897
1913
  )
1898
1914
  }
1899
- `),await e(x(t,"app/nav-header.tsx"),`'use client'
1915
+ `),await e(b(t,"app/nav-header.tsx"),`'use client'
1900
1916
 
1901
1917
  import Link from 'next/link'
1902
1918
  import { usePathname } from 'next/navigation'
@@ -1940,7 +1956,7 @@ export function NavHeader() {
1940
1956
  </header>
1941
1957
  )
1942
1958
  }
1943
- `)}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'
1944
1960
  import { content } from '@murumets-ee/content/plugin'
1945
1961
  import { defineConfig } from '@murumets-ee/core'
1946
1962
  import { mail, ResendMailProvider } from '@murumets-ee/mail'
@@ -1992,7 +2008,7 @@ export default defineConfig({
1992
2008
  ],
1993
2009
  projectRoot: import.meta.dirname,
1994
2010
  })
1995
- `),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'
1996
2012
  import config from '../toolkit.config'
1997
2013
 
1998
2014
  let appInstance: ToolkitApp | null = null
@@ -2006,7 +2022,7 @@ export async function getToolkitApp(): Promise<ToolkitApp> {
2006
2022
  }
2007
2023
  return appInstance
2008
2024
  }
2009
- `),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'
2010
2026
 
2011
2027
  if (!process.env.DATABASE_URL) {
2012
2028
  throw new Error('DATABASE_URL environment variable is required')
@@ -2020,7 +2036,7 @@ export default {
2020
2036
  url: process.env.DATABASE_URL,
2021
2037
  },
2022
2038
  } satisfies Config
2023
- `),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'
2024
2040
  import { drizzleAdapter } from 'better-auth/adapters/drizzle'
2025
2041
  import { admin } from 'better-auth/plugins'
2026
2042
  import { organization } from 'better-auth/plugins/organization'
@@ -2038,8 +2054,8 @@ export const auth = betterAuth({
2038
2054
  organization(),
2039
2055
  ],
2040
2056
  })
2041
- `),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.
2042
2058
  // Run: npx @better-auth/cli generate --config auth.config.ts -y
2043
2059
  export {}
2044
- `)}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 S(r,t),await z(r,t),await M(r,t),await N(r,t),await P(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 T(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(`
2045
- `),"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'
@@ -337,13 +459,13 @@ export const Category = defineEntity({
337
459
  delete: 'group.admin',
338
460
  },
339
461
  })
340
- `)}import{join as T}from"path";async function N(t,n){await e(T(t,"i18n/routing.ts"),`import { defineRouting } from 'next-intl/routing'
462
+ `)}import{join as N}from"path";async function T(t,n){await e(N(t,"i18n/routing.ts"),`import { defineRouting } from 'next-intl/routing'
341
463
 
342
464
  export const routing = defineRouting({
343
465
  locales: ['en'],
344
466
  defaultLocale: 'en',
345
467
  })
346
- `),await e(T(t,"i18n/request.ts"),`import { getRequestConfig } from 'next-intl/server'
468
+ `),await e(N(t,"i18n/request.ts"),`import { getRequestConfig } from 'next-intl/server'
347
469
  import { hasLocale } from 'next-intl'
348
470
  import { routing } from './routing'
349
471
  import { getAuthMessages } from '@murumets-ee/auth-ui/i18n'
@@ -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 S(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 E(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,119 +1834,13 @@ export default async function HomePage() {
1712
1834
  </div>
1713
1835
  )
1714
1836
  }
1715
- `)}import{join as b}from"path";async function P(t,n){await e(b(t,"scripts/generate-schema.ts"),`/**
1716
- * Generate Drizzle schemas from entity definitions
1717
- * This script reads entity definitions and outputs Drizzle schema files
1718
- */
1719
-
1720
- import { mkdir, writeFile } from 'node:fs/promises'
1721
- import { join } from 'node:path'
1722
- import { generateSchemaCode, generateTranslationSchemaCode } from '@murumets-ee/entity'
1723
- import config from '../toolkit.config'
1724
-
1725
- async function generateSchemas() {
1726
- console.log('Generating Drizzle schemas from entity definitions...')
1727
-
1728
- const schemaDir = join(import.meta.dirname, '..', 'generated')
1729
- await mkdir(schemaDir, { recursive: true })
1730
-
1731
- const imports: string[] = []
1732
- const schemas: string[] = []
1733
- let hasTranslations = false
1734
-
1735
- for (const entity of config.entities) {
1736
- console.log(\` - Generating schema for \${entity.name}\`)
1737
-
1738
- // Generate main table (returns TypeScript code string)
1739
- const schemaCode = generateSchemaCode(entity)
1740
- schemas.push(\`\\n// \${entity.name} table\`)
1741
- schemas.push(schemaCode)
1742
-
1743
- // Generate translation table if needed (returns TypeScript code string or null)
1744
- const translationCode = generateTranslationSchemaCode(entity)
1745
- if (translationCode) {
1746
- hasTranslations = true
1747
- schemas.push(\`\\n// \${entity.name} translations\`)
1748
- schemas.push(translationCode)
1749
- }
1750
- }
1751
-
1752
- // Add imports \u2014 include all pg-core types that entities might use
1753
- const pgCoreTypes = ['pgTable', 'varchar', 'text', 'boolean', 'timestamp', 'integer', 'doublePrecision', 'jsonb', 'uuid', 'index']
1754
- if (hasTranslations) pgCoreTypes.push('unique')
1755
- const pgCoreImports = \`import { \${pgCoreTypes.join(', ')} } from 'drizzle-orm/pg-core'\\n\`
1756
- imports.push(pgCoreImports)
1757
-
1758
- const schemaFile = join(schemaDir, 'schema.ts')
1759
- await writeFile(schemaFile, [...imports, ...schemas].join('\\n'))
1760
-
1761
- console.log(\`\\nSchemas written to: \${schemaFile}\`)
1762
- console.log('Run \\\`pnpm db:migrate:generate\\\` to create migrations')
1763
- }
1764
-
1765
- generateSchemas().catch(console.error)
1766
- `),await e(b(t,"scripts/migrate.ts"),`/**
1767
- * Run pending migrations
1768
- * Applies both toolkit migrations (.toolkit/) and project migrations
1769
- */
1770
-
1771
- import { createDbClient, runMigrations } from '@murumets-ee/db'
1772
-
1773
- async function migrate() {
1774
- console.log('Running migrations...')
1775
-
1776
- try {
1777
- if (!process.env.DATABASE_URL) {
1778
- throw new Error('DATABASE_URL environment variable is required')
1779
- }
1780
-
1781
- const db = createDbClient({ url: process.env.DATABASE_URL })
1782
- await runMigrations(db, import.meta.dirname + '/..')
1783
-
1784
- console.log('Migrations completed successfully')
1785
- process.exit(0)
1786
- } catch (error) {
1787
- console.error('Migration failed:', error)
1788
- process.exit(1)
1789
- }
1790
- }
1791
-
1792
- migrate()
1793
- `),await e(b(t,"scripts/reset-db.ts"),`/**
1794
- * Reset database (DROP all tables)
1795
- * WARNING: Only for development
1796
- */
1797
-
1798
- import postgres from 'postgres'
1799
-
1800
- async function resetDb() {
1801
- const DATABASE_URL = process.env.DATABASE_URL
1802
-
1803
- if (!DATABASE_URL) {
1804
- throw new Error('DATABASE_URL not set')
1805
- }
1806
-
1807
- console.warn('WARNING: This will DROP ALL TABLES')
1808
- console.log('Database:', DATABASE_URL.split('@')[1])
1809
-
1810
- const sql = postgres(DATABASE_URL)
1811
-
1812
- try {
1813
- // Drop all tables (cascade to handle foreign keys)
1814
- await sql\`
1815
- DROP SCHEMA public CASCADE;
1816
- CREATE SCHEMA public;
1817
- GRANT ALL ON SCHEMA public TO PUBLIC;
1818
- \`
1819
-
1820
- console.log('Database reset complete')
1821
- } finally {
1822
- await sql.end()
1823
- }
1824
- }
1825
-
1826
- resetDb().catch(console.error)
1827
- `)}import{join as g}from"path";async function C(t,n){let{name:r}=n;await e(g(t,"app/globals.css"),`@import "tailwindcss";
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'
1838
+ execSync('npx @murumets-ee/cli generate', { stdio: 'inherit', cwd: import.meta.dirname + '/..' })
1839
+ `),await e(b(t,"scripts/migrate.ts"),`import { execSync } from 'node:child_process'
1840
+ execSync('npx @murumets-ee/cli migrate', { stdio: 'inherit', cwd: import.meta.dirname + '/..' })
1841
+ `),await e(b(t,"scripts/reset-db.ts"),`import { execSync } from 'node:child_process'
1842
+ execSync('npx @murumets-ee/cli reset --force', { stdio: 'inherit', cwd: import.meta.dirname + '/..' })
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";
1828
1844
  @source "../node_modules/@murumets-ee/auth-ui/dist";
1829
1845
 
1830
1846
  @custom-variant dark (&:where(.dark, .dark *));
@@ -1851,7 +1867,7 @@ body {
1851
1867
  color: var(--foreground);
1852
1868
  font-family: Arial, Helvetica, sans-serif;
1853
1869
  }
1854
- `),await e(g(t,"app/theme-provider.tsx"),`'use client'
1870
+ `),await e(f(t,"app/theme-provider.tsx"),`'use client'
1855
1871
 
1856
1872
  import { ThemeProvider as NextThemesProvider } from 'next-themes'
1857
1873
  import type { ReactNode } from 'react'
@@ -1868,7 +1884,7 @@ export function ThemeProvider({ children }: { children: ReactNode }) {
1868
1884
  </NextThemesProvider>
1869
1885
  )
1870
1886
  }
1871
- `),await e(g(t,"app/theme-toggle.tsx"),`'use client'
1887
+ `),await e(f(t,"app/theme-toggle.tsx"),`'use client'
1872
1888
 
1873
1889
  import { useTheme } from 'next-themes'
1874
1890
  import { useState, useEffect } from 'react'
@@ -1895,7 +1911,7 @@ export function ThemeToggle() {
1895
1911
  </button>
1896
1912
  )
1897
1913
  }
1898
- `),await e(g(t,"app/nav-header.tsx"),`'use client'
1914
+ `),await e(f(t,"app/nav-header.tsx"),`'use client'
1899
1915
 
1900
1916
  import Link from 'next/link'
1901
1917
  import { usePathname } from 'next/navigation'
@@ -1939,7 +1955,7 @@ export function NavHeader() {
1939
1955
  </header>
1940
1956
  )
1941
1957
  }
1942
- `)}import{join as p}from"path";async function R(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'
1943
1959
  import { content } from '@murumets-ee/content/plugin'
1944
1960
  import { defineConfig } from '@murumets-ee/core'
1945
1961
  import { mail, ResendMailProvider } from '@murumets-ee/mail'
@@ -1991,7 +2007,7 @@ export default defineConfig({
1991
2007
  ],
1992
2008
  projectRoot: import.meta.dirname,
1993
2009
  })
1994
- `),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'
1995
2011
  import config from '../toolkit.config'
1996
2012
 
1997
2013
  let appInstance: ToolkitApp | null = null
@@ -2005,7 +2021,7 @@ export async function getToolkitApp(): Promise<ToolkitApp> {
2005
2021
  }
2006
2022
  return appInstance
2007
2023
  }
2008
- `),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'
2009
2025
 
2010
2026
  if (!process.env.DATABASE_URL) {
2011
2027
  throw new Error('DATABASE_URL environment variable is required')
@@ -2019,7 +2035,7 @@ export default {
2019
2035
  url: process.env.DATABASE_URL,
2020
2036
  },
2021
2037
  } satisfies Config
2022
- `),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'
2023
2039
  import { drizzleAdapter } from 'better-auth/adapters/drizzle'
2024
2040
  import { admin } from 'better-auth/plugins'
2025
2041
  import { organization } from 'better-auth/plugins/organization'
@@ -2037,7 +2053,7 @@ export const auth = betterAuth({
2037
2053
  organization(),
2038
2054
  ],
2039
2055
  })
2040
- `),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.
2041
2057
  // Run: npx @better-auth/cli generate --config auth.config.ts -y
2042
2058
  export {}
2043
- `)}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 R(r,t),await w(r,t),await N(r,t),await E(r,t),await C(r,t),await P(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 S(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.2",
3
+ "version": "0.1.4",
4
4
  "license": "Elastic-2.0",
5
5
  "type": "module",
6
6
  "bin": {