create-nara 0.1.3 → 1.0.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.
- package/dist/template.js +26 -6
- package/package.json +1 -1
- package/templates/svelte/env.example +17 -0
- package/templates/svelte/env.production.example +17 -0
- package/templates/svelte/resources/js/app.ts +1 -0
- package/templates/svelte/resources/js/index.css +76 -0
- package/templates/svelte/tailwind.config.js +120 -0
- package/templates/svelte/vite.config.ts +2 -1
- /package/templates/base/{.env.example → env.example} +0 -0
package/dist/template.js
CHANGED
|
@@ -17,6 +17,24 @@ export async function setupProject(options) {
|
|
|
17
17
|
if (fs.existsSync(gitignoreTemplate)) {
|
|
18
18
|
fs.renameSync(gitignoreTemplate, gitignoreDest);
|
|
19
19
|
}
|
|
20
|
+
// Rename env files (npm doesn't include dotfiles)
|
|
21
|
+
const envFiles = [
|
|
22
|
+
{ src: 'env.example', dest: '.env.example' },
|
|
23
|
+
{ src: 'env.production.example', dest: '.env.production.example' }
|
|
24
|
+
];
|
|
25
|
+
for (const envFile of envFiles) {
|
|
26
|
+
const envSrc = path.join(targetDir, envFile.src);
|
|
27
|
+
const envDest = path.join(targetDir, envFile.dest);
|
|
28
|
+
if (fs.existsSync(envSrc)) {
|
|
29
|
+
fs.renameSync(envSrc, envDest);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// Copy .env.example to .env for development convenience
|
|
33
|
+
const envExample = path.join(targetDir, '.env.example');
|
|
34
|
+
const envFile = path.join(targetDir, '.env');
|
|
35
|
+
if (fs.existsSync(envExample)) {
|
|
36
|
+
fs.copyFileSync(envExample, envFile);
|
|
37
|
+
}
|
|
20
38
|
// 2. Copy mode-specific template
|
|
21
39
|
const modeTemplateDir = path.join(templatesDir, mode);
|
|
22
40
|
if (fs.existsSync(modeTemplateDir)) {
|
|
@@ -59,7 +77,7 @@ function createPackageJson(name, mode, features) {
|
|
|
59
77
|
start: 'node dist/server.js'
|
|
60
78
|
},
|
|
61
79
|
dependencies: {
|
|
62
|
-
'@nara-web/core': '^
|
|
80
|
+
'@nara-web/core': '^1.0.0',
|
|
63
81
|
'dotenv': '^16.4.7'
|
|
64
82
|
},
|
|
65
83
|
devDependencies: {
|
|
@@ -69,14 +87,16 @@ function createPackageJson(name, mode, features) {
|
|
|
69
87
|
}
|
|
70
88
|
};
|
|
71
89
|
if (mode === 'svelte') {
|
|
72
|
-
pkg.dependencies['@nara-web/inertia-svelte'] = '^
|
|
90
|
+
pkg.dependencies['@nara-web/inertia-svelte'] = '^1.0.0';
|
|
73
91
|
pkg.dependencies['svelte'] = '^5.0.0';
|
|
74
92
|
pkg.devDependencies['vite'] = '^6.0.0';
|
|
75
93
|
pkg.devDependencies['@sveltejs/vite-plugin-svelte'] = '^5.0.0';
|
|
76
94
|
pkg.devDependencies['concurrently'] = '^9.0.0';
|
|
95
|
+
pkg.devDependencies['tailwindcss'] = '^4.0.0';
|
|
96
|
+
pkg.devDependencies['@tailwindcss/vite'] = '^4.0.0';
|
|
77
97
|
}
|
|
78
98
|
else if (mode === 'vue') {
|
|
79
|
-
pkg.dependencies['@nara-web/inertia-vue'] = '^
|
|
99
|
+
pkg.dependencies['@nara-web/inertia-vue'] = '^1.0.0';
|
|
80
100
|
pkg.dependencies['vue'] = '^3.5.0';
|
|
81
101
|
pkg.devDependencies['vite'] = '^6.0.0';
|
|
82
102
|
pkg.devDependencies['@vitejs/plugin-vue'] = '^5.0.0';
|
|
@@ -86,9 +106,9 @@ function createPackageJson(name, mode, features) {
|
|
|
86
106
|
pkg.dependencies['knex'] = '^3.1.0';
|
|
87
107
|
pkg.dependencies['better-sqlite3'] = '^11.0.0';
|
|
88
108
|
pkg.devDependencies['@types/better-sqlite3'] = '^7.6.0';
|
|
89
|
-
pkg.scripts['db:migrate'] = 'knex migrate:latest';
|
|
90
|
-
pkg.scripts['db:rollback'] = 'knex migrate:rollback';
|
|
91
|
-
pkg.scripts['db:make'] = 'knex migrate:make';
|
|
109
|
+
pkg.scripts['db:migrate'] = 'tsx node_modules/.bin/knex migrate:latest';
|
|
110
|
+
pkg.scripts['db:rollback'] = 'tsx node_modules/.bin/knex migrate:rollback';
|
|
111
|
+
pkg.scripts['db:make'] = 'tsx node_modules/.bin/knex migrate:make';
|
|
92
112
|
}
|
|
93
113
|
if (features.includes('auth')) {
|
|
94
114
|
pkg.dependencies['bcrypt'] = '^5.1.0';
|
package/package.json
CHANGED
|
@@ -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
|
|
@@ -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
|