@stratawp/cli 0.2.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.
@@ -0,0 +1,2 @@
1
+
2
+ export { }
package/dist/create.js ADDED
@@ -0,0 +1,386 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/create.ts
4
+ import prompts from "prompts";
5
+ import chalk from "chalk";
6
+ import ora from "ora";
7
+ import { execa } from "execa";
8
+ import fs from "fs-extra";
9
+ import path from "path";
10
+ import validatePackageName from "validate-npm-package-name";
11
+ async function main() {
12
+ console.log(chalk.bold.cyan("\n\u26A1 Create StrataWP Theme\n"));
13
+ const response = await prompts([
14
+ {
15
+ type: "text",
16
+ name: "name",
17
+ message: "Theme name:",
18
+ initial: "My Awesome Theme"
19
+ },
20
+ {
21
+ type: "text",
22
+ name: "slug",
23
+ message: "Theme slug (directory name):",
24
+ initial: (prev) => prev.toLowerCase().replace(/\s+/g, "-"),
25
+ validate: (value) => {
26
+ const validation = validatePackageName(value);
27
+ if (!validation.validForNewPackages) {
28
+ return validation.errors?.[0] || "Invalid package name";
29
+ }
30
+ return true;
31
+ }
32
+ },
33
+ {
34
+ type: "text",
35
+ name: "description",
36
+ message: "Description:",
37
+ initial: "A theme built with StrataWP"
38
+ },
39
+ {
40
+ type: "text",
41
+ name: "author",
42
+ message: "Author name:"
43
+ },
44
+ {
45
+ type: "select",
46
+ name: "cssFramework",
47
+ message: "CSS Framework:",
48
+ choices: [
49
+ { title: "Vanilla CSS (Custom Properties)", value: "vanilla" },
50
+ { title: "Tailwind CSS", value: "tailwind" },
51
+ { title: "UnoCSS (Recommended)", value: "unocss" },
52
+ { title: "Panda CSS (Type-safe)", value: "panda" }
53
+ ],
54
+ initial: 2
55
+ },
56
+ {
57
+ type: "confirm",
58
+ name: "typescript",
59
+ message: "Use TypeScript?",
60
+ initial: true
61
+ },
62
+ {
63
+ type: "confirm",
64
+ name: "testing",
65
+ message: "Include testing setup?",
66
+ initial: true
67
+ },
68
+ {
69
+ type: "confirm",
70
+ name: "ai",
71
+ message: "Enable AI-powered features?",
72
+ initial: false
73
+ }
74
+ ]);
75
+ if (!response.slug) {
76
+ console.log(chalk.red("\n\u2716 Theme creation cancelled\n"));
77
+ process.exit(1);
78
+ }
79
+ const config = response;
80
+ await createTheme(config);
81
+ }
82
+ async function createTheme(config) {
83
+ const spinner = ora("Creating theme...").start();
84
+ try {
85
+ const themePath = path.resolve(process.cwd(), config.slug);
86
+ if (await fs.pathExists(themePath)) {
87
+ spinner.fail(`Directory ${config.slug} already exists`);
88
+ process.exit(1);
89
+ }
90
+ await fs.ensureDir(themePath);
91
+ spinner.text = "Copying template files...";
92
+ await createBasicStructure(themePath, config);
93
+ spinner.text = "Installing dependencies...";
94
+ await execa("pnpm", ["install"], { cwd: themePath });
95
+ spinner.succeed(chalk.green("Theme created successfully!"));
96
+ console.log(chalk.cyan("\n\u{1F4E6} Next steps:\n"));
97
+ console.log(` cd ${config.slug}`);
98
+ console.log(" pnpm dev");
99
+ console.log();
100
+ } catch (error) {
101
+ spinner.fail("Failed to create theme");
102
+ console.error(error);
103
+ process.exit(1);
104
+ }
105
+ }
106
+ async function createBasicStructure(themePath, config) {
107
+ const packageJson = {
108
+ name: config.slug,
109
+ version: "1.0.0",
110
+ description: config.description,
111
+ author: config.author,
112
+ license: "GPL-3.0-or-later",
113
+ type: "module",
114
+ scripts: {
115
+ dev: "vite",
116
+ build: "vite build",
117
+ preview: "vite preview"
118
+ },
119
+ dependencies: {
120
+ "@wordpress/block-editor": "^12.19.0",
121
+ "@wordpress/blocks": "^12.28.0",
122
+ "@wordpress/components": "^27.0.0",
123
+ "@wordpress/element": "^5.28.0",
124
+ "@wordpress/i18n": "^4.51.0"
125
+ },
126
+ devDependencies: {
127
+ "@stratawp/cli": "^0.2.0",
128
+ "@stratawp/vite-plugin": "^0.2.0",
129
+ "@vitejs/plugin-react": "^4.2.1",
130
+ vite: "^5.0.10",
131
+ typescript: config.typescript ? "^5.3.3" : void 0
132
+ }
133
+ };
134
+ await fs.writeJson(path.join(themePath, "package.json"), packageJson, { spaces: 2 });
135
+ const styleCSS = `/*
136
+ Theme Name: ${config.name}
137
+ Theme URI: https://example.com
138
+ Author: ${config.author}
139
+ Description: ${config.description}
140
+ Version: 1.0.0
141
+ License: GPL-3.0-or-later
142
+ Text Domain: ${config.slug}
143
+
144
+ Built with \u26A1 StrataWP
145
+ */`;
146
+ await fs.writeFile(path.join(themePath, "style.css"), styleCSS);
147
+ const readme = `# ${config.name}
148
+
149
+ ${config.description}
150
+
151
+ ## Development
152
+
153
+ \`\`\`bash
154
+ pnpm dev
155
+ \`\`\`
156
+
157
+ ## Build
158
+
159
+ \`\`\`bash
160
+ pnpm build
161
+ \`\`\`
162
+
163
+ Built with [StrataWP](https://github.com/JonImmsWordpressDev/StrataWP)
164
+ `;
165
+ await fs.writeFile(path.join(themePath, "README.md"), readme);
166
+ const viteConfig = `import { defineConfig } from 'vite'
167
+ import react from '@vitejs/plugin-react'
168
+ import { strataWP } from '@stratawp/vite-plugin'
169
+
170
+ export default defineConfig({
171
+ plugins: [
172
+ react(),
173
+ strataWP({
174
+ blocks: {
175
+ dir: 'src/blocks',
176
+ autoRegister: true,
177
+ namespace: '${config.slug}',
178
+ },
179
+ ${config.cssFramework !== "vanilla" ? `designSystem: {
180
+ enabled: true,
181
+ framework: '${config.cssFramework === "unocss" ? "unocss" : config.cssFramework === "tailwind" ? "tailwind" : "none"}',
182
+ wordpressPresets: true,
183
+ },` : ""}
184
+ performance: {
185
+ criticalCSS: { enabled: true },
186
+ lazyLoading: { enabled: true },
187
+ preload: { enabled: true },
188
+ },
189
+ phpHmr: {
190
+ enabled: true,
191
+ watch: ['**/*.php', 'theme.json', 'templates/**/*'],
192
+ },
193
+ manifest: {
194
+ enabled: true,
195
+ wordpress: true,
196
+ },
197
+ }),
198
+ ],
199
+ build: {
200
+ rollupOptions: {
201
+ input: {
202
+ main: './src/js/main.ts',
203
+ editor: './src/js/editor.ts',
204
+ },
205
+ },
206
+ },
207
+ })`;
208
+ await fs.writeFile(path.join(themePath, "vite.config.ts"), viteConfig);
209
+ const functionsPhp = `<?php
210
+ /**
211
+ * Theme functions
212
+ */
213
+
214
+ if (!defined('ABSPATH')) {
215
+ exit;
216
+ }
217
+
218
+ // Load Vite assets
219
+ require_once get_template_directory() . '/inc/vite-assets.php';
220
+ `;
221
+ await fs.writeFile(path.join(themePath, "functions.php"), functionsPhp);
222
+ const themeJson = {
223
+ $schema: "https://schemas.wp.org/trunk/theme.json",
224
+ version: 2,
225
+ settings: {
226
+ appearanceTools: true,
227
+ layout: {
228
+ contentSize: "800px",
229
+ wideSize: "1200px"
230
+ }
231
+ }
232
+ };
233
+ await fs.writeJson(path.join(themePath, "theme.json"), themeJson, { spaces: 2 });
234
+ await fs.ensureDir(path.join(themePath, "src"));
235
+ await fs.ensureDir(path.join(themePath, "src/css"));
236
+ await fs.ensureDir(path.join(themePath, "src/js"));
237
+ await fs.ensureDir(path.join(themePath, "src/blocks"));
238
+ await fs.ensureDir(path.join(themePath, "inc"));
239
+ await fs.ensureDir(path.join(themePath, "templates"));
240
+ await fs.ensureDir(path.join(themePath, "parts"));
241
+ await fs.writeFile(
242
+ path.join(themePath, "src/js/main.ts"),
243
+ `import '../css/main.css'
244
+
245
+ console.log('${config.name} loaded')
246
+ `
247
+ );
248
+ await fs.writeFile(
249
+ path.join(themePath, "src/js/editor.ts"),
250
+ `import '../css/editor.css'
251
+ `
252
+ );
253
+ await fs.writeFile(
254
+ path.join(themePath, "src/css/main.css"),
255
+ `/* Main stylesheet for ${config.name} */
256
+
257
+ body {
258
+ font-family: system-ui, sans-serif;
259
+ }
260
+ `
261
+ );
262
+ await fs.writeFile(
263
+ path.join(themePath, "src/css/editor.css"),
264
+ `/* Editor stylesheet */
265
+ `
266
+ );
267
+ const viteAssetsPhp = `<?php
268
+ /**
269
+ * Vite asset loading helper
270
+ */
271
+
272
+ function load_vite_assets() {
273
+ $manifest_path = get_template_directory() . '/dist/.vite/manifest.json';
274
+
275
+ if (!file_exists($manifest_path)) {
276
+ return;
277
+ }
278
+
279
+ $manifest = json_decode(file_get_contents($manifest_path), true);
280
+
281
+ if (isset($manifest['src/js/main.ts'])) {
282
+ wp_enqueue_script(
283
+ '${config.slug}-main',
284
+ get_template_directory_uri() . '/dist/' . $manifest['src/js/main.ts']['file'],
285
+ [],
286
+ null,
287
+ true
288
+ );
289
+
290
+ if (isset($manifest['src/js/main.ts']['css'])) {
291
+ foreach ($manifest['src/js/main.ts']['css'] as $css) {
292
+ wp_enqueue_style(
293
+ '${config.slug}-main-css',
294
+ get_template_directory_uri() . '/dist/' . $css,
295
+ [],
296
+ null
297
+ );
298
+ }
299
+ }
300
+ }
301
+ }
302
+
303
+ add_action('wp_enqueue_scripts', 'load_vite_assets');
304
+ `;
305
+ await fs.writeFile(path.join(themePath, "inc/vite-assets.php"), viteAssetsPhp);
306
+ const indexTemplate = `<!-- wp:template-part {"slug":"header","tagName":"header"} /-->
307
+
308
+ <!-- wp:group {"tagName":"main","layout":{"type":"constrained"}} -->
309
+ <main class="wp-block-group">
310
+ <!-- wp:query {"queryId":0,"query":{"perPage":10,"pages":0,"offset":0,"postType":"post","order":"desc","orderBy":"date","author":"","search":"","exclude":[],"sticky":"","inherit":true}} -->
311
+ <div class="wp-block-query">
312
+ <!-- wp:post-template -->
313
+ <!-- wp:post-title {"isLink":true} /-->
314
+ <!-- wp:post-date /-->
315
+ <!-- wp:post-excerpt /-->
316
+ <!-- /wp:post-template -->
317
+
318
+ <!-- wp:query-pagination -->
319
+ <!-- wp:query-pagination-previous /-->
320
+ <!-- wp:query-pagination-numbers /-->
321
+ <!-- wp:query-pagination-next /-->
322
+ <!-- /wp:query-pagination -->
323
+
324
+ <!-- wp:query-no-results -->
325
+ <!-- wp:paragraph -->
326
+ <p>No posts found.</p>
327
+ <!-- /wp:paragraph -->
328
+ <!-- /wp:query-no-results -->
329
+ </div>
330
+ <!-- /wp:query -->
331
+ </main>
332
+ <!-- /wp:group -->
333
+
334
+ <!-- wp:template-part {"slug":"footer","tagName":"footer"} /-->`;
335
+ await fs.writeFile(path.join(themePath, "templates/index.html"), indexTemplate);
336
+ const headerTemplate = `<!-- wp:group {"tagName":"header","style":{"spacing":{"padding":{"top":"2rem","bottom":"2rem"}}},"layout":{"type":"constrained"}} -->
337
+ <header class="wp-block-group" style="padding-top:2rem;padding-bottom:2rem">
338
+ <!-- wp:group {"layout":{"type":"flex","flexWrap":"nowrap","justifyContent":"space-between"}} -->
339
+ <div class="wp-block-group">
340
+ <!-- wp:site-title /-->
341
+ <!-- wp:navigation /-->
342
+ </div>
343
+ <!-- /wp:group -->
344
+ </header>
345
+ <!-- /wp:group -->`;
346
+ await fs.writeFile(path.join(themePath, "parts/header.html"), headerTemplate);
347
+ const footerTemplate = `<!-- wp:group {"tagName":"footer","style":{"spacing":{"padding":{"top":"2rem","bottom":"2rem"}}},"layout":{"type":"constrained"}} -->
348
+ <footer class="wp-block-group" style="padding-top:2rem;padding-bottom:2rem">
349
+ <!-- wp:group {"layout":{"type":"flex","flexWrap":"nowrap","justifyContent":"center"}} -->
350
+ <div class="wp-block-group">
351
+ <!-- wp:paragraph -->
352
+ <p>Built with StrataWP</p>
353
+ <!-- /wp:paragraph -->
354
+ </div>
355
+ <!-- /wp:group -->
356
+ </footer>
357
+ <!-- /wp:group -->`;
358
+ await fs.writeFile(path.join(themePath, "parts/footer.html"), footerTemplate);
359
+ const singleTemplate = `<!-- wp:template-part {"slug":"header","tagName":"header"} /-->
360
+
361
+ <!-- wp:group {"tagName":"main","layout":{"type":"constrained"}} -->
362
+ <main class="wp-block-group">
363
+ <!-- wp:post-title /-->
364
+ <!-- wp:post-featured-image /-->
365
+ <!-- wp:post-content /-->
366
+ </main>
367
+ <!-- /wp:group -->
368
+
369
+ <!-- wp:template-part {"slug":"footer","tagName":"footer"} /-->`;
370
+ await fs.writeFile(path.join(themePath, "templates/single.html"), singleTemplate);
371
+ const pageTemplate = `<!-- wp:template-part {"slug":"header","tagName":"header"} /-->
372
+
373
+ <!-- wp:group {"tagName":"main","layout":{"type":"constrained"}} -->
374
+ <main class="wp-block-group">
375
+ <!-- wp:post-title /-->
376
+ <!-- wp:post-content /-->
377
+ </main>
378
+ <!-- /wp:group -->
379
+
380
+ <!-- wp:template-part {"slug":"footer","tagName":"footer"} /-->`;
381
+ await fs.writeFile(path.join(themePath, "templates/page.html"), pageTemplate);
382
+ }
383
+ main().catch((error) => {
384
+ console.error(chalk.red("Error:"), error);
385
+ process.exit(1);
386
+ });
@@ -0,0 +1,2 @@
1
+
2
+ export { }