{"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\n\n// create-modern-cmdk — Scaffold a new command palette project\n// Usage: npx create-modern-cmdk [project-name] [--template=<name>]\n\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { join, resolve } from 'node:path';\n\nconst TEMPLATES: Map<string, string> = new Map([\n  ['react-basic', 'Basic inline command palette (React)'],\n  ['react-dialog', 'Dialog command palette with Ctrl+K (React)'],\n  ['react-full', 'Full-featured: dialog + frecency + WASM search (React)'],\n]);\n\nfunction printUsage(): void {\n  // ES2026 Iterator Helper: .forEach on map entries\n  TEMPLATES.entries().forEach(([_name, _desc]) => {});\n}\n\nfunction parseArgs(argv: string[]): { projectName: string; template: string } | null {\n  const args = argv.slice(2);\n\n  // ES2026 Iterator Helpers: separate flags and positional args\n  const flags = args\n    .values()\n    .filter((a) => a.startsWith('--'))\n    .toArray();\n  const positional = args\n    .values()\n    .filter((a) => !a.startsWith('--'))\n    .toArray();\n\n  const projectName = positional[0];\n\n  if (!projectName || projectName === '--help') {\n    return null;\n  }\n\n  // Parse --template=<name> using Iterator Helpers\n  const templateFlag = flags.values().find((f) => f.startsWith('--template='));\n  const template = templateFlag ? (templateFlag.split('=')[1] as string) : 'react-basic';\n\n  return { projectName, template };\n}\n\n/** Write a file and return its path (for reporting). */\nasync function emitFile(filePath: string, content: string): Promise<string> {\n  await writeFile(filePath, content);\n  return filePath;\n}\n\nasync function main(): Promise<void> {\n  const parsed = parseArgs(process.argv);\n\n  if (!parsed) {\n    printUsage();\n    process.exit(0);\n    return; // unreachable, but tells TS that parsed is non-null below\n  }\n\n  const { projectName, template } = parsed;\n\n  if (!TEMPLATES.has(template)) {\n    const _available = TEMPLATES.keys().toArray().join(', ');\n    process.exit(1);\n  }\n\n  const projectDir = resolve(projectName);\n\n  await mkdir(join(projectDir, 'src'), { recursive: true });\n\n  // --- Generate files concurrently using Promise.allSettled ---\n\n  // package.json\n  const pkg = {\n    name: projectName,\n    version: '0.1.0',\n    type: 'module',\n    private: true,\n    scripts: {\n      dev: 'vite',\n      build: 'vite build',\n      preview: 'vite preview',\n    },\n    dependencies: {\n      'modern-cmdk': '^1.1.5',\n      react: '^19.2.0',\n      'react-dom': '^19.2.0',\n    },\n    devDependencies: {\n      '@vitejs/plugin-react': '^6.0.0',\n      typescript: '^6.0.0',\n      vite: '^8.0.0',\n    },\n  };\n\n  // tsconfig.json\n  const tsconfig = {\n    compilerOptions: {\n      target: 'ESNext',\n      module: 'ESNext',\n      moduleResolution: 'bundler',\n      lib: ['ESNext', 'DOM', 'DOM.Iterable'],\n      jsx: 'react-jsx',\n      strict: true,\n      noEmit: true,\n      isolatedDeclarations: true,\n      erasableSyntaxOnly: true,\n      verbatimModuleSyntax: true,\n      skipLibCheck: true,\n    },\n    include: ['src'],\n  };\n\n  // vite.config.ts\n  const viteConfig = `import { defineConfig } from 'vite';\nimport react from '@vitejs/plugin-react';\n\nexport default defineConfig({\n  plugins: [react()],\n});\n`;\n\n  // index.html\n  const indexHtml = `<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>${projectName}</title>\n  </head>\n  <body>\n    <div id=\"root\"></div>\n    <script type=\"module\" src=\"/src/main.tsx\"></script>\n  </body>\n</html>\n`;\n\n  // src/main.tsx\n  const mainTsx = `import { StrictMode } from 'react';\nimport { createRoot } from 'react-dom/client';\nimport { App } from './App.js';\n\ncreateRoot(document.getElementById('root')!).render(\n  <StrictMode>\n    <App />\n  </StrictMode>,\n);\n`;\n\n  // src/App.tsx — varies by template\n  const appContent =\n    template === 'react-dialog'\n      ? `import { Command } from 'modern-cmdk/react';\n\nexport function App() {\n  return (\n    <div style={{ padding: '2rem', fontFamily: 'system-ui' }}>\n      <h1>Command Palette</h1>\n      <p>Press <kbd>Ctrl+K</kbd> to open.</p>\n      <Command.Dialog>\n        <Command.Input placeholder=\"Search commands...\" />\n        <Command.List>\n          <Command.Empty>No results found.</Command.Empty>\n          <Command.Item value=\"home\" onSelect={() => alert('Home!')}>Home</Command.Item>\n          <Command.Item value=\"settings\" onSelect={() => alert('Settings!')}>Settings</Command.Item>\n          <Command.Item value=\"profile\" onSelect={() => alert('Profile!')}>Profile</Command.Item>\n        </Command.List>\n      </Command.Dialog>\n    </div>\n  );\n}\n`\n      : `import { Command } from 'modern-cmdk/react';\n\nexport function App() {\n  return (\n    <div style={{ padding: '2rem', fontFamily: 'system-ui' }}>\n      <h1>Command Palette</h1>\n      <Command label=\"Command menu\">\n        <Command.Input placeholder=\"Search...\" />\n        <Command.List>\n          <Command.Empty>No results found.</Command.Empty>\n          <Command.Group heading=\"Actions\">\n            <Command.Item value=\"copy\" onSelect={() => alert('Copied!')}>Copy</Command.Item>\n            <Command.Item value=\"paste\" onSelect={() => alert('Pasted!')}>Paste</Command.Item>\n          </Command.Group>\n          <Command.Group heading=\"Navigation\">\n            <Command.Item value=\"home\" onSelect={() => alert('Home!')}>Home</Command.Item>\n            <Command.Item value=\"settings\" onSelect={() => alert('Settings!')}>Settings</Command.Item>\n          </Command.Group>\n        </Command.List>\n      </Command>\n    </div>\n  );\n}\n`;\n\n  // Write all files concurrently\n  const results = await Promise.allSettled([\n    emitFile(join(projectDir, 'package.json'), `${JSON.stringify(pkg, null, 2)}\\n`),\n    emitFile(join(projectDir, 'tsconfig.json'), `${JSON.stringify(tsconfig, null, 2)}\\n`),\n    emitFile(join(projectDir, 'vite.config.ts'), viteConfig),\n    emitFile(join(projectDir, 'index.html'), indexHtml),\n    emitFile(join(projectDir, 'src', 'main.tsx'), mainTsx),\n    emitFile(join(projectDir, 'src', 'App.tsx'), appContent),\n  ]);\n\n  // Report results using Iterator Helpers\n  const failed = results\n    .values()\n    .filter((r) => r.status === 'rejected')\n    .toArray();\n\n  if (failed.length > 0) {\n    process.exit(1);\n  }\n\n  const written = results\n    .values()\n    .filter((r): r is PromiseFulfilledResult<string> => r.status === 'fulfilled')\n    .map((r) => r.value)\n    .toArray();\n  written.values().forEach((_f) => {});\n}\n\nmain().catch((_err: unknown) => {\n  process.exit(1);\n});\n"],"mappings":"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"}