@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.
- package/dist/cli.js +15 -121
- package/dist/index.js +13 -119
- 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
|
|
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
|
|
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
|
|
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
|
|
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(
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
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
|
|
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
|
|
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(
|
|
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
|
|
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
|
|
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
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
import
|
|
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
|
|
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
|
|
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};
|