@micropress/theme-sdk 0.1.0 → 0.1.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/cli/index.js CHANGED
@@ -179,6 +179,7 @@ var import_commander = require("commander");
179
179
  var fs = __toESM(require("fs"));
180
180
  var path = __toESM(require("path"));
181
181
  var import_child_process = require("child_process");
182
+ var SDK_VERSION = "0.1.2";
182
183
  var MANIFEST_TEMPLATE = `{
183
184
  "id": "{{name}}",
184
185
  "name": "{{displayName}}",
@@ -361,7 +362,7 @@ var PACKAGE_JSON_TEMPLATE = `{
361
362
  "package": "micropress-theme package"
362
363
  },
363
364
  "devDependencies": {
364
- "@micropress/theme-sdk": "^1.0.0",
365
+ "@micropress/theme-sdk": "^{{sdkVersion}}",
365
366
  "typescript": "^5.0.0"
366
367
  },
367
368
  "keywords": ["micropress", "theme"],
@@ -389,6 +390,80 @@ dist/
389
390
  *.zip
390
391
  .DS_Store
391
392
  `;
393
+ var GITHUB_RELEASE_WORKFLOW_TEMPLATE = `name: Release Theme
394
+
395
+ on:
396
+ push:
397
+ tags:
398
+ - 'v*'
399
+
400
+ permissions:
401
+ contents: write
402
+
403
+ jobs:
404
+ release:
405
+ runs-on: ubuntu-latest
406
+ steps:
407
+ - uses: actions/checkout@v4
408
+
409
+ - uses: actions/setup-node@v4
410
+ with:
411
+ node-version: '22'
412
+
413
+ - name: Install dependencies
414
+ run: npm ci
415
+
416
+ - name: Validate theme
417
+ run: npm run validate
418
+
419
+ - name: Build theme
420
+ run: npm run build
421
+
422
+ - name: Package theme
423
+ run: npm run package
424
+
425
+ - name: Create GitHub Release
426
+ uses: softprops/action-gh-release@v2
427
+ with:
428
+ files: "*.zip"
429
+ generate_release_notes: true
430
+ `;
431
+ var GITHUB_WORKFLOW_TEMPLATE = `name: Build Theme
432
+
433
+ on:
434
+ push:
435
+ branches: [main]
436
+ pull_request:
437
+ branches: [main]
438
+
439
+ jobs:
440
+ build:
441
+ runs-on: ubuntu-latest
442
+ steps:
443
+ - uses: actions/checkout@v4
444
+
445
+ - uses: actions/setup-node@v4
446
+ with:
447
+ node-version: '22'
448
+
449
+ - name: Install dependencies
450
+ run: npm ci
451
+
452
+ - name: Validate theme
453
+ run: npm run validate
454
+
455
+ - name: Build theme
456
+ run: npm run build
457
+
458
+ - name: Package theme
459
+ run: npm run package
460
+
461
+ - name: Upload theme artifact
462
+ uses: actions/upload-artifact@v4
463
+ with:
464
+ name: theme-package
465
+ path: "*.zip"
466
+ `;
392
467
  function toDisplayName(name) {
393
468
  return name.split(/[-_]/).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
394
469
  }
@@ -409,7 +484,8 @@ async function initCommand(name, options) {
409
484
  fs.mkdirSync(path.join(targetDir, "assets"));
410
485
  const vars = {
411
486
  name,
412
- displayName: toDisplayName(name)
487
+ displayName: toDisplayName(name),
488
+ sdkVersion: SDK_VERSION
413
489
  };
414
490
  const files = [
415
491
  { path: "manifest.json", content: replaceTemplateVars(MANIFEST_TEMPLATE, vars) },
@@ -417,7 +493,9 @@ async function initCommand(name, options) {
417
493
  { path: "src/renderers.ts", content: replaceTemplateVars(RENDERERS_TEMPLATE, vars) },
418
494
  { path: "package.json", content: replaceTemplateVars(PACKAGE_JSON_TEMPLATE, vars) },
419
495
  { path: "tsconfig.json", content: TSCONFIG_TEMPLATE },
420
- { path: ".gitignore", content: GITIGNORE_TEMPLATE }
496
+ { path: ".gitignore", content: GITIGNORE_TEMPLATE },
497
+ { path: ".github/workflows/build.yml", content: GITHUB_WORKFLOW_TEMPLATE },
498
+ { path: ".github/workflows/release.yml", content: GITHUB_RELEASE_WORKFLOW_TEMPLATE }
421
499
  ];
422
500
  for (const file of files) {
423
501
  const filePath = path.join(targetDir, file.path);
@@ -703,7 +781,7 @@ function createZipManually(sourceDir, outputPath) {
703
781
  }
704
782
 
705
783
  // cli/index.ts
706
- var VERSION = "0.1.0";
784
+ var VERSION = "0.1.2";
707
785
  var program = new import_commander.Command();
708
786
  program.name("micropress-theme").description("CLI for building MicroPress themes").version(VERSION);
709
787
  program.command("init <name>").description("Initialize a new theme project").option("-d, --directory <dir>", "Directory to create theme in", ".").option("--no-git", "Skip git initialization").action(initCommand);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../cli/commands/build.ts","../../cli/index.ts","../../cli/commands/init.ts","../../cli/commands/validate.ts","../../cli/commands/package.ts"],"sourcesContent":["import * as fs from 'fs';\nimport * as path from 'path';\nimport { execSync } from 'child_process';\n\ninterface BuildOptions {\n watch: boolean;\n output: string;\n}\n\nexport async function buildCommand(options: BuildOptions): Promise<void> {\n const cwd = process.cwd();\n const outputDir = path.resolve(cwd, options.output);\n\n console.log('Building theme...');\n console.log(`Output: ${outputDir}`);\n console.log();\n\n // Check for required files\n const manifestPath = path.join(cwd, 'manifest.json');\n const tsconfigPath = path.join(cwd, 'tsconfig.json');\n\n if (!fs.existsSync(manifestPath)) {\n console.error('Error: manifest.json not found');\n console.error('Run this command from your theme directory');\n process.exit(1);\n }\n\n // Create output directory\n if (!fs.existsSync(outputDir)) {\n fs.mkdirSync(outputDir, { recursive: true });\n }\n\n // Copy manifest.json\n fs.copyFileSync(manifestPath, path.join(outputDir, 'manifest.json'));\n console.log(' Copied: manifest.json');\n\n // Copy CSS files\n const srcDir = path.join(cwd, 'src');\n if (fs.existsSync(srcDir)) {\n const cssFiles = findFiles(srcDir, '.css');\n for (const cssFile of cssFiles) {\n const relativePath = path.relative(srcDir, cssFile);\n const destPath = path.join(outputDir, relativePath);\n const destDir = path.dirname(destPath);\n\n if (!fs.existsSync(destDir)) {\n fs.mkdirSync(destDir, { recursive: true });\n }\n\n fs.copyFileSync(cssFile, destPath);\n console.log(` Copied: ${relativePath}`);\n }\n }\n\n // Copy assets\n const assetsDir = path.join(cwd, 'assets');\n if (fs.existsSync(assetsDir)) {\n const destAssetsDir = path.join(outputDir, 'assets');\n copyDirectory(assetsDir, destAssetsDir);\n console.log(' Copied: assets/');\n }\n\n // Compile TypeScript if tsconfig exists\n if (fs.existsSync(tsconfigPath)) {\n console.log(' Compiling TypeScript...');\n try {\n execSync(`npx tsc --outDir \"${outputDir}\"`, { cwd, stdio: 'pipe' });\n console.log(' TypeScript compiled successfully');\n } catch (error: unknown) {\n const err = error as { stderr?: Buffer };\n if (err.stderr) {\n console.error('TypeScript compilation failed:');\n console.error(err.stderr.toString());\n }\n process.exit(1);\n }\n } else {\n // Just copy JS files if no TypeScript\n const jsFiles = findFiles(srcDir, '.js');\n for (const jsFile of jsFiles) {\n const relativePath = path.relative(srcDir, jsFile);\n const destPath = path.join(outputDir, relativePath);\n const destDir = path.dirname(destPath);\n\n if (!fs.existsSync(destDir)) {\n fs.mkdirSync(destDir, { recursive: true });\n }\n\n fs.copyFileSync(jsFile, destPath);\n console.log(` Copied: ${relativePath}`);\n }\n }\n\n console.log();\n console.log('Build complete!');\n\n if (options.watch) {\n console.log();\n console.log('Watching for changes... (press Ctrl+C to stop)');\n watchDirectory(cwd, async () => {\n console.log();\n console.log('Changes detected, rebuilding...');\n await buildCommand({ ...options, watch: false });\n });\n }\n}\n\nfunction findFiles(dir: string, extension: string): string[] {\n const files: string[] = [];\n\n if (!fs.existsSync(dir)) {\n return files;\n }\n\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n\n if (entry.isDirectory()) {\n files.push(...findFiles(fullPath, extension));\n } else if (entry.name.endsWith(extension)) {\n files.push(fullPath);\n }\n }\n\n return files;\n}\n\nfunction copyDirectory(src: string, dest: string): void {\n if (!fs.existsSync(dest)) {\n fs.mkdirSync(dest, { recursive: true });\n }\n\n const entries = fs.readdirSync(src, { withFileTypes: true });\n\n for (const entry of entries) {\n const srcPath = path.join(src, entry.name);\n const destPath = path.join(dest, entry.name);\n\n if (entry.isDirectory()) {\n copyDirectory(srcPath, destPath);\n } else {\n fs.copyFileSync(srcPath, destPath);\n }\n }\n}\n\nfunction watchDirectory(dir: string, callback: () => void): void {\n const watchDirs = ['src', 'assets'];\n let debounceTimer: NodeJS.Timeout | null = null;\n\n const debouncedCallback = () => {\n if (debounceTimer) {\n clearTimeout(debounceTimer);\n }\n debounceTimer = setTimeout(callback, 100);\n };\n\n for (const watchDir of watchDirs) {\n const fullPath = path.join(dir, watchDir);\n if (fs.existsSync(fullPath)) {\n fs.watch(fullPath, { recursive: true }, debouncedCallback);\n }\n }\n\n // Also watch manifest.json\n const manifestPath = path.join(dir, 'manifest.json');\n if (fs.existsSync(manifestPath)) {\n fs.watch(manifestPath, debouncedCallback);\n }\n}\n","#!/usr/bin/env node\n\nimport { Command } from 'commander';\nimport { initCommand } from './commands/init';\nimport { buildCommand } from './commands/build';\nimport { validateCommand } from './commands/validate';\nimport { packageCommand } from './commands/package';\n\n// Version injected at build time from package.json\nconst VERSION = process.env.PKG_VERSION || '0.1.0';\n\nconst program = new Command();\n\nprogram\n .name('micropress-theme')\n .description('CLI for building MicroPress themes')\n .version(VERSION);\n\nprogram\n .command('init <name>')\n .description('Initialize a new theme project')\n .option('-d, --directory <dir>', 'Directory to create theme in', '.')\n .option('--no-git', 'Skip git initialization')\n .action(initCommand);\n\nprogram\n .command('build')\n .description('Build the theme for distribution')\n .option('-w, --watch', 'Watch for changes')\n .option('-o, --output <dir>', 'Output directory', 'dist')\n .action(buildCommand);\n\nprogram\n .command('validate')\n .description('Validate theme structure and manifest')\n .option('--fix', 'Attempt to fix simple issues')\n .action(validateCommand);\n\nprogram\n .command('package')\n .description('Create a distributable ZIP file')\n .option('-o, --output <file>', 'Output file path')\n .action(packageCommand);\n\nprogram.parse();\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport { execSync } from 'child_process';\n\ninterface InitOptions {\n directory: string;\n git: boolean;\n}\n\nconst MANIFEST_TEMPLATE = `{\n \"id\": \"{{name}}\",\n \"name\": \"{{displayName}}\",\n \"version\": \"1.0.0\",\n \"description\": \"A custom MicroPress theme\",\n \"author\": \"Your Name\",\n \"homepage\": \"\",\n \"breakpoints\": {\n \"sm\": \"640px\",\n \"md\": \"768px\",\n \"lg\": \"1024px\",\n \"xl\": \"1280px\"\n },\n \"customizable\": {\n \"primaryColor\": {\n \"type\": \"color\",\n \"label\": \"Primary Color\",\n \"default\": \"#3b82f6\"\n },\n \"fontFamily\": {\n \"type\": \"select\",\n \"label\": \"Font Family\",\n \"default\": \"system-ui\",\n \"options\": [\"system-ui\", \"Georgia\", \"Helvetica\"]\n }\n }\n}`;\n\nconst THEME_CSS_TEMPLATE = `/* {{displayName}} - Main Styles */\n\n:root {\n --primary: var(--theme-primaryColor, #3b82f6);\n --font-family: var(--theme-fontFamily, system-ui);\n}\n\n/* Base styles */\nbody {\n font-family: var(--font-family), sans-serif;\n line-height: 1.6;\n color: #1f2937;\n}\n\n/* Header */\n.theme-header {\n padding: 1rem 2rem;\n border-bottom: 1px solid #e5e7eb;\n}\n\n.theme-header__brand {\n font-weight: 600;\n font-size: 1.25rem;\n text-decoration: none;\n color: inherit;\n}\n\n/* Navigation */\n.theme-nav {\n padding: 0.5rem 2rem;\n}\n\n.theme-nav__list {\n display: flex;\n gap: 1.5rem;\n list-style: none;\n margin: 0;\n padding: 0;\n}\n\n.theme-nav__link {\n color: #6b7280;\n text-decoration: none;\n transition: color 0.2s;\n}\n\n.theme-nav__link:hover,\n.theme-nav__link.is-active {\n color: var(--primary);\n}\n\n/* Main content */\n.theme-content {\n max-width: 800px;\n margin: 0 auto;\n padding: 2rem;\n}\n\n/* Footer */\n.theme-footer {\n padding: 2rem;\n background: #f9fafb;\n text-align: center;\n color: #6b7280;\n font-size: 0.875rem;\n}\n\n/* Responsive */\n@media (max-width: 768px) {\n .theme-nav__list {\n flex-direction: column;\n gap: 0.5rem;\n }\n}\n`;\n\nconst RENDERERS_TEMPLATE = `import { defineTheme, html, css, raw, when } from '@micropress/theme-sdk';\nimport type { HeaderDTO, NavigationDTO, FooterDTO } from '@micropress/theme-sdk';\n\nexport default defineTheme({\n config: {\n id: '{{name}}',\n name: '{{displayName}}',\n version: '1.0.0',\n },\n\n renderers: {\n // Custom header renderer\n header: {\n render: (data: HeaderDTO) => html\\`\n <header class=\"theme-header\">\n <a href=\"/\" class=\"theme-header__brand\">\n \\${data.logo\n ? html\\`<img src=\"\\${data.logo.src}\" alt=\"\\${data.logo.alt}\" />\\`\n : html\\`<span>\\${data.siteName}</span>\\`\n }\n </a>\n \\${when(data.showMenuToggle, html\\`\n <button class=\"theme-header__toggle\" aria-label=\"Toggle menu\">\n <span></span>\n </button>\n \\`)}\n </header>\n \\`.html,\n },\n\n // Custom navigation renderer\n navigation: {\n render: (data: NavigationDTO) => html\\`\n <nav class=\"theme-nav\">\n <ul class=\"theme-nav__list\">\n \\${raw(data.items.map(item => html\\`\n <li class=\"theme-nav__item\">\n <a\n href=\"\\${item.href}\"\n class=\"theme-nav__link \\${item.active ? 'is-active' : ''}\"\n >\n \\${item.label}\n </a>\n </li>\n \\`.html).join(''))}\n </ul>\n </nav>\n \\`.html,\n },\n\n // Custom footer renderer\n footer: {\n render: (data: FooterDTO) => html\\`\n <footer class=\"theme-footer\">\n <p>&copy; \\${data.year} \\${data.copyright}</p>\n \\${when(data.links.length > 0, html\\`\n <nav>\n \\${raw(data.links.map(link => html\\`\n <a href=\"\\${link.href}\">\\${link.label}</a>\n \\`.html).join(' · '))}\n </nav>\n \\`)}\n </footer>\n \\`.html,\n },\n },\n});\n`;\n\nconst PACKAGE_JSON_TEMPLATE = `{\n \"name\": \"{{name}}\",\n \"version\": \"1.0.0\",\n \"description\": \"A custom MicroPress theme\",\n \"main\": \"dist/renderers.js\",\n \"types\": \"dist/renderers.d.ts\",\n \"scripts\": {\n \"build\": \"micropress-theme build\",\n \"validate\": \"micropress-theme validate\",\n \"package\": \"micropress-theme package\"\n },\n \"devDependencies\": {\n \"@micropress/theme-sdk\": \"^1.0.0\",\n \"typescript\": \"^5.0.0\"\n },\n \"keywords\": [\"micropress\", \"theme\"],\n \"license\": \"MIT\"\n}`;\n\nconst TSCONFIG_TEMPLATE = `{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"declaration\": true,\n \"declarationMap\": true,\n \"outDir\": \"dist\",\n \"rootDir\": \"src\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true,\n \"forceConsistentCasingInFileNames\": true\n },\n \"include\": [\"src/**/*\"],\n \"exclude\": [\"node_modules\", \"dist\"]\n}`;\n\nconst GITIGNORE_TEMPLATE = `node_modules/\ndist/\n*.zip\n.DS_Store\n`;\n\nfunction toDisplayName(name: string): string {\n return name\n .split(/[-_]/)\n .map(word => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n}\n\nfunction replaceTemplateVars(template: string, vars: Record<string, string>): string {\n return template.replace(/\\{\\{(\\w+)\\}\\}/g, (_, key) => vars[key] || '');\n}\n\nexport async function initCommand(name: string, options: InitOptions): Promise<void> {\n const targetDir = path.resolve(options.directory === '.' ? name : path.join(options.directory, name));\n\n console.log(`Creating theme: ${name}`);\n console.log(`Location: ${targetDir}`);\n console.log();\n\n // Check if directory exists\n if (fs.existsSync(targetDir)) {\n console.error(`Error: Directory already exists: ${targetDir}`);\n process.exit(1);\n }\n\n // Create directories\n fs.mkdirSync(targetDir, { recursive: true });\n fs.mkdirSync(path.join(targetDir, 'src'));\n fs.mkdirSync(path.join(targetDir, 'assets'));\n\n const vars = {\n name,\n displayName: toDisplayName(name),\n };\n\n // Write files\n const files = [\n { path: 'manifest.json', content: replaceTemplateVars(MANIFEST_TEMPLATE, vars) },\n { path: 'src/theme.css', content: replaceTemplateVars(THEME_CSS_TEMPLATE, vars) },\n { path: 'src/renderers.ts', content: replaceTemplateVars(RENDERERS_TEMPLATE, vars) },\n { path: 'package.json', content: replaceTemplateVars(PACKAGE_JSON_TEMPLATE, vars) },\n { path: 'tsconfig.json', content: TSCONFIG_TEMPLATE },\n { path: '.gitignore', content: GITIGNORE_TEMPLATE },\n ];\n\n for (const file of files) {\n const filePath = path.join(targetDir, file.path);\n const dir = path.dirname(filePath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n fs.writeFileSync(filePath, file.content);\n console.log(` Created: ${file.path}`);\n }\n\n // Initialize git\n if (options.git) {\n try {\n execSync('git init', { cwd: targetDir, stdio: 'ignore' });\n console.log(' Initialized git repository');\n } catch {\n console.log(' Warning: Could not initialize git repository');\n }\n }\n\n console.log();\n console.log('Theme created successfully!');\n console.log();\n console.log('Next steps:');\n console.log(` cd ${name}`);\n console.log(' npm install');\n console.log(' npm run build');\n console.log();\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\n\ninterface ValidateOptions {\n fix: boolean;\n}\n\ninterface ValidationResult {\n valid: boolean;\n errors: string[];\n warnings: string[];\n}\n\ninterface Manifest {\n id?: string;\n name?: string;\n version?: string;\n description?: string;\n author?: string;\n homepage?: string;\n breakpoints?: Record<string, string>;\n customizable?: Record<string, {\n type?: string;\n label?: string;\n default?: string;\n options?: string[];\n }>;\n}\n\nexport async function validateCommand(options: ValidateOptions): Promise<void> {\n const cwd = process.cwd();\n console.log('Validating theme...');\n console.log();\n\n const result: ValidationResult = {\n valid: true,\n errors: [],\n warnings: [],\n };\n\n // Check manifest.json\n const manifestPath = path.join(cwd, 'manifest.json');\n if (!fs.existsSync(manifestPath)) {\n result.errors.push('manifest.json not found');\n result.valid = false;\n } else {\n const manifestResult = validateManifest(manifestPath, options.fix);\n result.errors.push(...manifestResult.errors);\n result.warnings.push(...manifestResult.warnings);\n if (!manifestResult.valid) {\n result.valid = false;\n }\n }\n\n // Check required directories\n const srcDir = path.join(cwd, 'src');\n if (!fs.existsSync(srcDir)) {\n result.errors.push('src/ directory not found');\n result.valid = false;\n }\n\n // Check for CSS files\n const cssFiles = findFiles(srcDir, '.css');\n if (cssFiles.length === 0) {\n result.warnings.push('No CSS files found in src/');\n }\n\n // Check for renderers\n const renderersTs = path.join(srcDir, 'renderers.ts');\n const renderersJs = path.join(srcDir, 'renderers.js');\n if (!fs.existsSync(renderersTs) && !fs.existsSync(renderersJs)) {\n result.warnings.push('No renderers.ts or renderers.js found in src/');\n }\n\n // Check package.json\n const packagePath = path.join(cwd, 'package.json');\n if (!fs.existsSync(packagePath)) {\n result.warnings.push('package.json not found');\n } else {\n const packageResult = validatePackageJson(packagePath);\n result.warnings.push(...packageResult.warnings);\n }\n\n // Print results\n if (result.errors.length > 0) {\n console.log('Errors:');\n for (const error of result.errors) {\n console.log(` \\x1b[31m✗\\x1b[0m ${error}`);\n }\n console.log();\n }\n\n if (result.warnings.length > 0) {\n console.log('Warnings:');\n for (const warning of result.warnings) {\n console.log(` \\x1b[33m!\\x1b[0m ${warning}`);\n }\n console.log();\n }\n\n if (result.valid && result.errors.length === 0) {\n console.log('\\x1b[32m✓\\x1b[0m Theme is valid!');\n if (result.warnings.length > 0) {\n console.log(` (${result.warnings.length} warning${result.warnings.length === 1 ? '' : 's'})`);\n }\n } else {\n console.log('\\x1b[31m✗\\x1b[0m Theme validation failed');\n process.exit(1);\n }\n}\n\nfunction validateManifest(manifestPath: string, fix: boolean): ValidationResult {\n const result: ValidationResult = {\n valid: true,\n errors: [],\n warnings: [],\n };\n\n let manifest: Manifest;\n try {\n const content = fs.readFileSync(manifestPath, 'utf-8');\n manifest = JSON.parse(content);\n } catch (error) {\n result.errors.push(`Invalid JSON in manifest.json: ${(error as Error).message}`);\n result.valid = false;\n return result;\n }\n\n // Required fields\n const requiredFields = ['id', 'name', 'version', 'description', 'author'] as const;\n for (const field of requiredFields) {\n if (!manifest[field]) {\n result.errors.push(`Missing required field in manifest.json: ${field}`);\n result.valid = false;\n }\n }\n\n // Validate ID format\n if (manifest.id && !/^[a-z][a-z0-9-]*$/.test(manifest.id)) {\n result.errors.push('Invalid theme ID: must start with a letter and contain only lowercase letters, numbers, and hyphens');\n result.valid = false;\n }\n\n // Validate version format\n if (manifest.version && !/^\\d+\\.\\d+\\.\\d+(-[a-z0-9.]+)?$/.test(manifest.version)) {\n result.warnings.push('Version should follow semver format (e.g., 1.0.0)');\n }\n\n // Validate customizable fields\n if (manifest.customizable) {\n for (const [key, field] of Object.entries(manifest.customizable)) {\n if (!field.type) {\n result.errors.push(`Missing type for customizable field: ${key}`);\n result.valid = false;\n } else if (!['color', 'font', 'size', 'select'].includes(field.type)) {\n result.errors.push(`Invalid type for customizable field ${key}: ${field.type}`);\n result.valid = false;\n }\n\n if (!field.label) {\n result.warnings.push(`Missing label for customizable field: ${key}`);\n }\n\n if (field.default === undefined) {\n result.warnings.push(`Missing default value for customizable field: ${key}`);\n }\n\n if (field.type === 'select' && (!field.options || field.options.length === 0)) {\n result.errors.push(`Select field ${key} must have options array`);\n result.valid = false;\n }\n }\n }\n\n return result;\n}\n\nfunction validatePackageJson(packagePath: string): ValidationResult {\n const result: ValidationResult = {\n valid: true,\n errors: [],\n warnings: [],\n };\n\n try {\n const content = fs.readFileSync(packagePath, 'utf-8');\n const pkg = JSON.parse(content);\n\n // Check for SDK dependency\n const deps = { ...pkg.dependencies, ...pkg.devDependencies };\n if (!deps['@micropress/theme-sdk']) {\n result.warnings.push('@micropress/theme-sdk not found in dependencies');\n }\n } catch (error) {\n result.warnings.push(`Could not parse package.json: ${(error as Error).message}`);\n }\n\n return result;\n}\n\nfunction findFiles(dir: string, extension: string): string[] {\n const files: string[] = [];\n\n if (!fs.existsSync(dir)) {\n return files;\n }\n\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n\n if (entry.isDirectory()) {\n files.push(...findFiles(fullPath, extension));\n } else if (entry.name.endsWith(extension)) {\n files.push(fullPath);\n }\n }\n\n return files;\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport { execSync } from 'child_process';\n\ninterface PackageOptions {\n output?: string;\n}\n\nexport async function packageCommand(options: PackageOptions): Promise<void> {\n const cwd = process.cwd();\n console.log('Packaging theme...');\n console.log();\n\n // Check for manifest.json\n const manifestPath = path.join(cwd, 'manifest.json');\n if (!fs.existsSync(manifestPath)) {\n console.error('Error: manifest.json not found');\n console.error('Run this command from your theme directory');\n process.exit(1);\n }\n\n // Read manifest for name and version\n let manifest: { id: string; version: string };\n try {\n const content = fs.readFileSync(manifestPath, 'utf-8');\n manifest = JSON.parse(content);\n } catch (error) {\n console.error('Error: Invalid manifest.json');\n process.exit(1);\n }\n\n if (!manifest.id || !manifest.version) {\n console.error('Error: manifest.json must have id and version fields');\n process.exit(1);\n }\n\n // Check for dist directory\n const distDir = path.join(cwd, 'dist');\n if (!fs.existsSync(distDir)) {\n console.log('Build directory not found. Running build first...');\n console.log();\n\n try {\n // Import and run build command\n const { buildCommand } = await import('./build');\n await buildCommand({ watch: false, output: 'dist' });\n console.log();\n } catch (error) {\n console.error('Build failed');\n process.exit(1);\n }\n }\n\n // Verify dist has required files\n const requiredFiles = ['manifest.json'];\n for (const file of requiredFiles) {\n if (!fs.existsSync(path.join(distDir, file))) {\n console.error(`Error: ${file} not found in dist/`);\n console.error('Please run build first');\n process.exit(1);\n }\n }\n\n // Determine output filename\n const outputFile = options.output || `${manifest.id}-${manifest.version}.zip`;\n const outputPath = path.resolve(cwd, outputFile);\n\n console.log(`Creating: ${outputFile}`);\n\n // Create ZIP using native zip command or archiver\n try {\n // Try using native zip command first (available on most systems)\n const files = getAllFiles(distDir);\n const fileList = files\n .map(f => path.relative(distDir, f))\n .join(' ');\n\n execSync(`zip -r \"${outputPath}\" ${fileList}`, {\n cwd: distDir,\n stdio: 'pipe',\n });\n } catch {\n // Fallback: create a simple tar.gz or manual process\n console.log('Native zip not available, creating package manually...');\n createZipManually(distDir, outputPath);\n }\n\n // Get file size\n const stats = fs.statSync(outputPath);\n const sizeKB = (stats.size / 1024).toFixed(1);\n\n console.log();\n console.log(`\\x1b[32m✓\\x1b[0m Package created: ${outputFile} (${sizeKB} KB)`);\n console.log();\n console.log('Upload this file to MicroPress to install your theme.');\n}\n\nfunction getAllFiles(dir: string): string[] {\n const files: string[] = [];\n\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n\n if (entry.isDirectory()) {\n files.push(...getAllFiles(fullPath));\n } else {\n files.push(fullPath);\n }\n }\n\n return files;\n}\n\nfunction createZipManually(sourceDir: string, outputPath: string): void {\n // Simple fallback: create a minimal zip-like archive\n // In practice, you'd want to use a library like archiver\n // For now, we'll just create a tarball if zip isn't available\n\n try {\n execSync(`tar -czf \"${outputPath.replace('.zip', '.tar.gz')}\" -C \"${sourceDir}\" .`, {\n stdio: 'pipe',\n });\n console.log('Note: Created tar.gz instead of zip (zip command not available)');\n\n // Rename to .zip for compatibility\n fs.renameSync(outputPath.replace('.zip', '.tar.gz'), outputPath);\n } catch (error) {\n // Last resort: create a directory listing file\n const files = getAllFiles(sourceDir);\n const listing = files.map(f => path.relative(sourceDir, f)).join('\\n');\n fs.writeFileSync(outputPath.replace('.zip', '.txt'), listing);\n console.error('Warning: Could not create archive. Created file listing instead.');\n console.error('Please install zip or tar to create proper packages.');\n }\n}\n"],"mappings":"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","names":["fs","path","import_child_process","fs","path","findFiles","fs","path","import_child_process","buildCommand"]}
1
+ {"version":3,"sources":["../../cli/commands/build.ts","../../cli/index.ts","../../cli/commands/init.ts","../../cli/commands/validate.ts","../../cli/commands/package.ts"],"sourcesContent":["import * as fs from 'fs';\nimport * as path from 'path';\nimport { execSync } from 'child_process';\n\ninterface BuildOptions {\n watch: boolean;\n output: string;\n}\n\nexport async function buildCommand(options: BuildOptions): Promise<void> {\n const cwd = process.cwd();\n const outputDir = path.resolve(cwd, options.output);\n\n console.log('Building theme...');\n console.log(`Output: ${outputDir}`);\n console.log();\n\n // Check for required files\n const manifestPath = path.join(cwd, 'manifest.json');\n const tsconfigPath = path.join(cwd, 'tsconfig.json');\n\n if (!fs.existsSync(manifestPath)) {\n console.error('Error: manifest.json not found');\n console.error('Run this command from your theme directory');\n process.exit(1);\n }\n\n // Create output directory\n if (!fs.existsSync(outputDir)) {\n fs.mkdirSync(outputDir, { recursive: true });\n }\n\n // Copy manifest.json\n fs.copyFileSync(manifestPath, path.join(outputDir, 'manifest.json'));\n console.log(' Copied: manifest.json');\n\n // Copy CSS files\n const srcDir = path.join(cwd, 'src');\n if (fs.existsSync(srcDir)) {\n const cssFiles = findFiles(srcDir, '.css');\n for (const cssFile of cssFiles) {\n const relativePath = path.relative(srcDir, cssFile);\n const destPath = path.join(outputDir, relativePath);\n const destDir = path.dirname(destPath);\n\n if (!fs.existsSync(destDir)) {\n fs.mkdirSync(destDir, { recursive: true });\n }\n\n fs.copyFileSync(cssFile, destPath);\n console.log(` Copied: ${relativePath}`);\n }\n }\n\n // Copy assets\n const assetsDir = path.join(cwd, 'assets');\n if (fs.existsSync(assetsDir)) {\n const destAssetsDir = path.join(outputDir, 'assets');\n copyDirectory(assetsDir, destAssetsDir);\n console.log(' Copied: assets/');\n }\n\n // Compile TypeScript if tsconfig exists\n if (fs.existsSync(tsconfigPath)) {\n console.log(' Compiling TypeScript...');\n try {\n execSync(`npx tsc --outDir \"${outputDir}\"`, { cwd, stdio: 'pipe' });\n console.log(' TypeScript compiled successfully');\n } catch (error: unknown) {\n const err = error as { stderr?: Buffer };\n if (err.stderr) {\n console.error('TypeScript compilation failed:');\n console.error(err.stderr.toString());\n }\n process.exit(1);\n }\n } else {\n // Just copy JS files if no TypeScript\n const jsFiles = findFiles(srcDir, '.js');\n for (const jsFile of jsFiles) {\n const relativePath = path.relative(srcDir, jsFile);\n const destPath = path.join(outputDir, relativePath);\n const destDir = path.dirname(destPath);\n\n if (!fs.existsSync(destDir)) {\n fs.mkdirSync(destDir, { recursive: true });\n }\n\n fs.copyFileSync(jsFile, destPath);\n console.log(` Copied: ${relativePath}`);\n }\n }\n\n console.log();\n console.log('Build complete!');\n\n if (options.watch) {\n console.log();\n console.log('Watching for changes... (press Ctrl+C to stop)');\n watchDirectory(cwd, async () => {\n console.log();\n console.log('Changes detected, rebuilding...');\n await buildCommand({ ...options, watch: false });\n });\n }\n}\n\nfunction findFiles(dir: string, extension: string): string[] {\n const files: string[] = [];\n\n if (!fs.existsSync(dir)) {\n return files;\n }\n\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n\n if (entry.isDirectory()) {\n files.push(...findFiles(fullPath, extension));\n } else if (entry.name.endsWith(extension)) {\n files.push(fullPath);\n }\n }\n\n return files;\n}\n\nfunction copyDirectory(src: string, dest: string): void {\n if (!fs.existsSync(dest)) {\n fs.mkdirSync(dest, { recursive: true });\n }\n\n const entries = fs.readdirSync(src, { withFileTypes: true });\n\n for (const entry of entries) {\n const srcPath = path.join(src, entry.name);\n const destPath = path.join(dest, entry.name);\n\n if (entry.isDirectory()) {\n copyDirectory(srcPath, destPath);\n } else {\n fs.copyFileSync(srcPath, destPath);\n }\n }\n}\n\nfunction watchDirectory(dir: string, callback: () => void): void {\n const watchDirs = ['src', 'assets'];\n let debounceTimer: NodeJS.Timeout | null = null;\n\n const debouncedCallback = () => {\n if (debounceTimer) {\n clearTimeout(debounceTimer);\n }\n debounceTimer = setTimeout(callback, 100);\n };\n\n for (const watchDir of watchDirs) {\n const fullPath = path.join(dir, watchDir);\n if (fs.existsSync(fullPath)) {\n fs.watch(fullPath, { recursive: true }, debouncedCallback);\n }\n }\n\n // Also watch manifest.json\n const manifestPath = path.join(dir, 'manifest.json');\n if (fs.existsSync(manifestPath)) {\n fs.watch(manifestPath, debouncedCallback);\n }\n}\n","#!/usr/bin/env node\n\nimport { Command } from 'commander';\nimport { initCommand } from './commands/init';\nimport { buildCommand } from './commands/build';\nimport { validateCommand } from './commands/validate';\nimport { packageCommand } from './commands/package';\n\n// Version injected at build time from package.json\nconst VERSION = process.env.PKG_VERSION || '0.1.0';\n\nconst program = new Command();\n\nprogram\n .name('micropress-theme')\n .description('CLI for building MicroPress themes')\n .version(VERSION);\n\nprogram\n .command('init <name>')\n .description('Initialize a new theme project')\n .option('-d, --directory <dir>', 'Directory to create theme in', '.')\n .option('--no-git', 'Skip git initialization')\n .action(initCommand);\n\nprogram\n .command('build')\n .description('Build the theme for distribution')\n .option('-w, --watch', 'Watch for changes')\n .option('-o, --output <dir>', 'Output directory', 'dist')\n .action(buildCommand);\n\nprogram\n .command('validate')\n .description('Validate theme structure and manifest')\n .option('--fix', 'Attempt to fix simple issues')\n .action(validateCommand);\n\nprogram\n .command('package')\n .description('Create a distributable ZIP file')\n .option('-o, --output <file>', 'Output file path')\n .action(packageCommand);\n\nprogram.parse();\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport { execSync } from 'child_process';\n\ninterface InitOptions {\n directory: string;\n git: boolean;\n}\n\n// Version injected at build time from package.json\nconst SDK_VERSION = process.env.PKG_VERSION || '0.1.0';\n\nconst MANIFEST_TEMPLATE = `{\n \"id\": \"{{name}}\",\n \"name\": \"{{displayName}}\",\n \"version\": \"1.0.0\",\n \"description\": \"A custom MicroPress theme\",\n \"author\": \"Your Name\",\n \"homepage\": \"\",\n \"breakpoints\": {\n \"sm\": \"640px\",\n \"md\": \"768px\",\n \"lg\": \"1024px\",\n \"xl\": \"1280px\"\n },\n \"customizable\": {\n \"primaryColor\": {\n \"type\": \"color\",\n \"label\": \"Primary Color\",\n \"default\": \"#3b82f6\"\n },\n \"fontFamily\": {\n \"type\": \"select\",\n \"label\": \"Font Family\",\n \"default\": \"system-ui\",\n \"options\": [\"system-ui\", \"Georgia\", \"Helvetica\"]\n }\n }\n}`;\n\nconst THEME_CSS_TEMPLATE = `/* {{displayName}} - Main Styles */\n\n:root {\n --primary: var(--theme-primaryColor, #3b82f6);\n --font-family: var(--theme-fontFamily, system-ui);\n}\n\n/* Base styles */\nbody {\n font-family: var(--font-family), sans-serif;\n line-height: 1.6;\n color: #1f2937;\n}\n\n/* Header */\n.theme-header {\n padding: 1rem 2rem;\n border-bottom: 1px solid #e5e7eb;\n}\n\n.theme-header__brand {\n font-weight: 600;\n font-size: 1.25rem;\n text-decoration: none;\n color: inherit;\n}\n\n/* Navigation */\n.theme-nav {\n padding: 0.5rem 2rem;\n}\n\n.theme-nav__list {\n display: flex;\n gap: 1.5rem;\n list-style: none;\n margin: 0;\n padding: 0;\n}\n\n.theme-nav__link {\n color: #6b7280;\n text-decoration: none;\n transition: color 0.2s;\n}\n\n.theme-nav__link:hover,\n.theme-nav__link.is-active {\n color: var(--primary);\n}\n\n/* Main content */\n.theme-content {\n max-width: 800px;\n margin: 0 auto;\n padding: 2rem;\n}\n\n/* Footer */\n.theme-footer {\n padding: 2rem;\n background: #f9fafb;\n text-align: center;\n color: #6b7280;\n font-size: 0.875rem;\n}\n\n/* Responsive */\n@media (max-width: 768px) {\n .theme-nav__list {\n flex-direction: column;\n gap: 0.5rem;\n }\n}\n`;\n\nconst RENDERERS_TEMPLATE = `import { defineTheme, html, css, raw, when } from '@micropress/theme-sdk';\nimport type { HeaderDTO, NavigationDTO, FooterDTO } from '@micropress/theme-sdk';\n\nexport default defineTheme({\n config: {\n id: '{{name}}',\n name: '{{displayName}}',\n version: '1.0.0',\n },\n\n renderers: {\n // Custom header renderer\n header: {\n render: (data: HeaderDTO) => html\\`\n <header class=\"theme-header\">\n <a href=\"/\" class=\"theme-header__brand\">\n \\${data.logo\n ? html\\`<img src=\"\\${data.logo.src}\" alt=\"\\${data.logo.alt}\" />\\`\n : html\\`<span>\\${data.siteName}</span>\\`\n }\n </a>\n \\${when(data.showMenuToggle, html\\`\n <button class=\"theme-header__toggle\" aria-label=\"Toggle menu\">\n <span></span>\n </button>\n \\`)}\n </header>\n \\`.html,\n },\n\n // Custom navigation renderer\n navigation: {\n render: (data: NavigationDTO) => html\\`\n <nav class=\"theme-nav\">\n <ul class=\"theme-nav__list\">\n \\${raw(data.items.map(item => html\\`\n <li class=\"theme-nav__item\">\n <a\n href=\"\\${item.href}\"\n class=\"theme-nav__link \\${item.active ? 'is-active' : ''}\"\n >\n \\${item.label}\n </a>\n </li>\n \\`.html).join(''))}\n </ul>\n </nav>\n \\`.html,\n },\n\n // Custom footer renderer\n footer: {\n render: (data: FooterDTO) => html\\`\n <footer class=\"theme-footer\">\n <p>&copy; \\${data.year} \\${data.copyright}</p>\n \\${when(data.links.length > 0, html\\`\n <nav>\n \\${raw(data.links.map(link => html\\`\n <a href=\"\\${link.href}\">\\${link.label}</a>\n \\`.html).join(' · '))}\n </nav>\n \\`)}\n </footer>\n \\`.html,\n },\n },\n});\n`;\n\nconst PACKAGE_JSON_TEMPLATE = `{\n \"name\": \"{{name}}\",\n \"version\": \"1.0.0\",\n \"description\": \"A custom MicroPress theme\",\n \"main\": \"dist/renderers.js\",\n \"types\": \"dist/renderers.d.ts\",\n \"scripts\": {\n \"build\": \"micropress-theme build\",\n \"validate\": \"micropress-theme validate\",\n \"package\": \"micropress-theme package\"\n },\n \"devDependencies\": {\n \"@micropress/theme-sdk\": \"^{{sdkVersion}}\",\n \"typescript\": \"^5.0.0\"\n },\n \"keywords\": [\"micropress\", \"theme\"],\n \"license\": \"MIT\"\n}`;\n\nconst TSCONFIG_TEMPLATE = `{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"declaration\": true,\n \"declarationMap\": true,\n \"outDir\": \"dist\",\n \"rootDir\": \"src\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true,\n \"forceConsistentCasingInFileNames\": true\n },\n \"include\": [\"src/**/*\"],\n \"exclude\": [\"node_modules\", \"dist\"]\n}`;\n\nconst GITIGNORE_TEMPLATE = `node_modules/\ndist/\n*.zip\n.DS_Store\n`;\n\nconst GITHUB_RELEASE_WORKFLOW_TEMPLATE = `name: Release Theme\n\non:\n push:\n tags:\n - 'v*'\n\npermissions:\n contents: write\n\njobs:\n release:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v4\n\n - uses: actions/setup-node@v4\n with:\n node-version: '22'\n\n - name: Install dependencies\n run: npm ci\n\n - name: Validate theme\n run: npm run validate\n\n - name: Build theme\n run: npm run build\n\n - name: Package theme\n run: npm run package\n\n - name: Create GitHub Release\n uses: softprops/action-gh-release@v2\n with:\n files: \"*.zip\"\n generate_release_notes: true\n`\n\nconst GITHUB_WORKFLOW_TEMPLATE = `name: Build Theme\n\non:\n push:\n branches: [main]\n pull_request:\n branches: [main]\n\njobs:\n build:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v4\n\n - uses: actions/setup-node@v4\n with:\n node-version: '22'\n\n - name: Install dependencies\n run: npm ci\n\n - name: Validate theme\n run: npm run validate\n\n - name: Build theme\n run: npm run build\n\n - name: Package theme\n run: npm run package\n\n - name: Upload theme artifact\n uses: actions/upload-artifact@v4\n with:\n name: theme-package\n path: \"*.zip\"\n`;\n\nfunction toDisplayName(name: string): string {\n return name\n .split(/[-_]/)\n .map(word => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n}\n\nfunction replaceTemplateVars(template: string, vars: Record<string, string>): string {\n return template.replace(/\\{\\{(\\w+)\\}\\}/g, (_, key) => vars[key] || '');\n}\n\nexport async function initCommand(name: string, options: InitOptions): Promise<void> {\n const targetDir = path.resolve(options.directory === '.' ? name : path.join(options.directory, name));\n\n console.log(`Creating theme: ${name}`);\n console.log(`Location: ${targetDir}`);\n console.log();\n\n // Check if directory exists\n if (fs.existsSync(targetDir)) {\n console.error(`Error: Directory already exists: ${targetDir}`);\n process.exit(1);\n }\n\n // Create directories\n fs.mkdirSync(targetDir, { recursive: true });\n fs.mkdirSync(path.join(targetDir, 'src'));\n fs.mkdirSync(path.join(targetDir, 'assets'));\n\n const vars = {\n name,\n displayName: toDisplayName(name),\n sdkVersion: SDK_VERSION,\n };\n\n // Write files\n const files = [\n { path: 'manifest.json', content: replaceTemplateVars(MANIFEST_TEMPLATE, vars) },\n { path: 'src/theme.css', content: replaceTemplateVars(THEME_CSS_TEMPLATE, vars) },\n { path: 'src/renderers.ts', content: replaceTemplateVars(RENDERERS_TEMPLATE, vars) },\n { path: 'package.json', content: replaceTemplateVars(PACKAGE_JSON_TEMPLATE, vars) },\n { path: 'tsconfig.json', content: TSCONFIG_TEMPLATE },\n { path: '.gitignore', content: GITIGNORE_TEMPLATE },\n { path: '.github/workflows/build.yml', content: GITHUB_WORKFLOW_TEMPLATE },\n { path: '.github/workflows/release.yml', content: GITHUB_RELEASE_WORKFLOW_TEMPLATE },\n ];\n\n for (const file of files) {\n const filePath = path.join(targetDir, file.path);\n const dir = path.dirname(filePath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n fs.writeFileSync(filePath, file.content);\n console.log(` Created: ${file.path}`);\n }\n\n // Initialize git\n if (options.git) {\n try {\n execSync('git init', { cwd: targetDir, stdio: 'ignore' });\n console.log(' Initialized git repository');\n } catch {\n console.log(' Warning: Could not initialize git repository');\n }\n }\n\n console.log();\n console.log('Theme created successfully!');\n console.log();\n console.log('Next steps:');\n console.log(` cd ${name}`);\n console.log(' npm install');\n console.log(' npm run build');\n console.log();\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\n\ninterface ValidateOptions {\n fix: boolean;\n}\n\ninterface ValidationResult {\n valid: boolean;\n errors: string[];\n warnings: string[];\n}\n\ninterface Manifest {\n id?: string;\n name?: string;\n version?: string;\n description?: string;\n author?: string;\n homepage?: string;\n breakpoints?: Record<string, string>;\n customizable?: Record<string, {\n type?: string;\n label?: string;\n default?: string;\n options?: string[];\n }>;\n}\n\nexport async function validateCommand(options: ValidateOptions): Promise<void> {\n const cwd = process.cwd();\n console.log('Validating theme...');\n console.log();\n\n const result: ValidationResult = {\n valid: true,\n errors: [],\n warnings: [],\n };\n\n // Check manifest.json\n const manifestPath = path.join(cwd, 'manifest.json');\n if (!fs.existsSync(manifestPath)) {\n result.errors.push('manifest.json not found');\n result.valid = false;\n } else {\n const manifestResult = validateManifest(manifestPath, options.fix);\n result.errors.push(...manifestResult.errors);\n result.warnings.push(...manifestResult.warnings);\n if (!manifestResult.valid) {\n result.valid = false;\n }\n }\n\n // Check required directories\n const srcDir = path.join(cwd, 'src');\n if (!fs.existsSync(srcDir)) {\n result.errors.push('src/ directory not found');\n result.valid = false;\n }\n\n // Check for CSS files\n const cssFiles = findFiles(srcDir, '.css');\n if (cssFiles.length === 0) {\n result.warnings.push('No CSS files found in src/');\n }\n\n // Check for renderers\n const renderersTs = path.join(srcDir, 'renderers.ts');\n const renderersJs = path.join(srcDir, 'renderers.js');\n if (!fs.existsSync(renderersTs) && !fs.existsSync(renderersJs)) {\n result.warnings.push('No renderers.ts or renderers.js found in src/');\n }\n\n // Check package.json\n const packagePath = path.join(cwd, 'package.json');\n if (!fs.existsSync(packagePath)) {\n result.warnings.push('package.json not found');\n } else {\n const packageResult = validatePackageJson(packagePath);\n result.warnings.push(...packageResult.warnings);\n }\n\n // Print results\n if (result.errors.length > 0) {\n console.log('Errors:');\n for (const error of result.errors) {\n console.log(` \\x1b[31m✗\\x1b[0m ${error}`);\n }\n console.log();\n }\n\n if (result.warnings.length > 0) {\n console.log('Warnings:');\n for (const warning of result.warnings) {\n console.log(` \\x1b[33m!\\x1b[0m ${warning}`);\n }\n console.log();\n }\n\n if (result.valid && result.errors.length === 0) {\n console.log('\\x1b[32m✓\\x1b[0m Theme is valid!');\n if (result.warnings.length > 0) {\n console.log(` (${result.warnings.length} warning${result.warnings.length === 1 ? '' : 's'})`);\n }\n } else {\n console.log('\\x1b[31m✗\\x1b[0m Theme validation failed');\n process.exit(1);\n }\n}\n\nfunction validateManifest(manifestPath: string, fix: boolean): ValidationResult {\n const result: ValidationResult = {\n valid: true,\n errors: [],\n warnings: [],\n };\n\n let manifest: Manifest;\n try {\n const content = fs.readFileSync(manifestPath, 'utf-8');\n manifest = JSON.parse(content);\n } catch (error) {\n result.errors.push(`Invalid JSON in manifest.json: ${(error as Error).message}`);\n result.valid = false;\n return result;\n }\n\n // Required fields\n const requiredFields = ['id', 'name', 'version', 'description', 'author'] as const;\n for (const field of requiredFields) {\n if (!manifest[field]) {\n result.errors.push(`Missing required field in manifest.json: ${field}`);\n result.valid = false;\n }\n }\n\n // Validate ID format\n if (manifest.id && !/^[a-z][a-z0-9-]*$/.test(manifest.id)) {\n result.errors.push('Invalid theme ID: must start with a letter and contain only lowercase letters, numbers, and hyphens');\n result.valid = false;\n }\n\n // Validate version format\n if (manifest.version && !/^\\d+\\.\\d+\\.\\d+(-[a-z0-9.]+)?$/.test(manifest.version)) {\n result.warnings.push('Version should follow semver format (e.g., 1.0.0)');\n }\n\n // Validate customizable fields\n if (manifest.customizable) {\n for (const [key, field] of Object.entries(manifest.customizable)) {\n if (!field.type) {\n result.errors.push(`Missing type for customizable field: ${key}`);\n result.valid = false;\n } else if (!['color', 'font', 'size', 'select'].includes(field.type)) {\n result.errors.push(`Invalid type for customizable field ${key}: ${field.type}`);\n result.valid = false;\n }\n\n if (!field.label) {\n result.warnings.push(`Missing label for customizable field: ${key}`);\n }\n\n if (field.default === undefined) {\n result.warnings.push(`Missing default value for customizable field: ${key}`);\n }\n\n if (field.type === 'select' && (!field.options || field.options.length === 0)) {\n result.errors.push(`Select field ${key} must have options array`);\n result.valid = false;\n }\n }\n }\n\n return result;\n}\n\nfunction validatePackageJson(packagePath: string): ValidationResult {\n const result: ValidationResult = {\n valid: true,\n errors: [],\n warnings: [],\n };\n\n try {\n const content = fs.readFileSync(packagePath, 'utf-8');\n const pkg = JSON.parse(content);\n\n // Check for SDK dependency\n const deps = { ...pkg.dependencies, ...pkg.devDependencies };\n if (!deps['@micropress/theme-sdk']) {\n result.warnings.push('@micropress/theme-sdk not found in dependencies');\n }\n } catch (error) {\n result.warnings.push(`Could not parse package.json: ${(error as Error).message}`);\n }\n\n return result;\n}\n\nfunction findFiles(dir: string, extension: string): string[] {\n const files: string[] = [];\n\n if (!fs.existsSync(dir)) {\n return files;\n }\n\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n\n if (entry.isDirectory()) {\n files.push(...findFiles(fullPath, extension));\n } else if (entry.name.endsWith(extension)) {\n files.push(fullPath);\n }\n }\n\n return files;\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport { execSync } from 'child_process';\n\ninterface PackageOptions {\n output?: string;\n}\n\nexport async function packageCommand(options: PackageOptions): Promise<void> {\n const cwd = process.cwd();\n console.log('Packaging theme...');\n console.log();\n\n // Check for manifest.json\n const manifestPath = path.join(cwd, 'manifest.json');\n if (!fs.existsSync(manifestPath)) {\n console.error('Error: manifest.json not found');\n console.error('Run this command from your theme directory');\n process.exit(1);\n }\n\n // Read manifest for name and version\n let manifest: { id: string; version: string };\n try {\n const content = fs.readFileSync(manifestPath, 'utf-8');\n manifest = JSON.parse(content);\n } catch (error) {\n console.error('Error: Invalid manifest.json');\n process.exit(1);\n }\n\n if (!manifest.id || !manifest.version) {\n console.error('Error: manifest.json must have id and version fields');\n process.exit(1);\n }\n\n // Check for dist directory\n const distDir = path.join(cwd, 'dist');\n if (!fs.existsSync(distDir)) {\n console.log('Build directory not found. Running build first...');\n console.log();\n\n try {\n // Import and run build command\n const { buildCommand } = await import('./build');\n await buildCommand({ watch: false, output: 'dist' });\n console.log();\n } catch (error) {\n console.error('Build failed');\n process.exit(1);\n }\n }\n\n // Verify dist has required files\n const requiredFiles = ['manifest.json'];\n for (const file of requiredFiles) {\n if (!fs.existsSync(path.join(distDir, file))) {\n console.error(`Error: ${file} not found in dist/`);\n console.error('Please run build first');\n process.exit(1);\n }\n }\n\n // Determine output filename\n const outputFile = options.output || `${manifest.id}-${manifest.version}.zip`;\n const outputPath = path.resolve(cwd, outputFile);\n\n console.log(`Creating: ${outputFile}`);\n\n // Create ZIP using native zip command or archiver\n try {\n // Try using native zip command first (available on most systems)\n const files = getAllFiles(distDir);\n const fileList = files\n .map(f => path.relative(distDir, f))\n .join(' ');\n\n execSync(`zip -r \"${outputPath}\" ${fileList}`, {\n cwd: distDir,\n stdio: 'pipe',\n });\n } catch {\n // Fallback: create a simple tar.gz or manual process\n console.log('Native zip not available, creating package manually...');\n createZipManually(distDir, outputPath);\n }\n\n // Get file size\n const stats = fs.statSync(outputPath);\n const sizeKB = (stats.size / 1024).toFixed(1);\n\n console.log();\n console.log(`\\x1b[32m✓\\x1b[0m Package created: ${outputFile} (${sizeKB} KB)`);\n console.log();\n console.log('Upload this file to MicroPress to install your theme.');\n}\n\nfunction getAllFiles(dir: string): string[] {\n const files: string[] = [];\n\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n\n if (entry.isDirectory()) {\n files.push(...getAllFiles(fullPath));\n } else {\n files.push(fullPath);\n }\n }\n\n return files;\n}\n\nfunction createZipManually(sourceDir: string, outputPath: string): void {\n // Simple fallback: create a minimal zip-like archive\n // In practice, you'd want to use a library like archiver\n // For now, we'll just create a tarball if zip isn't available\n\n try {\n execSync(`tar -czf \"${outputPath.replace('.zip', '.tar.gz')}\" -C \"${sourceDir}\" .`, {\n stdio: 'pipe',\n });\n console.log('Note: Created tar.gz instead of zip (zip command not available)');\n\n // Rename to .zip for compatibility\n fs.renameSync(outputPath.replace('.zip', '.tar.gz'), outputPath);\n } catch (error) {\n // Last resort: create a directory listing file\n const files = getAllFiles(sourceDir);\n const listing = files.map(f => path.relative(sourceDir, f)).join('\\n');\n fs.writeFileSync(outputPath.replace('.zip', '.txt'), listing);\n console.error('Warning: Could not create archive. Created file listing instead.');\n console.error('Please install zip or tar to create proper packages.');\n }\n}\n"],"mappings":"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","names":["fs","path","import_child_process","fs","path","findFiles","fs","path","import_child_process","buildCommand"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@micropress/theme-sdk",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "SDK for building MicroPress themes",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",