create-nara 1.0.0 → 1.0.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/template.js CHANGED
@@ -11,12 +11,6 @@ export async function setupProject(options) {
11
11
  }
12
12
  // 1. Copy base template (shared files like .gitignore, tsconfig, etc)
13
13
  copyDir(path.join(templatesDir, 'base'), targetDir);
14
- // Rename gitignore.template to .gitignore (npm doesn't include dotfiles)
15
- const gitignoreTemplate = path.join(targetDir, 'gitignore.template');
16
- const gitignoreDest = path.join(targetDir, '.gitignore');
17
- if (fs.existsSync(gitignoreTemplate)) {
18
- fs.renameSync(gitignoreTemplate, gitignoreDest);
19
- }
20
14
  // 2. Copy mode-specific template
21
15
  const modeTemplateDir = path.join(templatesDir, mode);
22
16
  if (fs.existsSync(modeTemplateDir)) {
@@ -30,7 +24,32 @@ export async function setupProject(options) {
30
24
  copyDir(featureDir, targetDir);
31
25
  }
32
26
  }
33
- // 4. Ensure required directories exist
27
+ // 4. Rename dotfiles (npm doesn't include them by default)
28
+ // Must happen AFTER all templates are copied
29
+ const gitignoreTemplate = path.join(targetDir, 'gitignore.template');
30
+ const gitignoreDest = path.join(targetDir, '.gitignore');
31
+ if (fs.existsSync(gitignoreTemplate)) {
32
+ fs.renameSync(gitignoreTemplate, gitignoreDest);
33
+ }
34
+ // Rename env files
35
+ const envFiles = [
36
+ { src: 'env.example', dest: '.env.example' },
37
+ { src: 'env.production.example', dest: '.env.production.example' }
38
+ ];
39
+ for (const envFile of envFiles) {
40
+ const envSrc = path.join(targetDir, envFile.src);
41
+ const envDest = path.join(targetDir, envFile.dest);
42
+ if (fs.existsSync(envSrc)) {
43
+ fs.renameSync(envSrc, envDest);
44
+ }
45
+ }
46
+ // Copy .env.example to .env for development convenience
47
+ const envExample = path.join(targetDir, '.env.example');
48
+ const envFile = path.join(targetDir, '.env');
49
+ if (fs.existsSync(envExample)) {
50
+ fs.copyFileSync(envExample, envFile);
51
+ }
52
+ // 5. Ensure required directories exist
34
53
  fs.mkdirSync(path.join(targetDir, 'app/controllers'), { recursive: true });
35
54
  fs.mkdirSync(path.join(targetDir, 'app/models'), { recursive: true });
36
55
  // Create database directory if db feature is selected
@@ -41,7 +60,7 @@ export async function setupProject(options) {
41
60
  if (features.includes('uploads')) {
42
61
  fs.mkdirSync(path.join(targetDir, 'uploads'), { recursive: true });
43
62
  }
44
- // 5. Generate package.json (dynamic content)
63
+ // 6. Generate package.json (dynamic content)
45
64
  const pkg = createPackageJson(projectName, mode, features);
46
65
  fs.writeFileSync(path.join(targetDir, 'package.json'), JSON.stringify(pkg, null, 2));
47
66
  }
@@ -74,6 +93,8 @@ function createPackageJson(name, mode, features) {
74
93
  pkg.devDependencies['vite'] = '^6.0.0';
75
94
  pkg.devDependencies['@sveltejs/vite-plugin-svelte'] = '^5.0.0';
76
95
  pkg.devDependencies['concurrently'] = '^9.0.0';
96
+ pkg.devDependencies['tailwindcss'] = '^4.0.0';
97
+ pkg.devDependencies['@tailwindcss/vite'] = '^4.0.0';
77
98
  }
78
99
  else if (mode === 'vue') {
79
100
  pkg.dependencies['@nara-web/inertia-vue'] = '^1.0.0';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-nara",
3
- "version": "1.0.0",
3
+ "version": "1.0.3",
4
4
  "description": "CLI to scaffold NARA projects",
5
5
  "type": "module",
6
6
  "bin": {
@@ -0,0 +1,17 @@
1
+ # Application
2
+ PORT=3000
3
+ NODE_ENV=development
4
+ APP_URL=http://localhost:3000
5
+ APP_KEY=change-me-to-random-string
6
+
7
+ # Database
8
+ DB_CONNECTION=sqlite
9
+ DB_DATABASE=./database/dev.sqlite3
10
+
11
+ # Authentication (if auth feature enabled)
12
+ JWT_SECRET=change-me-to-random-jwt-secret
13
+ JWT_EXPIRES_IN=7d
14
+
15
+ # Session
16
+ SESSION_SECRET=change-me-to-random-session-secret
17
+ SESSION_NAME=nara_session
@@ -0,0 +1,17 @@
1
+ # Application
2
+ PORT=3000
3
+ NODE_ENV=production
4
+ APP_URL=https://your-domain.com
5
+ APP_KEY=generate-a-strong-random-key-here
6
+
7
+ # Database
8
+ DB_CONNECTION=sqlite
9
+ DB_DATABASE=./database/prod.sqlite3
10
+
11
+ # Authentication (if auth feature enabled)
12
+ JWT_SECRET=generate-a-strong-jwt-secret-here
13
+ JWT_EXPIRES_IN=7d
14
+
15
+ # Session
16
+ SESSION_SECRET=generate-a-strong-session-secret-here
17
+ SESSION_NAME=nara_session
@@ -1,3 +1,4 @@
1
+ import './index.css';
1
2
  import { createInertiaApp } from '@inertiajs/svelte';
2
3
  import { mount } from 'svelte';
3
4
 
@@ -0,0 +1,76 @@
1
+ @import url('https://rsms.me/inter/inter.css');
2
+ @import url('https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400;0,600;0,700;1,400&display=swap');
3
+ @tailwind base;
4
+ @tailwind components;
5
+ @tailwind utilities;
6
+
7
+ @layer base {
8
+ html {
9
+ font-family: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
10
+ }
11
+
12
+ body::-webkit-scrollbar {
13
+ width: 4px;
14
+ }
15
+
16
+ body::-webkit-scrollbar-track {
17
+ background: transparent;
18
+ }
19
+
20
+ body::-webkit-scrollbar-thumb {
21
+ background-color: theme('colors.primary.500');
22
+ border-radius: 3px;
23
+ }
24
+ }
25
+
26
+ @layer components {
27
+ .card-hover {
28
+ @apply transition-all duration-300 hover:shadow-soft hover:-translate-y-1;
29
+ }
30
+
31
+ .nav-link {
32
+ @apply px-4 py-2 text-gray-600 dark:text-gray-200 hover:text-gray-900 hover:bg-gray-100 rounded-lg transition-colors duration-300;
33
+ }
34
+
35
+ .nav-link.active {
36
+ @apply bg-primary-50 dark:bg-gray-800 text-primary-600;
37
+ }
38
+
39
+ .gradient-text {
40
+ @apply bg-clip-text text-transparent bg-gradient-to-r from-primary-600 to-primary-400;
41
+ }
42
+
43
+ .btn-primary {
44
+ @apply bg-primary-600 text-white px-4 py-2 rounded-lg hover:bg-primary-700
45
+ transition-all duration-300 active:bg-primary-800
46
+ disabled:opacity-50 disabled:cursor-not-allowed
47
+ focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-2;
48
+ }
49
+
50
+ .btn-secondary {
51
+ @apply bg-white text-gray-900 px-4 py-2 rounded-lg border border-gray-300
52
+ hover:bg-gray-50 transition-all duration-300 active:bg-gray-100
53
+ disabled:opacity-50 disabled:cursor-not-allowed
54
+ focus:outline-none focus:ring-2 focus:ring-gray-500 focus:ring-offset-2;
55
+ }
56
+
57
+ .btn-danger {
58
+ @apply bg-danger-600 text-white px-4 py-2 rounded-lg hover:bg-danger-700
59
+ transition-all duration-300 active:bg-danger-800
60
+ disabled:opacity-50 disabled:cursor-not-allowed
61
+ focus:outline-none focus:ring-2 focus:ring-danger-500 focus:ring-offset-2;
62
+ }
63
+
64
+ .card {
65
+ @apply bg-white rounded-xl shadow-soft p-6 transition-all duration-300
66
+ shadow-lg hover:shadow-xl hover:-translate-y-0.5;
67
+ }
68
+
69
+ .bg-surface {
70
+ @apply bg-surface-light dark:bg-surface-dark;
71
+ }
72
+
73
+ .bg-surface-card {
74
+ @apply bg-surface-card-light dark:bg-surface-card-dark;
75
+ }
76
+ }
@@ -0,0 +1,120 @@
1
+ /** @type {import('tailwindcss').Config} */
2
+ export default {
3
+ content: [
4
+ "./resources/**/*.{svelte,html,js,ts}",
5
+ ],
6
+ darkMode: 'class',
7
+ theme: {
8
+ extend: {
9
+ fontFamily: {
10
+ sans: ['Inter var', 'Inter', 'system-ui', '-apple-system', 'BlinkMacSystemFont', 'Segoe UI', 'Roboto', 'Helvetica Neue', 'Arial', 'sans-serif'],
11
+ serif: ['Playfair Display', 'Georgia', 'Cambria', 'Times New Roman', 'Times', 'serif'],
12
+ },
13
+ colors: {
14
+ primary: {
15
+ 50: '#ecfdf5',
16
+ 100: '#d1fae5',
17
+ 200: '#a7f3d0',
18
+ 300: '#6ee7b7',
19
+ 400: '#34d399',
20
+ 500: '#10b981',
21
+ 600: '#059669',
22
+ 700: '#047857',
23
+ 800: '#065f46',
24
+ 900: '#064e3b',
25
+ 950: '#022c22',
26
+ },
27
+ secondary: {
28
+ 50: '#fffbeb',
29
+ 100: '#fef3c7',
30
+ 200: '#fde68a',
31
+ 300: '#fcd34d',
32
+ 400: '#fbbf24',
33
+ 500: '#f59e0b',
34
+ 600: '#d97706',
35
+ 700: '#b45309',
36
+ 800: '#92400e',
37
+ 900: '#78350f',
38
+ 950: '#451a03',
39
+ },
40
+ accent: {
41
+ 50: '#faf5ff',
42
+ 100: '#f3e8ff',
43
+ 200: '#e9d5ff',
44
+ 300: '#d8b4fe',
45
+ 400: '#c084fc',
46
+ 500: '#a855f7',
47
+ 600: '#9333ea',
48
+ 700: '#7c3aed',
49
+ 800: '#6b21a8',
50
+ 900: '#581c87',
51
+ 950: '#3b0764',
52
+ },
53
+ info: {
54
+ 50: '#ecfeff',
55
+ 100: '#cffafe',
56
+ 200: '#a5f3fc',
57
+ 300: '#67e8f9',
58
+ 400: '#22d3ee',
59
+ 500: '#06b6d4',
60
+ 600: '#0891b2',
61
+ 700: '#0e7490',
62
+ 800: '#155e75',
63
+ 900: '#164e63',
64
+ 950: '#083344',
65
+ },
66
+ warning: {
67
+ 50: '#fff7ed',
68
+ 100: '#ffedd5',
69
+ 200: '#fed7aa',
70
+ 300: '#fdba74',
71
+ 400: '#fb923c',
72
+ 500: '#f97316',
73
+ 600: '#ea580c',
74
+ 700: '#c2410c',
75
+ 800: '#9a3412',
76
+ 900: '#7c2d12',
77
+ 950: '#431407',
78
+ },
79
+ danger: {
80
+ 50: '#fef2f2',
81
+ 100: '#fee2e2',
82
+ 200: '#fecaca',
83
+ 300: '#fca5a5',
84
+ 400: '#f87171',
85
+ 500: '#ef4444',
86
+ 600: '#dc2626',
87
+ 700: '#b91c1c',
88
+ 800: '#991b1b',
89
+ 900: '#7f1d1d',
90
+ 950: '#450a0a',
91
+ },
92
+ success: {
93
+ 50: '#ecfdf5',
94
+ 100: '#d1fae5',
95
+ 200: '#a7f3d0',
96
+ 300: '#6ee7b7',
97
+ 400: '#34d399',
98
+ 500: '#10b981',
99
+ 600: '#059669',
100
+ 700: '#047857',
101
+ 800: '#065f46',
102
+ 900: '#064e3b',
103
+ 950: '#022c22',
104
+ },
105
+ surface: {
106
+ light: '#f8f8f8',
107
+ dark: '#0a0a0a',
108
+ card: {
109
+ light: '#f1f5f9',
110
+ dark: '#0f0f0f',
111
+ }
112
+ },
113
+ },
114
+ boxShadow: {
115
+ 'soft': '0 2px 15px -3px rgba(0, 0, 0, 0.07), 0 10px 20px -2px rgba(0, 0, 0, 0.04)',
116
+ },
117
+ },
118
+ },
119
+ plugins: [],
120
+ }
@@ -1,9 +1,10 @@
1
1
  import { defineConfig } from 'vite';
2
2
  import { svelte } from '@sveltejs/vite-plugin-svelte';
3
+ import tailwindcss from '@tailwindcss/vite';
3
4
  import path from 'path';
4
5
 
5
6
  export default defineConfig({
6
- plugins: [svelte()],
7
+ plugins: [svelte(), tailwindcss()],
7
8
  resolve: {
8
9
  alias: {
9
10
  '@': path.resolve(__dirname, './resources/js')
File without changes