meno-core 1.0.31 → 1.0.33

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 (2) hide show
  1. package/package.json +14 -25
  2. package/bin/cli.ts +0 -440
package/package.json CHANGED
@@ -1,19 +1,21 @@
1
1
  {
2
2
  "name": "meno-core",
3
- "version": "1.0.31",
4
- "files": ["dist"],
3
+ "version": "1.0.33",
4
+ "files": [
5
+ "dist"
6
+ ],
5
7
  "type": "module",
6
8
  "bin": {
7
- "meno": "./bin/cli.ts"
9
+ "meno": "./dist/bin/cli.js"
8
10
  },
9
11
  "exports": {
10
- ".": "./lib/shared/index.ts",
11
- "./server": "./lib/server/index.ts",
12
- "./client": "./lib/client/index.ts",
13
- "./shared": "./lib/shared/index.ts",
14
- "./shared/richtext": "./lib/shared/richtext/index.ts",
15
- "./shared/*": "./lib/shared/*.ts",
16
- "./test-utils": "./lib/test-utils/index.ts"
12
+ ".": "./dist/lib/shared/index.js",
13
+ "./server": "./dist/lib/server/index.js",
14
+ "./client": "./dist/lib/client/index.js",
15
+ "./shared": "./dist/lib/shared/index.js",
16
+ "./shared/richtext": "./dist/lib/shared/richtext/index.js",
17
+ "./shared/*": "./dist/lib/shared/*.js",
18
+ "./test-utils": "./dist/lib/test-utils/index.js"
17
19
  },
18
20
  "scripts": {
19
21
  "dev": "cd ../../example && bun run ../packages/core/bin/cli.ts dev",
@@ -24,21 +26,8 @@
24
26
  "dev:full": "bun run build:static && bun run serve",
25
27
  "test": "bun test",
26
28
  "typecheck": "tsc --noEmit",
27
- "prepublishOnly": "node scripts/build-for-publish.mjs"
28
- },
29
- "publishConfig": {
30
- "bin": {
31
- "meno": "./dist/bin/cli.js"
32
- },
33
- "exports": {
34
- ".": "./dist/lib/shared/index.js",
35
- "./server": "./dist/lib/server/index.js",
36
- "./client": "./dist/lib/client/index.js",
37
- "./shared": "./dist/lib/shared/index.js",
38
- "./shared/richtext": "./dist/lib/shared/richtext/index.js",
39
- "./shared/*": "./dist/lib/shared/*.js",
40
- "./test-utils": "./dist/lib/test-utils/index.js"
41
- }
29
+ "prepublishOnly": "node scripts/build-for-publish.mjs",
30
+ "postpublish": "git checkout -- package.json"
42
31
  },
43
32
  "dependencies": {
44
33
  "@emotion/css": "^11.13.5",
package/bin/cli.ts DELETED
@@ -1,440 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * meno CLI
4
- * Commands: dev, build, init
5
- */
6
-
7
- import { resolve, join } from 'path';
8
- import { existsSync, mkdirSync, writeFileSync, cpSync, readFileSync } from 'fs';
9
- import { setProjectRoot } from '../lib/server/projectContext';
10
- import { generateBuildErrorPage, type BuildErrorsData } from '../lib/server/ssr/buildErrorOverlay';
11
- import { createRuntimeServer, serveFile, fileExists as runtimeFileExists } from '../lib/server/runtime';
12
-
13
- const args = process.argv.slice(2);
14
- const command = args[0];
15
-
16
- function printHelp() {
17
- console.log(`
18
- meno - Visual editor for JSON-based pages
19
-
20
- Requirements:
21
- - Bun or Node.js 18+
22
-
23
- Usage:
24
- meno <command> [options]
25
-
26
- Commands:
27
- dev Start development server with hot reload
28
- build Build static HTML files for production
29
- serve Serve built files from ./dist on port 8080
30
- init Initialize a new project
31
-
32
- Options:
33
- build --dev Include draft pages in build (for local preview)
34
-
35
- Examples:
36
- meno dev Start dev server in current directory
37
- meno build Build static files to ./dist (excludes drafts)
38
- meno build --dev Build including draft pages
39
- meno serve Serve built files on port 8080
40
- meno init my-project Create new project in ./my-project
41
- `);
42
- }
43
-
44
- // Parse _headers file (Netlify/Cloudflare format)
45
- function parseHeadersFile(distPath: string): Map<string, Record<string, string>> {
46
- const headersPath = join(distPath, '_headers');
47
- const headers = new Map<string, Record<string, string>>();
48
-
49
- if (!existsSync(headersPath)) return headers;
50
-
51
- const content = readFileSync(headersPath, 'utf-8');
52
- let currentPath = '';
53
-
54
- for (const line of content.split('\n')) {
55
- const trimmed = line.trim();
56
- if (!trimmed || trimmed.startsWith('#')) continue;
57
-
58
- if (!line.startsWith(' ') && !line.startsWith('\t')) {
59
- // Path line
60
- currentPath = trimmed;
61
- if (!headers.has(currentPath)) {
62
- headers.set(currentPath, {});
63
- }
64
- } else if (currentPath && trimmed.includes(':')) {
65
- // Header line
66
- const colonIndex = trimmed.indexOf(':');
67
- const name = trimmed.substring(0, colonIndex).trim();
68
- const value = trimmed.substring(colonIndex + 1).trim();
69
- headers.get(currentPath)![name] = value;
70
- }
71
- }
72
-
73
- return headers;
74
- }
75
-
76
- // Get headers matching a pathname
77
- function getMatchingHeaders(
78
- pathname: string,
79
- headersMap: Map<string, Record<string, string>>
80
- ): Record<string, string> {
81
- const result: Record<string, string> = {};
82
-
83
- headersMap.forEach((headers, pattern) => {
84
- if (pattern === pathname || pattern === '/*') {
85
- Object.assign(result, headers);
86
- } else if (pattern.endsWith('/*')) {
87
- const prefix = pattern.slice(0, -1);
88
- if (pathname.startsWith(prefix)) {
89
- Object.assign(result, headers);
90
- }
91
- }
92
- });
93
-
94
- return result;
95
- }
96
-
97
- // Start static file server on port 8080 (non-blocking)
98
- async function startStaticServer(distPath: string) {
99
- const { SERVE_PORT } = await import('../lib/shared/constants');
100
-
101
- // Parse _headers file once on startup
102
- const headersMap = parseHeadersFile(distPath);
103
-
104
- const server = await createRuntimeServer({
105
- port: SERVE_PORT,
106
- hostname: 'localhost',
107
- async fetch(req: Request) {
108
- const url = new URL(req.url);
109
- let pathname = url.pathname;
110
-
111
- // Check for build errors and show overlay (except for _errors.json itself)
112
- if (pathname !== '/_errors.json') {
113
- const errorsPath = join(distPath, '_errors.json');
114
- if (existsSync(errorsPath)) {
115
- try {
116
- const errorsData: BuildErrorsData = JSON.parse(readFileSync(errorsPath, 'utf-8'));
117
- return new Response(generateBuildErrorPage(errorsData), {
118
- headers: { 'Content-Type': 'text/html; charset=utf-8' },
119
- });
120
- } catch {
121
- // If we can't parse errors file, continue normally
122
- }
123
- }
124
- }
125
-
126
- // Default to index.html for root
127
- if (pathname === '/') {
128
- pathname = '/index.html';
129
- }
130
-
131
- // Get custom headers for this path
132
- const customHeaders = getMatchingHeaders(pathname, headersMap);
133
-
134
- // Try to serve the file
135
- const filePath = join(distPath, pathname);
136
-
137
- // Check if file exists and serve it
138
- if (await runtimeFileExists(filePath)) {
139
- return await serveFile(filePath, customHeaders);
140
- }
141
-
142
- // Try with .html extension for clean URLs
143
- const htmlPath = filePath.endsWith('.html') ? filePath : `${filePath}.html`;
144
- if (await runtimeFileExists(htmlPath)) {
145
- return await serveFile(htmlPath, customHeaders);
146
- }
147
-
148
- // Try index.html in directory
149
- const indexPath = join(filePath, 'index.html');
150
- if (await runtimeFileExists(indexPath)) {
151
- return await serveFile(indexPath, customHeaders);
152
- }
153
-
154
- return new Response('Not Found', { status: 404 });
155
- },
156
- });
157
-
158
- return server;
159
- }
160
-
161
- async function runDev() {
162
- const projectRoot = process.cwd();
163
-
164
- // Validate project structure
165
- if (!existsSync(join(projectRoot, 'pages'))) {
166
- console.error('❌ No pages directory found. Are you in a valid project directory?');
167
- console.error(' Run "meno init <project-name>" to create a new project.');
168
- process.exit(1);
169
- }
170
-
171
- // Set project root for path resolution
172
- setProjectRoot(projectRoot);
173
-
174
- console.log(`📁 Project root: ${projectRoot}`);
175
-
176
- // Start static server on 8080 if dist exists
177
- const distPath = join(projectRoot, 'dist');
178
- if (existsSync(distPath)) {
179
- const staticServer = await startStaticServer(distPath);
180
- console.log(`🚀 Static server running at http://localhost:${staticServer.port}`);
181
- }
182
-
183
- // Import and run the dev server (it handles all initialization internally)
184
- await import('../entries/server-router');
185
- }
186
-
187
- async function runBuild(isDev: boolean = false) {
188
- const projectRoot = process.cwd();
189
-
190
- // Validate project structure
191
- if (!existsSync(join(projectRoot, 'pages'))) {
192
- console.error('❌ No pages directory found. Are you in a valid project directory?');
193
- process.exit(1);
194
- }
195
-
196
- // Set project root for path resolution
197
- setProjectRoot(projectRoot);
198
-
199
- // Set dev mode environment variable (drafts are built in dev mode)
200
- if (isDev) {
201
- process.env.MENO_DEV_BUILD = 'true';
202
- }
203
-
204
- console.log(`📁 Building project: ${projectRoot}${isDev ? ' (dev mode - including drafts)' : ''}`);
205
-
206
- // Import and run build
207
- const { buildStaticPages } = await import('../build-static.ts');
208
- await buildStaticPages();
209
- }
210
-
211
- async function runServe() {
212
- const projectRoot = process.cwd();
213
- const distPath = join(projectRoot, 'dist');
214
-
215
- // Validate dist directory exists
216
- if (!existsSync(distPath)) {
217
- console.error('❌ No dist directory found. Run "meno build" first.');
218
- process.exit(1);
219
- }
220
-
221
- console.log(`📁 Serving built files from: ${distPath}`);
222
- const server = await startStaticServer(distPath);
223
- console.log(`🚀 Static server running at http://localhost:${server.port}`);
224
-
225
- // Keep the process alive
226
- await new Promise(() => {});
227
- }
228
-
229
- async function runInit(projectName?: string) {
230
- if (!projectName) {
231
- console.error('❌ Please provide a project name: meno init <project-name>');
232
- process.exit(1);
233
- }
234
-
235
- const projectPath = resolve(process.cwd(), projectName);
236
-
237
- if (existsSync(projectPath)) {
238
- console.error(`❌ Directory "${projectName}" already exists.`);
239
- process.exit(1);
240
- }
241
-
242
- console.log(`\n🚀 Creating new meno project: ${projectName}\n`);
243
-
244
- // Create project structure
245
- mkdirSync(projectPath, { recursive: true });
246
- mkdirSync(join(projectPath, 'pages'));
247
- mkdirSync(join(projectPath, 'components'));
248
- mkdirSync(join(projectPath, 'fonts'));
249
- mkdirSync(join(projectPath, 'images'));
250
-
251
- // Create default project.config.json
252
- const defaultConfig = {
253
- fonts: [],
254
- editor: {
255
- theme: 'dark'
256
- }
257
- };
258
- writeFileSync(
259
- join(projectPath, 'project.config.json'),
260
- JSON.stringify(defaultConfig, null, 2)
261
- );
262
-
263
- // Create default colors.json
264
- const defaultColors = {
265
- default: 'light',
266
- themes: {
267
- light: {
268
- label: 'Light',
269
- colors: {
270
- text: '#1f2937',
271
- bg: '#ffffff'
272
- }
273
- }
274
- }
275
- };
276
- writeFileSync(
277
- join(projectPath, 'colors.json'),
278
- JSON.stringify(defaultColors, null, 2)
279
- );
280
-
281
- // Create package.json for deployment
282
- const packageJson = {
283
- name: projectName,
284
- version: '1.0.0',
285
- private: true,
286
- scripts: {
287
- dev: 'meno dev',
288
- build: 'meno build',
289
- },
290
- dependencies: {
291
- 'meno-core': '^1.0.0'
292
- }
293
- };
294
- writeFileSync(
295
- join(projectPath, 'package.json'),
296
- JSON.stringify(packageJson, null, 2)
297
- );
298
-
299
- // Create .gitignore
300
- const gitignore = `# Dependencies
301
- node_modules/
302
-
303
- # Build output
304
- dist/
305
-
306
- # OS files
307
- .DS_Store
308
- `;
309
- writeFileSync(
310
- join(projectPath, '.gitignore'),
311
- gitignore
312
- );
313
-
314
- // Create netlify.toml
315
- const netlifyConfig = `[build]
316
- command = "bun install && bun run build"
317
- publish = "dist"
318
-
319
- [build.environment]
320
- BUN_VERSION = "1"
321
- `;
322
- writeFileSync(
323
- join(projectPath, 'netlify.toml'),
324
- netlifyConfig
325
- );
326
-
327
- // Create vercel.json
328
- const vercelConfig = {
329
- buildCommand: 'bun run build',
330
- outputDirectory: 'dist',
331
- installCommand: 'bun install'
332
- };
333
- writeFileSync(
334
- join(projectPath, 'vercel.json'),
335
- JSON.stringify(vercelConfig, null, 2)
336
- );
337
-
338
- // Create wrangler.toml for Cloudflare Pages
339
- const cloudflareConfig = `name = "${projectName}"
340
- compatibility_date = "2024-01-01"
341
- pages_build_output_dir = "dist"
342
-
343
- [build]
344
- command = "bun install && bun run build"
345
- `;
346
- writeFileSync(
347
- join(projectPath, 'wrangler.toml'),
348
- cloudflareConfig
349
- );
350
-
351
- // Create default index page
352
- const defaultPage = {
353
- meta: {
354
- title: 'Your Project Title',
355
- description: 'Your Project Description',
356
- keywords: '',
357
- ogTitle: 'Your Project Title',
358
- ogDescription: 'Your Project Description',
359
- ogType: 'website'
360
- },
361
- root: {
362
- type: 'node',
363
- tag: 'div',
364
- style: {
365
- base: {
366
- padding: '40px'
367
- },
368
- tablet: {},
369
- mobile: {}
370
- },
371
- children: [
372
- {
373
- type: 'node',
374
- tag: 'h1',
375
- style: {
376
- base: {}
377
- },
378
- children: 'Hello'
379
- }
380
- ]
381
- }
382
- };
383
- writeFileSync(
384
- join(projectPath, 'pages', 'index.json'),
385
- JSON.stringify(defaultPage, null, 2)
386
- );
387
-
388
- console.log('✅ Created project structure:');
389
- console.log(` ${projectName}/`);
390
- console.log(' ├── pages/');
391
- console.log(' │ └── index.json');
392
- console.log(' ├── components/');
393
- console.log(' ├── fonts/');
394
- console.log(' ├── images/');
395
- console.log(' ├── colors.json');
396
- console.log(' ├── project.config.json');
397
- console.log(' ├── package.json');
398
- console.log(' ├── netlify.toml');
399
- console.log(' ├── vercel.json');
400
- console.log(' ├── wrangler.toml');
401
- console.log(' └── .gitignore');
402
- console.log('\n🎉 Project created successfully!\n');
403
- console.log('Requirements:');
404
- console.log(' Bun - https://bun.sh');
405
- console.log('');
406
- console.log('Next steps:');
407
- console.log(` cd ${projectName}`);
408
- console.log(' bun install # Install dependencies');
409
- console.log(' bun run dev # Start dev server');
410
- console.log('');
411
- console.log('Deploy:');
412
- console.log(' Push to GitHub and connect to Netlify/Vercel/Cloudflare');
413
- console.log(' Config files included - auto-detected!');
414
- console.log('');
415
- }
416
-
417
- // Main
418
- switch (command) {
419
- case 'dev':
420
- runDev();
421
- break;
422
- case 'build':
423
- runBuild(args.includes('--dev'));
424
- break;
425
- case 'serve':
426
- runServe();
427
- break;
428
- case 'init':
429
- runInit(args[1]);
430
- break;
431
- case '--help':
432
- case '-h':
433
- case undefined:
434
- printHelp();
435
- break;
436
- default:
437
- console.error(`Unknown command: ${command}`);
438
- printHelp();
439
- process.exit(1);
440
- }