@murumets-ee/create 0.1.2 → 0.1.3

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 +15 -121
  2. package/dist/index.js +13 -119
  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 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'
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 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
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
@@ -288,7 +288,7 @@ generated/
288
288
  volumes:
289
289
  postgres_data:
290
290
  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'
291
+ `)}import{join as y}from"path";async function P(t,n){await e(y(t,"entities/index.ts"),`export { Article } from './article'
292
292
  export { Category } from './category'
293
293
  `),await e(y(t,"entities/article.ts"),`import { behavior, defineEntity, field } from '@murumets-ee/entity'
294
294
 
@@ -338,13 +338,13 @@ export const Category = defineEntity({
338
338
  delete: 'group.admin',
339
339
  },
340
340
  })
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'
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'
342
342
 
343
343
  export const routing = defineRouting({
344
344
  locales: ['en'],
345
345
  defaultLocale: 'en',
346
346
  })
347
- `),await e(E(t,"i18n/request.ts"),`import { getRequestConfig } from 'next-intl/server'
347
+ `),await e(S(t,"i18n/request.ts"),`import { getRequestConfig } from 'next-intl/server'
348
348
  import { hasLocale } from 'next-intl'
349
349
  import { routing } from './routing'
350
350
  import { getAuthMessages } from '@murumets-ee/auth-ui/i18n'
@@ -364,7 +364,7 @@ export default getRequestConfig(async ({ requestLocale }) => {
364
364
  },
365
365
  }
366
366
  })
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:
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:
368
368
  - 'packages/*'
369
369
  - 'apps/*'
370
370
 
@@ -703,7 +703,7 @@ async function resetDb() {
703
703
  }
704
704
 
705
705
  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"),`
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"),`
707
707
  # Environment
708
708
  .env*
709
709
  !.env.example
@@ -1251,7 +1251,7 @@ export async function createFirstAdmin(formData: FormData) {
1251
1251
 
1252
1252
  return { ok: true, email: adminUser.user.email }
1253
1253
  }
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"),`
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"),`
1255
1255
  # Environment
1256
1256
  .env*
1257
1257
  !.env.example
@@ -1713,118 +1713,12 @@ export default async function HomePage() {
1713
1713
  </div>
1714
1714
  )
1715
1715
  }
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)
1716
+ `)}import{join as w}from"path";async function _(t,n){await e(w(t,"scripts/generate-schema.ts"),`import { execSync } from 'node:child_process'
1717
+ execSync('npx @murumets-ee/cli generate', { stdio: 'inherit', cwd: import.meta.dirname + '/..' })
1718
+ `),await e(w(t,"scripts/migrate.ts"),`import { execSync } from 'node:child_process'
1719
+ execSync('npx @murumets-ee/cli migrate', { stdio: 'inherit', cwd: import.meta.dirname + '/..' })
1720
+ `),await e(w(t,"scripts/reset-db.ts"),`import { execSync } from 'node:child_process'
1721
+ execSync('npx @murumets-ee/cli reset --force', { stdio: 'inherit', cwd: import.meta.dirname + '/..' })
1828
1722
  `)}import{join as x}from"path";async function $(t,n){let{name:r}=n;await e(x(t,"app/globals.css"),`@import "tailwindcss";
1829
1723
  @source "../node_modules/@murumets-ee/auth-ui/dist";
1830
1724
 
@@ -2041,5 +1935,5 @@ export const auth = betterAuth({
2041
1935
  `),await e(f(t,"generated/auth-schema.ts"),`// This file is generated by better-auth CLI.
2042
1936
  // Run: npx @better-auth/cli generate --config auth.config.ts -y
2043
1937
  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(`
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(`
2045
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();
package/dist/index.js CHANGED
@@ -337,13 +337,13 @@ export const Category = defineEntity({
337
337
  delete: 'group.admin',
338
338
  },
339
339
  })
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'
340
+ `)}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
341
 
342
342
  export const routing = defineRouting({
343
343
  locales: ['en'],
344
344
  defaultLocale: 'en',
345
345
  })
346
- `),await e(T(t,"i18n/request.ts"),`import { getRequestConfig } from 'next-intl/server'
346
+ `),await e(N(t,"i18n/request.ts"),`import { getRequestConfig } from 'next-intl/server'
347
347
  import { hasLocale } from 'next-intl'
348
348
  import { routing } from './routing'
349
349
  import { getAuthMessages } from '@murumets-ee/auth-ui/i18n'
@@ -363,7 +363,7 @@ export default getRequestConfig(async ({ requestLocale }) => {
363
363
  },
364
364
  }
365
365
  })
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:
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:
367
367
  - 'packages/*'
368
368
  - 'apps/*'
369
369
 
@@ -1538,7 +1538,7 @@ export default async function HomePage() {
1538
1538
  </div>
1539
1539
  )
1540
1540
  }
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'
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'
1542
1542
  import createNextIntlPlugin from 'next-intl/plugin'
1543
1543
 
1544
1544
  const withNextIntl = createNextIntlPlugin('./i18n/request.ts')
@@ -1712,119 +1712,13 @@ export default async function HomePage() {
1712
1712
  </div>
1713
1713
  )
1714
1714
  }
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";
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'
1716
+ execSync('npx @murumets-ee/cli generate', { stdio: 'inherit', cwd: import.meta.dirname + '/..' })
1717
+ `),await e(b(t,"scripts/migrate.ts"),`import { execSync } from 'node:child_process'
1718
+ execSync('npx @murumets-ee/cli migrate', { stdio: 'inherit', cwd: import.meta.dirname + '/..' })
1719
+ `),await e(b(t,"scripts/reset-db.ts"),`import { execSync } from 'node:child_process'
1720
+ 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";
1828
1722
  @source "../node_modules/@murumets-ee/auth-ui/dist";
1829
1723
 
1830
1724
  @custom-variant dark (&:where(.dark, .dark *));
@@ -1939,7 +1833,7 @@ export function NavHeader() {
1939
1833
  </header>
1940
1834
  )
1941
1835
  }
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'
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'
1943
1837
  import { content } from '@murumets-ee/content/plugin'
1944
1838
  import { defineConfig } from '@murumets-ee/core'
1945
1839
  import { mail, ResendMailProvider } from '@murumets-ee/mail'
@@ -2040,4 +1934,4 @@ export const auth = betterAuth({
2040
1934
  `),await e(p(t,"generated/auth-schema.ts"),`// This file is generated by better-auth CLI.
2041
1935
  // Run: npx @better-auth/cli generate --config auth.config.ts -y
2042
1936
  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};
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};
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.3",
4
4
  "license": "Elastic-2.0",
5
5
  "type": "module",
6
6
  "bin": {