sparesdev 0.0.7 ā 0.0.9
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/core/init.js +223 -20
- package/package.json +1 -1
package/core/init.js
CHANGED
|
@@ -1,7 +1,19 @@
|
|
|
1
1
|
import fs from "fs";
|
|
2
2
|
import { execSync } from "child_process";
|
|
3
3
|
|
|
4
|
+
// -----------------------------
|
|
5
|
+
// š¦ Dependencies
|
|
6
|
+
// -----------------------------
|
|
4
7
|
function getMissingDependencies() {
|
|
8
|
+
const required = [
|
|
9
|
+
"react",
|
|
10
|
+
"react-dom",
|
|
11
|
+
"react-router-dom",
|
|
12
|
+
"clsx",
|
|
13
|
+
"tailwind-merge",
|
|
14
|
+
"class-variance-authority"
|
|
15
|
+
];
|
|
16
|
+
|
|
5
17
|
try {
|
|
6
18
|
const pkg = JSON.parse(fs.readFileSync("package.json", "utf-8"));
|
|
7
19
|
|
|
@@ -10,21 +22,15 @@ function getMissingDependencies() {
|
|
|
10
22
|
...pkg.devDependencies
|
|
11
23
|
};
|
|
12
24
|
|
|
13
|
-
const required = [
|
|
14
|
-
"react",
|
|
15
|
-
"react-dom",
|
|
16
|
-
"react-router-dom",
|
|
17
|
-
"clsx",
|
|
18
|
-
"tailwind-merge",
|
|
19
|
-
"class-variance-authority"
|
|
20
|
-
];
|
|
21
|
-
|
|
22
25
|
return required.filter(dep => !installed?.[dep]);
|
|
23
26
|
} catch {
|
|
24
27
|
return required;
|
|
25
28
|
}
|
|
26
29
|
}
|
|
27
30
|
|
|
31
|
+
// -----------------------------
|
|
32
|
+
// āļø Vite Config
|
|
33
|
+
// -----------------------------
|
|
28
34
|
function patchViteConfig() {
|
|
29
35
|
const viteConfigPath = "vite.config.ts";
|
|
30
36
|
|
|
@@ -35,7 +41,7 @@ function patchViteConfig() {
|
|
|
35
41
|
|
|
36
42
|
let content = fs.readFileSync(viteConfigPath, "utf-8");
|
|
37
43
|
|
|
38
|
-
//
|
|
44
|
+
// Tailwind import
|
|
39
45
|
if (!content.includes("@tailwindcss/vite")) {
|
|
40
46
|
content = content.replace(
|
|
41
47
|
/import react from ['"]@vitejs\/plugin-react['"]/,
|
|
@@ -43,7 +49,12 @@ function patchViteConfig() {
|
|
|
43
49
|
);
|
|
44
50
|
}
|
|
45
51
|
|
|
46
|
-
//
|
|
52
|
+
// Path import
|
|
53
|
+
if (!content.includes('import path from "path"')) {
|
|
54
|
+
content = `import path from "path"\n` + content;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Tailwind plugin
|
|
47
58
|
if (!content.includes("tailwindcss()")) {
|
|
48
59
|
content = content.replace(
|
|
49
60
|
/plugins:\s*\[([^\]]*)\]/,
|
|
@@ -51,11 +62,199 @@ function patchViteConfig() {
|
|
|
51
62
|
);
|
|
52
63
|
}
|
|
53
64
|
|
|
65
|
+
// Alias
|
|
66
|
+
if (!content.includes("resolve:")) {
|
|
67
|
+
content = content.replace(
|
|
68
|
+
/export default defineConfig\(\{/,
|
|
69
|
+
`export default defineConfig({
|
|
70
|
+
resolve: {
|
|
71
|
+
alias: {
|
|
72
|
+
"@": path.resolve(__dirname, "./src"),
|
|
73
|
+
},
|
|
74
|
+
},`
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
54
78
|
fs.writeFileSync(viteConfigPath, content);
|
|
55
79
|
|
|
56
|
-
console.log("ā
vite.config.ts
|
|
80
|
+
console.log("ā
vite.config.ts configured");
|
|
57
81
|
}
|
|
58
82
|
|
|
83
|
+
// -----------------------------
|
|
84
|
+
// š Project Structure
|
|
85
|
+
// -----------------------------
|
|
86
|
+
function ensureSrcFolder() {
|
|
87
|
+
if (!fs.existsSync("src")) {
|
|
88
|
+
fs.mkdirSync("src", { recursive: true });
|
|
89
|
+
console.log("š Created src folder");
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// -----------------------------
|
|
94
|
+
// šØ Tokens
|
|
95
|
+
// -----------------------------
|
|
96
|
+
function createTokensCss() {
|
|
97
|
+
const tokensPath = "src/tokens.css";
|
|
98
|
+
|
|
99
|
+
if (fs.existsSync(tokensPath)) {
|
|
100
|
+
console.log("ā¹ļø tokens.css already exists");
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const content = `@theme {
|
|
105
|
+
|
|
106
|
+
/* Screens */
|
|
107
|
+
--breakpoint-sm: 640px;
|
|
108
|
+
--breakpoint-md: 768px;
|
|
109
|
+
--breakpoint-lg: 1024px;
|
|
110
|
+
|
|
111
|
+
/* Fonts */
|
|
112
|
+
--font-sans: "Inter", ui-sans-serif, system-ui, sans-serif;
|
|
113
|
+
|
|
114
|
+
/* Text */
|
|
115
|
+
--text-xs: 10px;
|
|
116
|
+
--text-sm: 12px;
|
|
117
|
+
--text-base: 14px;
|
|
118
|
+
--text-lg: 16px;
|
|
119
|
+
--text-xl: 17.5px;
|
|
120
|
+
|
|
121
|
+
/* Colors */
|
|
122
|
+
--color-background: 255 255 255;
|
|
123
|
+
--color-text: 0 0 0;
|
|
124
|
+
|
|
125
|
+
/* Radius */
|
|
126
|
+
--radius-sm: 4px;
|
|
127
|
+
--radius-base: 8px;
|
|
128
|
+
--radius-lg: 12px;
|
|
129
|
+
|
|
130
|
+
/* Shadows */
|
|
131
|
+
--shadow-sm: 0 1px 3px -1px rgba(0, 0, 0, 0.16);
|
|
132
|
+
|
|
133
|
+
/* Spacing */
|
|
134
|
+
--spacing-1: 4px;
|
|
135
|
+
--spacing-2: 8px;
|
|
136
|
+
--spacing-4: 16px;
|
|
137
|
+
}
|
|
138
|
+
`;
|
|
139
|
+
|
|
140
|
+
fs.writeFileSync(tokensPath, content);
|
|
141
|
+
console.log("ā
Created src/tokens.css");
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// -----------------------------
|
|
145
|
+
// šÆ Index CSS (overwrite)
|
|
146
|
+
// -----------------------------
|
|
147
|
+
function createIndexCss() {
|
|
148
|
+
const indexPath = "src/index.css";
|
|
149
|
+
|
|
150
|
+
const content = `@import "tailwindcss";
|
|
151
|
+
@import "./tokens.css";
|
|
152
|
+
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap');
|
|
153
|
+
|
|
154
|
+
body {
|
|
155
|
+
background: rgb(var(--color-background));
|
|
156
|
+
color: rgb(var(--color-text));
|
|
157
|
+
font-feature-settings: "rlig" 1, "calt" 1;
|
|
158
|
+
font-family: var(--font-sans);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.hide-scrollbar {
|
|
162
|
+
-ms-overflow-style: none;
|
|
163
|
+
scrollbar-width: none;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
.hide-scrollbar::-webkit-scrollbar {
|
|
167
|
+
display: none;
|
|
168
|
+
}
|
|
169
|
+
`;
|
|
170
|
+
|
|
171
|
+
fs.writeFileSync(indexPath, content);
|
|
172
|
+
|
|
173
|
+
console.log("ā
src/index.css replaced");
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// -----------------------------
|
|
177
|
+
// āļø TS Config
|
|
178
|
+
// -----------------------------
|
|
179
|
+
function patchTsconfigAlias() {
|
|
180
|
+
const tsconfigPath = "tsconfig.app.json";
|
|
181
|
+
|
|
182
|
+
if (!fs.existsSync(tsconfigPath)) return;
|
|
183
|
+
|
|
184
|
+
const config = JSON.parse(fs.readFileSync(tsconfigPath, "utf-8"));
|
|
185
|
+
|
|
186
|
+
config.compilerOptions = {
|
|
187
|
+
...config.compilerOptions,
|
|
188
|
+
baseUrl: ".",
|
|
189
|
+
paths: {
|
|
190
|
+
"@/*": ["src/*"]
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
fs.writeFileSync(tsconfigPath, JSON.stringify(config, null, 2));
|
|
195
|
+
|
|
196
|
+
console.log("ā
tsconfig alias configured");
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// -----------------------------
|
|
200
|
+
// š ScrollToTop
|
|
201
|
+
// -----------------------------
|
|
202
|
+
function createScrollToTop() {
|
|
203
|
+
const filePath = "src/ScrollToTop.tsx";
|
|
204
|
+
|
|
205
|
+
const content = `import { useEffect } from "react";
|
|
206
|
+
import { useLocation } from "react-router-dom";
|
|
207
|
+
|
|
208
|
+
function ScrollToTop() {
|
|
209
|
+
const { pathname } = useLocation();
|
|
210
|
+
|
|
211
|
+
useEffect(() => {
|
|
212
|
+
window.scrollTo(0, 0);
|
|
213
|
+
}, [pathname]);
|
|
214
|
+
|
|
215
|
+
return null;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
export default ScrollToTop;
|
|
219
|
+
`;
|
|
220
|
+
|
|
221
|
+
fs.writeFileSync(filePath, content);
|
|
222
|
+
|
|
223
|
+
console.log("ā
Created ScrollToTop.tsx");
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// -----------------------------
|
|
227
|
+
// š main.tsx
|
|
228
|
+
// -----------------------------
|
|
229
|
+
function createMainTsx() {
|
|
230
|
+
const filePath = "src/main.tsx";
|
|
231
|
+
|
|
232
|
+
const content = `import { StrictMode } from "react";
|
|
233
|
+
import { createRoot } from "react-dom/client";
|
|
234
|
+
import { BrowserRouter } from "react-router-dom";
|
|
235
|
+
|
|
236
|
+
import "./index.css";
|
|
237
|
+
import App from "./App.tsx";
|
|
238
|
+
import ScrollToTop from "./ScrollToTop.tsx";
|
|
239
|
+
|
|
240
|
+
createRoot(document.getElementById("root")!).render(
|
|
241
|
+
<StrictMode>
|
|
242
|
+
<BrowserRouter>
|
|
243
|
+
<ScrollToTop />
|
|
244
|
+
<App />
|
|
245
|
+
</BrowserRouter>
|
|
246
|
+
</StrictMode>
|
|
247
|
+
);
|
|
248
|
+
`;
|
|
249
|
+
|
|
250
|
+
fs.writeFileSync(filePath, content);
|
|
251
|
+
|
|
252
|
+
console.log("ā
Replaced src/main.tsx");
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// -----------------------------
|
|
256
|
+
// š§ INIT
|
|
257
|
+
// -----------------------------
|
|
59
258
|
export async function init() {
|
|
60
259
|
const config = {
|
|
61
260
|
language: "typescript",
|
|
@@ -76,10 +275,7 @@ export async function init() {
|
|
|
76
275
|
|
|
77
276
|
try {
|
|
78
277
|
if (missingDeps.length) {
|
|
79
|
-
console.log(
|
|
80
|
-
`š¦ Installing dependencies: ${missingDeps.join(", ")}\n`
|
|
81
|
-
);
|
|
82
|
-
|
|
278
|
+
console.log(`š¦ Installing: ${missingDeps.join(", ")}\n`);
|
|
83
279
|
execSync(`npm install ${missingDeps.join(" ")}`, {
|
|
84
280
|
stdio: "inherit"
|
|
85
281
|
});
|
|
@@ -87,17 +283,24 @@ export async function init() {
|
|
|
87
283
|
console.log("ā
Core dependencies already installed\n");
|
|
88
284
|
}
|
|
89
285
|
|
|
90
|
-
console.log("šØ Installing Tailwind
|
|
286
|
+
console.log("šØ Installing Tailwind...\n");
|
|
91
287
|
|
|
92
288
|
execSync(
|
|
93
289
|
"npm install -D tailwindcss @tailwindcss/vite",
|
|
94
290
|
{ stdio: "inherit" }
|
|
95
291
|
);
|
|
96
292
|
|
|
293
|
+
ensureSrcFolder();
|
|
97
294
|
patchViteConfig();
|
|
295
|
+
patchTsconfigAlias();
|
|
296
|
+
createTokensCss();
|
|
297
|
+
createIndexCss();
|
|
298
|
+
createScrollToTop();
|
|
299
|
+
createMainTsx();
|
|
98
300
|
|
|
99
|
-
console.log("\n
|
|
100
|
-
} catch {
|
|
101
|
-
console.log("\nā
|
|
301
|
+
console.log("\nš SparesDev setup completed\n");
|
|
302
|
+
} catch (err) {
|
|
303
|
+
console.log("\nā Setup failed");
|
|
304
|
+
console.error(err.message);
|
|
102
305
|
}
|
|
103
306
|
}
|