create-mantiq 0.5.0 → 0.5.2

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 (42) hide show
  1. package/package.json +2 -1
  2. package/skeleton/.env.example +12 -0
  3. package/skeleton/README.md +46 -0
  4. package/skeleton/app/Http/Controllers/HomeController.ts +78 -0
  5. package/skeleton/app/Http/Middleware/.gitkeep +0 -0
  6. package/skeleton/app/Models/PersonalAccessToken.ts +5 -0
  7. package/skeleton/app/Models/User.ts +18 -0
  8. package/skeleton/app/Providers/DatabaseServiceProvider.ts +27 -0
  9. package/skeleton/config/app.ts +11 -0
  10. package/skeleton/config/auth.ts +16 -0
  11. package/skeleton/config/database.ts +12 -0
  12. package/skeleton/config/filesystem.ts +17 -0
  13. package/skeleton/config/heartbeat.ts +45 -0
  14. package/skeleton/config/logging.ts +27 -0
  15. package/skeleton/config/mail.ts +52 -0
  16. package/skeleton/config/notify.ts +3 -0
  17. package/skeleton/config/queue.ts +23 -0
  18. package/skeleton/config/search.ts +25 -0
  19. package/skeleton/database/factories/.gitkeep +0 -0
  20. package/skeleton/database/migrations/001_create_users_table.ts +19 -0
  21. package/skeleton/database/migrations/002_create_personal_access_tokens_table.ts +22 -0
  22. package/skeleton/database/seeders/DatabaseSeeder.ts +7 -0
  23. package/skeleton/index.ts +20 -0
  24. package/skeleton/mantiq.ts +8 -0
  25. package/skeleton/package.json +33 -0
  26. package/skeleton/public/.gitkeep +0 -0
  27. package/skeleton/routes/api.ts +8 -0
  28. package/skeleton/routes/web.ts +6 -0
  29. package/skeleton/tsconfig.json +27 -0
  30. package/src/index.ts +50 -14
  31. package/src/templates.ts +75 -864
  32. package/stubs/react/src/components/layout/nav-user.tsx.stub +1 -1
  33. package/stubs/react/src/components/layout/sidebar-data.ts.stub +1 -1
  34. package/stubs/react/vite.config.ts.stub +1 -1
  35. package/stubs/svelte/src/lib/components/layout/sidebar-data.ts.stub +1 -1
  36. package/stubs/svelte/vite.config.ts.stub +1 -1
  37. package/stubs/vue/src/components/layout/sidebar-data.ts.stub +1 -1
  38. package/stubs/vue/vite.config.ts.stub +1 -1
  39. package/src/kits/react.ts +0 -437
  40. package/src/kits/svelte.ts +0 -464
  41. package/src/kits/vue.ts +0 -532
  42. package/src/ui/shadcn.ts +0 -910
package/src/index.ts CHANGED
@@ -1,10 +1,37 @@
1
1
  #!/usr/bin/env bun
2
- import { existsSync, mkdirSync } from 'node:fs'
3
- import { dirname, resolve } from 'node:path'
2
+ import { existsSync, mkdirSync, readdirSync, statSync, readFileSync } from 'node:fs'
3
+ import { dirname, resolve, join, relative } from 'node:path'
4
4
  import { randomBytes } from 'node:crypto'
5
5
  import { getTemplates } from './templates.ts'
6
6
  import { Terminal } from './terminal.ts'
7
7
 
8
+ /**
9
+ * Recursively copy a directory, preserving structure.
10
+ * Skips node_modules, .git, bun.lock, *.sqlite files.
11
+ */
12
+ async function copyDirectory(src: string, dest: string): Promise<number> {
13
+ let count = 0
14
+ const entries = readdirSync(src, { withFileTypes: true })
15
+ for (const entry of entries) {
16
+ const srcPath = join(src, entry.name)
17
+ const destPath = join(dest, entry.name)
18
+
19
+ // Skip files that shouldn't be copied
20
+ if (['node_modules', '.git', 'bun.lock', 'README.md'].includes(entry.name)) continue
21
+ if (entry.name.endsWith('.sqlite') || entry.name.endsWith('.sqlite-wal') || entry.name.endsWith('.sqlite-shm')) continue
22
+
23
+ if (entry.isDirectory()) {
24
+ mkdirSync(destPath, { recursive: true })
25
+ count += await copyDirectory(srcPath, destPath)
26
+ } else {
27
+ mkdirSync(dirname(destPath), { recursive: true })
28
+ await Bun.write(destPath, Bun.file(srcPath))
29
+ count++
30
+ }
31
+ }
32
+ return count
33
+ }
34
+
8
35
  // ── ANSI helpers ─────────────────────────────────────────────────────────────
9
36
  const R = '\x1b[0m'
10
37
  const bold = (s: string) => `\x1b[1m${s}${R}`
@@ -98,19 +125,28 @@ if (!isCI && !kit) {
98
125
  // ── Generate ─────────────────────────────────────────────────────────────────
99
126
  term.step('Scaffolding project')
100
127
 
128
+ let fileCount = 0
129
+
130
+ // Step 1: Copy the skeleton directory as the base
131
+ const skeletonDir = resolve(import.meta.dir, '..', 'skeleton')
132
+ if (existsSync(skeletonDir)) {
133
+ fileCount += await copyDirectory(skeletonDir, projectDir)
134
+ } else {
135
+ // Fallback: skeleton not bundled (shouldn't happen in published package)
136
+ console.error(' Skeleton directory not found')
137
+ }
138
+
139
+ // Step 2: Generate dynamic files (package.json, .env — overwrites skeleton versions)
101
140
  const appKey = `base64:${randomBytes(32).toString('base64')}`
102
141
  const templates = getTemplates({ name: projectName, appKey, kit, ui })
103
-
104
- // Write base skeleton (dynamic templates)
105
- const templateFiles = Object.keys(templates).sort()
106
- for (const relativePath of templateFiles) {
142
+ for (const [relativePath, content] of Object.entries(templates)) {
107
143
  const fullPath = `${projectDir}/${relativePath}`
108
144
  mkdirSync(dirname(fullPath), { recursive: true })
109
- await Bun.write(fullPath, templates[relativePath]!)
145
+ await Bun.write(fullPath, content)
146
+ fileCount++
110
147
  }
111
148
 
112
- // Copy starter kit stubs (static files)
113
- let stubCount = 0
149
+ // Step 3: Overlay starter kit stubs (new files + route overrides)
114
150
  if (kit) {
115
151
  const stubsDir = resolve(import.meta.dir, '..', 'stubs')
116
152
  const manifestPath = resolve(stubsDir, 'manifest.json')
@@ -120,18 +156,18 @@ if (kit) {
120
156
  const kitManifest = manifest[kit]
121
157
  const sharedManifest = manifest.shared
122
158
 
123
- // Copy kit-specific stubs (src/, vite.config.ts, tsconfig.json, etc.)
159
+ // Kit-specific stubs (src/, vite.config.ts, etc.)
124
160
  if (kitManifest?.files) {
125
161
  for (const { stub, target } of kitManifest.files) {
126
162
  const src = resolve(stubsDir, kit, stub)
127
163
  const dest = resolve(projectDir, target)
128
164
  mkdirSync(dirname(dest), { recursive: true })
129
165
  await Bun.write(dest, Bun.file(src))
130
- stubCount++
166
+ fileCount++
131
167
  }
132
168
  }
133
169
 
134
- // Copy shared stubs (routes, controllers, seeder) with placeholder replacement
170
+ // Shared stubs (routes, controllers, seeder overwrites skeleton routes)
135
171
  if (sharedManifest?.files) {
136
172
  const mainEntry = kitManifest?.mainEntry ?? 'src/main.ts'
137
173
  for (const { stub, target } of sharedManifest.files) {
@@ -141,12 +177,12 @@ if (kit) {
141
177
  let content = await Bun.file(src).text()
142
178
  content = content.replace(/\{\{MAIN_ENTRY\}\}/g, mainEntry)
143
179
  await Bun.write(dest, content)
144
- stubCount++
180
+ fileCount++
145
181
  }
146
182
  }
147
183
  }
148
184
  }
149
- console.log(` ${dim(`${templateFiles.length + stubCount} files created`)}`)
185
+ console.log(` ${dim(`${fileCount} files created`)}`)
150
186
 
151
187
  // ── Install dependencies ─────────────────────────────────────────────────────
152
188
  const spin = term.spinner('Installing dependencies')