@puzzle-ui/create 0.4.0 → 0.5.1

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/README.md CHANGED
@@ -1,41 +1,33 @@
1
1
  # @puzzle-ui/create
2
2
 
3
- Create React applications with Puzzle UI.
3
+ Generate a new React application with Puzzle UI and Theme configured. Choose Next.js, TanStack Start, or Basic React (React + Vite + TypeScript), then optionally add Tailwind CSS v4 or Puzzle Auth.
4
+
5
+ **Documentation:** [https://puzzle-ui.com/docs/create](https://puzzle-ui.com/docs/create)
4
6
 
5
7
  ## Requirements
6
8
 
7
- - Node.js >= 20.19
8
- - npm or Bun
9
+ - Node.js 20.19 or later
10
+ - npm, Bun, pnpm, or Yarn
11
+ - Internet access to download the framework template and dependencies
9
12
 
10
- ## Usage
13
+ ## Create a project
11
14
 
12
- With npm:
15
+ Run the interactive generator; it prompts for a project name, framework, Tailwind, and Puzzle Auth. The name is converted to kebab-case. The CLI does not overwrite an existing directory and has no command-line flags.
13
16
 
14
17
  ```bash
15
18
  npx @puzzle-ui/create
16
19
  ```
17
20
 
18
- With Bun:
19
-
20
- ```bash
21
- bunx @puzzle-ui/create
22
- ```
21
+ Alternatives: `bunx @puzzle-ui/create`, `pnpm dlx @puzzle-ui/create`, or `yarn dlx @puzzle-ui/create` (Yarn 2+; Yarn Classic users can use `npx`).
23
22
 
24
- ## Supported frameworks
23
+ The generator installs `@puzzle-ui/ui` and `@puzzle-ui/theme`, adds a themed starter page with a Puzzle `Button`, and uses the detected package manager for framework generation and dependency installation. Tailwind is enabled by default; Puzzle Auth is optional and disabled by default.
25
24
 
26
- - Next.js
27
- - TanStack Start
28
- - Basic React (Vite + TypeScript)
25
+ When Auth is enabled, the CLI adds client auth components and, for Next.js and TanStack Start, an API route and server bootstrap. The generated bootstrap deliberately has no default security providers: configure the required storage, password hashing, rate limiting, sessions, MFA, step-up, cookies, CSRF, and trusted client IP handling before exposing the route. See the [Authentication setup guide](https://puzzle-ui.com/docs/developer/authentication).
29
26
 
30
- ## Features
27
+ See the [Create documentation](https://puzzle-ui.com/docs/create) for framework-specific generated files, Tailwind setup, and Auth requirements.
31
28
 
32
- - Interactive project setup
33
- - Automatic kebab-case project names
34
- - Framework scaffolding using official CLI tools
35
- - Automatic Puzzle UI installation
36
- - Automatic Puzzle Theme configuration
37
- - React 19 compatibility
29
+ Puzzle is under active development and is not yet ready for production use. Review and test generated applications before using them in production.
38
30
 
39
- ## License
31
+ ## Package details
40
32
 
41
- MIT
33
+ The published command is `create-puzzle`. The package is CLI-only; it does not provide an importable JavaScript API. License: MIT.
package/dist/index.js CHANGED
@@ -5,6 +5,11 @@ import path from "node:path";
5
5
  import { spawn } from "node:child_process";
6
6
  // src/constants.ts
7
7
  const PUZZLE_PACKAGES = ["@puzzle-ui/ui@latest", "@puzzle-ui/theme@latest"];
8
+ const PUZZLE_AUTH_PACKAGES = [
9
+ "@puzzle-ui/auth@latest",
10
+ "@puzzle-ui/fullstack@latest",
11
+ "@puzzle-ui/session@latest"
12
+ ];
8
13
  const FRAMEWORKS = [
9
14
  {
10
15
  value: "react",
@@ -26,8 +31,7 @@ const FRAMEWORKS = [
26
31
  const toKebabCase = (value) => value.normalize("NFKD").replace(/[\u0300-\u036f]/g, "").replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/([A-Z])([A-Z][a-z])/g, "$1-$2").replace(/[^a-zA-Z0-9]+/g, "-").replace(/^-+|-+$/g, "").toLowerCase();
27
32
  // src/utils/detect-package-manager.ts
28
33
  const detectPackageManager = (userAgent = process.env.npm_config_user_agent ?? "") => {
29
- if (userAgent.startsWith("bun/")) return "bun";
30
- return "npm";
34
+ return userAgent.match(/(?:^|\s)(bun|pnpm|yarn|npm)\/[^\s]+/)?.[1] ?? "npm";
31
35
  };
32
36
  // src/prompts.ts
33
37
  const getProjectOptions = async () => {
@@ -59,12 +63,21 @@ const getProjectOptions = async () => {
59
63
  p.cancel("Project creation cancelled.");
60
64
  return null;
61
65
  }
66
+ const auth = await p.confirm({
67
+ message: "Would you like to add Puzzle Auth?",
68
+ initialValue: false
69
+ });
70
+ if (p.isCancel(auth)) {
71
+ p.cancel("Project creation cancelled.");
72
+ return null;
73
+ }
62
74
  return {
63
75
  name: directory,
64
76
  directory,
65
77
  framework,
66
78
  packageManager: detectPackageManager(),
67
- tailwind
79
+ tailwind,
80
+ auth
68
81
  };
69
82
  };
70
83
  // src/utils/execute.ts
@@ -85,6 +98,20 @@ const runCommand = (command, args, options = {}) => new Promise((resolve, reject
85
98
  });
86
99
  });
87
100
  // src/frameworks/next.ts
101
+ const getExecutor$1 = (packageManager) => {
102
+ if (packageManager === "bun") return {
103
+ command: "bunx",
104
+ prefix: []
105
+ };
106
+ if (packageManager === "pnpm" || packageManager === "yarn") return {
107
+ command: packageManager,
108
+ prefix: ["dlx"]
109
+ };
110
+ return {
111
+ command: "npx",
112
+ prefix: ["--yes"]
113
+ };
114
+ };
88
115
  const createNextProject = async (directory, packageManager, runner = runCommand, cwd) => {
89
116
  const args = [
90
117
  "create-next-app@latest",
@@ -96,17 +123,26 @@ const createNextProject = async (directory, packageManager, runner = runCommand,
96
123
  "--disable-git",
97
124
  "--no-tailwind",
98
125
  "--yes",
99
- packageManager === "bun" ? "--use-bun" : "--use-npm"
126
+ `--use-${packageManager}`
100
127
  ];
101
- const command = packageManager === "bun" ? "bunx" : "npx";
102
- const commandArgs = packageManager === "bun" ? args : ["--yes", ...args];
103
- if (cwd) {
104
- await runner(command, commandArgs, { cwd });
105
- return;
106
- }
107
- await runner(command, commandArgs);
128
+ const executor = getExecutor$1(packageManager);
129
+ await runner(executor.command, [...executor.prefix, ...args], cwd ? { cwd } : void 0);
108
130
  };
109
131
  // src/frameworks/tanstack.ts
132
+ const getExecutor = (packageManager) => {
133
+ if (packageManager === "bun") return {
134
+ command: "bunx",
135
+ prefix: []
136
+ };
137
+ if (packageManager === "pnpm" || packageManager === "yarn") return {
138
+ command: packageManager,
139
+ prefix: ["dlx"]
140
+ };
141
+ return {
142
+ command: "npx",
143
+ prefix: ["--yes"]
144
+ };
145
+ };
110
146
  const createTanStackProject = async (directory, packageManager, runner = runCommand, cwd) => {
111
147
  const args = [
112
148
  "@tanstack/cli@latest",
@@ -121,13 +157,8 @@ const createTanStackProject = async (directory, packageManager, runner = runComm
121
157
  "--no-git",
122
158
  "--yes"
123
159
  ];
124
- const command = packageManager === "bun" ? "bunx" : "npx";
125
- const commandArgs = packageManager === "bun" ? args : ["--yes", ...args];
126
- if (cwd) {
127
- await runner(command, commandArgs, { cwd });
128
- return;
129
- }
130
- await runner(command, commandArgs);
160
+ const executor = getExecutor(packageManager);
161
+ await runner(executor.command, [...executor.prefix, ...args], cwd ? { cwd } : void 0);
131
162
  };
132
163
  // src/frameworks/react.ts
133
164
  const createReactProject = async (directory, _packageManager, _runner) => {
@@ -246,6 +277,43 @@ const frameworkGenerators = {
246
277
  tanstack: createTanStackProject,
247
278
  react: createReactProject
248
279
  };
280
+ // src/frameworks/configure-framework.ts
281
+ const getTranspiledPackages = (auth) => [
282
+ "@puzzle-ui/ui",
283
+ "@puzzle-ui/theme",
284
+ ...auth ? ["@puzzle-ui/fullstack"] : []
285
+ ];
286
+ const configureNext = async (directory, auth) => {
287
+ const configPath = path.join(directory, "next.config.ts");
288
+ const packages = getTranspiledPackages(auth);
289
+ const config = `import type { NextConfig } from "next";
290
+
291
+ const nextConfig: NextConfig = {
292
+ transpilePackages: ${JSON.stringify(packages, null, 4)},
293
+ };
294
+
295
+ export default nextConfig;
296
+ `;
297
+ await writeFile(configPath, config, "utf8");
298
+ };
299
+ const configureTanStack = async (directory, auth) => {
300
+ const configPath = path.join(directory, "vite.config.ts");
301
+ let config = await readFile(configPath, "utf8");
302
+ const packages = getTranspiledPackages(auth);
303
+ if (!config.includes("noExternal")) config = config.replace(/defineConfig\(\s*\{/, `defineConfig({
304
+ ssr: {
305
+ noExternal: ${JSON.stringify(packages)},
306
+ },`);
307
+ else if (auth && !config.includes("\"@puzzle-ui/fullstack\"")) config = config.replace(/noExternal:\s*\[([^\]]*)\]/, `noExternal: [$1, "@puzzle-ui/fullstack"]`);
308
+ await writeFile(configPath, config, "utf8");
309
+ };
310
+ const configureFramework = async (directory, framework, auth = false) => {
311
+ if (framework === "next") {
312
+ await configureNext(directory, auth);
313
+ return;
314
+ }
315
+ if (framework === "tanstack") await configureTanStack(directory, auth);
316
+ };
249
317
  const themeTemplates = {
250
318
  next: {
251
319
  "src/app/providers.tsx": `"use client";
@@ -399,6 +467,283 @@ const configureTheme = async (directory, framework) => {
399
467
  await writeFile(filePath, content, "utf8");
400
468
  }));
401
469
  };
470
+ // src/auth/templates.ts
471
+ const authServer = `import type { AuthServer } from "@puzzle-ui/fullstack/auth/server";
472
+
473
+ let authServer: AuthServer | null = null;
474
+
475
+ /**
476
+ * Register the server configured by your application.
477
+ *
478
+ * Create the AuthServer with your own storage adapter, password hasher,
479
+ * rate limiter, session manager, MFA manager and CSRF configuration.
480
+ *
481
+ * Never import this module from browser-facing code.
482
+ */
483
+ export const configureAuthServer = (server: AuthServer): void => {
484
+ if (authServer && authServer !== server) {
485
+ throw new Error("Puzzle Auth has already been configured.");
486
+ }
487
+
488
+ authServer = server;
489
+ };
490
+
491
+ /**
492
+ * Returns null until the application has registered its AuthServer.
493
+ */
494
+ export const getAuthServer = (): AuthServer | null => authServer;
495
+ `;
496
+ const authBootstrap = `/**
497
+ * Initialize Puzzle Auth once for this server runtime.
498
+ *
499
+ * Configure your storage adapter and security providers here.
500
+ *
501
+ * Example:
502
+ *
503
+ * configureAuthServer(
504
+ * createAuthServer({
505
+ * auth,
506
+ * mfa,
507
+ * stepUp,
508
+ * sessions,
509
+ * cookie,
510
+ * csrf,
511
+ * resolveClientIp,
512
+ * }),
513
+ * );
514
+ *
515
+ * Do not use development-only or in-memory providers in production.
516
+ */
517
+ const configure = async (): Promise<void> => {
518
+ // TODO: initialize your application-specific AuthServer.
519
+ };
520
+
521
+ let initialization: Promise<void> | null = null;
522
+
523
+ export const initializePuzzleAuth = (): Promise<void> => {
524
+ if (!initialization) {
525
+ initialization = configure().catch((error: unknown) => {
526
+ initialization = null;
527
+ throw error;
528
+ });
529
+ }
530
+
531
+ return initialization;
532
+ };
533
+ `;
534
+ const authUnavailableResponse = `const createAuthUnavailableResponse = (): Response =>
535
+ new Response(
536
+ JSON.stringify({
537
+ error: {
538
+ code: "AUTH_NOT_CONFIGURED",
539
+ message: "Puzzle Auth has not been configured by the application.",
540
+ },
541
+ }),
542
+ {
543
+ status: 503,
544
+ headers: {
545
+ "Content-Type": "application/json; charset=utf-8",
546
+ "Cache-Control": "no-store",
547
+ Pragma: "no-cache",
548
+ },
549
+ },
550
+ );
551
+
552
+ export { createAuthUnavailableResponse };
553
+ `;
554
+ const authTemplates = {
555
+ next: {
556
+ "src/app/providers.tsx": `"use client";
557
+
558
+ import type { ReactNode } from "react";
559
+
560
+ import { Theme } from "@puzzle-ui/theme";
561
+ import { AuthProvider } from "@puzzle-ui/fullstack/auth/client";
562
+
563
+ type ProvidersProps = {
564
+ children: ReactNode;
565
+ };
566
+
567
+ const Providers = ({ children }: ProvidersProps) => (
568
+ <Theme theme="system">
569
+ <AuthProvider options={{ basePath: "/api/auth" }}>
570
+ {children}
571
+ </AuthProvider>
572
+ </Theme>
573
+ );
574
+
575
+ export { Providers };
576
+ `,
577
+ "src/app/sign-in/page.tsx": `"use client";
578
+
579
+ import { AuthExperience } from "@puzzle-ui/fullstack/auth/client";
580
+
581
+ const SignInPage = () => <AuthExperience mode="sign-in" />;
582
+
583
+ export default SignInPage;
584
+ `,
585
+ "src/app/sign-up/page.tsx": `"use client";
586
+
587
+ import { AuthExperience } from "@puzzle-ui/fullstack/auth/client";
588
+
589
+ const SignUpPage = () => <AuthExperience mode="sign-up" />;
590
+
591
+ export default SignUpPage;
592
+ `,
593
+ "src/app/api/auth/[...auth]/route.ts": `import { createNextAuthHandler } from "@puzzle-ui/fullstack/auth/next";
594
+
595
+ import { getAuthServer } from "../../../../lib/auth/server";
596
+ import { initializePuzzleAuth } from "../../../../lib/auth/bootstrap";
597
+ import { createAuthUnavailableResponse } from "../../../../lib/auth/unavailable";
598
+
599
+ const handle = async (request: Request): Promise<Response> => {
600
+ await initializePuzzleAuth();
601
+
602
+ const auth = getAuthServer();
603
+
604
+ if (!auth) {
605
+ return createAuthUnavailableResponse();
606
+ }
607
+
608
+ const handlers = createNextAuthHandler({ auth });
609
+
610
+ return request.method.toUpperCase() === "GET"
611
+ ? handlers.GET(request)
612
+ : handlers.POST(request);
613
+ };
614
+
615
+ export { handle as GET, handle as POST };
616
+ `,
617
+ "src/lib/auth/server.ts": authServer,
618
+ "src/lib/auth/bootstrap.ts": authBootstrap,
619
+ "src/lib/auth/unavailable.ts": authUnavailableResponse
620
+ },
621
+ tanstack: {
622
+ "src/routes/__root.tsx": `import {
623
+ createRootRoute,
624
+ HeadContent,
625
+ Outlet,
626
+ Scripts,
627
+ } from "@tanstack/react-router";
628
+
629
+ import { Theme } from "@puzzle-ui/theme";
630
+ import { AuthProvider } from "@puzzle-ui/fullstack/auth/client";
631
+
632
+ const RootComponent = () => (
633
+ <html lang="en">
634
+ <head>
635
+ <HeadContent />
636
+ </head>
637
+ <body>
638
+ <Theme theme="system">
639
+ <AuthProvider options={{ basePath: "/api/auth" }}>
640
+ <Outlet />
641
+ </AuthProvider>
642
+ </Theme>
643
+ <Scripts />
644
+ </body>
645
+ </html>
646
+ );
647
+
648
+ export const Route = createRootRoute({
649
+ component: RootComponent,
650
+ });
651
+ `,
652
+ "src/routes/sign-in.tsx": `import { createFileRoute } from "@tanstack/react-router";
653
+
654
+ import { AuthExperience } from "@puzzle-ui/fullstack/auth/client";
655
+
656
+ const SignInPage = () => <AuthExperience mode="sign-in" />;
657
+
658
+ export const Route = createFileRoute("/sign-in")({
659
+ component: SignInPage,
660
+ });
661
+ `,
662
+ "src/routes/sign-up.tsx": `import { createFileRoute } from "@tanstack/react-router";
663
+
664
+ import { AuthExperience } from "@puzzle-ui/fullstack/auth/client";
665
+
666
+ const SignUpPage = () => <AuthExperience mode="sign-up" />;
667
+
668
+ export const Route = createFileRoute("/sign-up")({
669
+ component: SignUpPage,
670
+ });
671
+ `,
672
+ "src/routes/api/auth/$.ts": `import { createFileRoute } from "@tanstack/react-router";
673
+
674
+ import { createTanStackAuthHandler } from "@puzzle-ui/fullstack/auth/tanstack";
675
+
676
+ import { getAuthServer } from "../../../lib/auth/server";
677
+ import { initializePuzzleAuth } from "../../../lib/auth/bootstrap";
678
+ import { createAuthUnavailableResponse } from "../../../lib/auth/unavailable";
679
+
680
+ const handle = async (request: Request): Promise<Response> => {
681
+ await initializePuzzleAuth();
682
+
683
+ const auth = getAuthServer();
684
+
685
+ if (!auth) {
686
+ return createAuthUnavailableResponse();
687
+ }
688
+
689
+ return createTanStackAuthHandler({ auth })(request);
690
+ };
691
+
692
+ export const Route = createFileRoute("/api/auth/$")({
693
+ server: {
694
+ handlers: {
695
+ GET: ({ request }) => handle(request),
696
+ POST: ({ request }) => handle(request),
697
+ },
698
+ },
699
+ });
700
+ `,
701
+ "src/lib/auth/server.ts": authServer,
702
+ "src/lib/auth/bootstrap.ts": authBootstrap,
703
+ "src/lib/auth/unavailable.ts": authUnavailableResponse
704
+ },
705
+ react: {
706
+ "src/main.tsx": `import React from "react";
707
+ import ReactDOM from "react-dom/client";
708
+
709
+ import { Theme } from "@puzzle-ui/theme";
710
+ import { AuthProvider } from "@puzzle-ui/fullstack/auth/client";
711
+
712
+ import App from "./App";
713
+
714
+ import "./index.css";
715
+
716
+ ReactDOM.createRoot(
717
+ document.getElementById("root")!,
718
+ ).render(
719
+ <React.StrictMode>
720
+ <Theme theme="system">
721
+ <AuthProvider options={{ basePath: "/api/auth" }}>
722
+ <App />
723
+ </AuthProvider>
724
+ </Theme>
725
+ </React.StrictMode>,
726
+ );
727
+ `,
728
+ "src/auth/sign-in.tsx": `import { AuthExperience } from "@puzzle-ui/fullstack/auth/client";
729
+
730
+ export const SignInPage = () => <AuthExperience mode="sign-in" />;
731
+ `,
732
+ "src/auth/sign-up.tsx": `import { AuthExperience } from "@puzzle-ui/fullstack/auth/client";
733
+
734
+ export const SignUpPage = () => <AuthExperience mode="sign-up" />;
735
+ `
736
+ }
737
+ };
738
+ // src/auth/configure-auth.ts
739
+ const configureAuth = async (directory, framework) => {
740
+ const templates = authTemplates[framework];
741
+ await Promise.all(Object.entries(templates).map(async ([relativePath, content]) => {
742
+ const filePath = path.join(directory, relativePath);
743
+ await mkdir(path.dirname(filePath), { recursive: true });
744
+ await writeFile(filePath, content, "utf8");
745
+ }));
746
+ };
402
747
  // src/utils/validate-project.ts
403
748
  const validateProjectDirectory = async (directory, cwd = process.cwd()) => {
404
749
  const root = path.resolve(cwd);
@@ -501,30 +846,31 @@ const getTailwindPackages = (framework) => {
501
846
  ];
502
847
  return ["tailwindcss@latest", "@tailwindcss/vite@latest"];
503
848
  };
504
- const installTailwind = async ({ directory, framework, packageManager, runner }) => {
505
- const packages = getTailwindPackages(framework);
506
- if (packageManager === "bun") {
507
- await runner("bun", [
508
- "add",
509
- "-d",
510
- ...packages
511
- ], { cwd: directory });
512
- return;
513
- }
514
- await runner("npm", [
849
+ const getInstallArguments = (packageManager, packages) => {
850
+ if (packageManager === "npm") return [
515
851
  "install",
516
852
  "--save-dev",
517
853
  ...packages
518
- ], { cwd: directory });
854
+ ];
855
+ if (packageManager === "yarn") return [
856
+ "add",
857
+ "--dev",
858
+ ...packages
859
+ ];
860
+ return [
861
+ "add",
862
+ "-D",
863
+ ...packages
864
+ ];
865
+ };
866
+ const installTailwind = async ({ directory, framework, packageManager, runner }) => {
867
+ const packages = getTailwindPackages(framework);
868
+ await runner(packageManager, getInstallArguments(packageManager, packages), { cwd: directory });
519
869
  };
520
870
  // src/create-project.ts
521
- const installDependencies = async (directory, packageManager, runner) => {
522
- const packages = [...PUZZLE_PACKAGES];
523
- if (packageManager === "bun") {
524
- await runner("bun", ["add", ...packages], { cwd: directory });
525
- return;
526
- }
527
- await runner("npm", ["install", ...packages], { cwd: directory });
871
+ const installDependencies = async (directory, packageManager, auth, runner) => {
872
+ const packages = [...PUZZLE_PACKAGES, ...auth ? PUZZLE_AUTH_PACKAGES : []];
873
+ await runner(packageManager, packageManager === "npm" ? ["install", ...packages] : ["add", ...packages], { cwd: directory });
528
874
  };
529
875
  const configureProjectName = async (directory, projectName) => {
530
876
  const packageJsonPath = path.join(directory, "package.json");
@@ -551,10 +897,18 @@ const createProject = async (options, { cwd = process.cwd(), runner = runCommand
551
897
  if (options.framework === "react") await frameworkGenerators.react(targetDirectory, options.packageManager, runner);
552
898
  else await frameworkGenerators[options.framework](projectName, options.packageManager, runner, projectParent);
553
899
  finishStep("Framework generated");
900
+ startStep("Configuring framework");
901
+ await configureFramework(targetDirectory, options.framework, options.auth);
902
+ finishStep("Framework configured");
554
903
  startStep("Configuring Puzzle theme");
555
904
  await configureTheme(targetDirectory, options.framework);
556
905
  await configureProjectName(targetDirectory, projectName);
557
906
  finishStep("Puzzle theme configured");
907
+ if (options.auth) {
908
+ startStep("Configuring Puzzle Auth");
909
+ await configureAuth(targetDirectory, options.framework);
910
+ finishStep("Puzzle Auth configured");
911
+ }
558
912
  if (options.tailwind) {
559
913
  startStep("Configuring Tailwind CSS");
560
914
  await configureTailwind(targetDirectory, options.framework);
@@ -569,14 +923,14 @@ const createProject = async (options, { cwd = process.cwd(), runner = runCommand
569
923
  finishStep("Tailwind CSS installed");
570
924
  }
571
925
  startStep("Installing Puzzle");
572
- await installDependencies(targetDirectory, options.packageManager, runner);
573
- finishStep("Puzzle installed");
926
+ await installDependencies(targetDirectory, options.packageManager, options.auth, runner);
927
+ finishStep(options.auth ? "Puzzle and Auth installed" : "Puzzle installed");
574
928
  } catch (error) {
575
929
  if (spinnerActive) spinner.error("Project creation failed");
576
930
  throw error;
577
931
  }
578
932
  p.log.success(`Project "${projectName}" created successfully.`);
579
- p.outro(`Next steps:\n\n cd ${path.relative(process.cwd(), targetDirectory) || "."}\n ${options.packageManager} run dev`);
933
+ p.outro(`Next steps:\n\n cd ${path.relative(cwd, targetDirectory) || "."}\n ${options.packageManager} run dev`);
580
934
  };
581
935
  // src/index.ts
582
936
  const main = async () => {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/constants.ts","../src/utils/kebab-case.ts","../src/utils/detect-package-manager.ts","../src/prompts.ts","../src/utils/execute.ts","../src/frameworks/next.ts","../src/frameworks/tanstack.ts","../src/frameworks/react.ts","../src/frameworks/index.ts","../src/theme/templates.ts","../src/theme/configure-theme.ts","../src/utils/validate-project.ts","../src/tailwind/configure-tailwind.ts","../src/tailwind/install-tailwind.ts","../src/create-project.ts","../src/index.ts"],"sourcesContent":["import type { Framework } from \"./types\";\n\nexport const PACKAGE_NAME = \"@puzzle-ui/create\";\n\nexport const PUZZLE_PACKAGES = [\n \"@puzzle-ui/ui@latest\",\n \"@puzzle-ui/theme@latest\",\n] as const;\n\nexport const FRAMEWORKS: {\n value: Framework;\n label: string;\n hint: string;\n}[] = [\n {\n value: \"react\",\n label: \"Basic React Project\",\n hint: \"React + Vite + TypeScript\",\n },\n {\n value: \"tanstack\",\n label: \"TanStack Start\",\n hint: \"Full-stack React framework\",\n },\n {\n value: \"next\",\n label: \"Next.js\",\n hint: \"React framework with App Router\",\n },\n];\n","const toKebabCase = (value: string): string =>\n value\n .normalize(\"NFKD\")\n .replace(/[\\u0300-\\u036f]/g, \"\")\n .replace(/([a-z0-9])([A-Z])/g, \"$1-$2\")\n .replace(/([A-Z])([A-Z][a-z])/g, \"$1-$2\")\n .replace(/[^a-zA-Z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .toLowerCase();\n\nexport { toKebabCase };\n","import type { PackageManager } from \"../types\";\n\nconst detectPackageManager = (\n userAgent = process.env.npm_config_user_agent ?? \"\",\n): PackageManager => {\n if (userAgent.startsWith(\"bun/\")) {\n return \"bun\";\n }\n\n return \"npm\";\n};\n\nexport { detectPackageManager };\n","import * as p from \"@clack/prompts\";\n\nimport { FRAMEWORKS } from \"./constants\";\n\nimport type { Framework, ProjectOptions } from \"./types\";\n\nimport { toKebabCase } from \"./utils/kebab-case\";\n\nimport { detectPackageManager } from \"./utils/detect-package-manager\";\n\nconst getProjectOptions = async (): Promise<ProjectOptions | null> => {\n p.intro(\"Create a Puzzle application\");\n\n const name = await p.text({\n message: \"What is the name of your project?\",\n placeholder: \"my-awesome-app\",\n validate: (value) => {\n if (!value?.trim()) {\n return \"Project name is required.\";\n }\n\n if (!toKebabCase(value)) {\n return \"Please enter a valid project name.\";\n }\n },\n });\n\n if (p.isCancel(name)) {\n return null;\n }\n\n const directory = toKebabCase(name);\n\n const framework = await p.select({\n message: \"Which framework would you like to use?\",\n options: FRAMEWORKS.map((item) => ({\n value: item.value,\n label: item.label,\n hint: item.hint,\n })),\n });\n\n if (p.isCancel(framework)) {\n return null;\n }\n\n const tailwind = await p.confirm({\n message: \"Would you like to install Tailwind CSS?\",\n initialValue: true,\n });\n\n if (p.isCancel(tailwind)) {\n p.cancel(\"Project creation cancelled.\");\n return null;\n }\n\n return {\n name: directory,\n directory,\n framework: framework as Framework,\n packageManager: detectPackageManager(),\n tailwind,\n };\n};\n\nexport { getProjectOptions };\n","import { spawn } from \"node:child_process\";\n\nimport type { CommandRunner } from \"../types\";\n\nconst runCommand: CommandRunner = (command, args, options = {}) =>\n new Promise((resolve, reject) => {\n const child = spawn(command, args, {\n cwd: options.cwd ?? process.cwd(),\n stdio: options.stdio ?? \"inherit\",\n shell: false,\n env: process.env,\n });\n\n child.once(\"error\", reject);\n\n child.once(\"close\", (code, signal) => {\n if (code === 0) {\n resolve();\n return;\n }\n\n reject(\n new Error(\n signal\n ? `${command} terminated with signal ${signal}`\n : `${command} exited with code ${code ?? \"unknown\"}`,\n ),\n );\n });\n });\n\nexport { runCommand };\n","import type { FrameworkGenerator } from \"../types\";\n\nimport { runCommand } from \"../utils/execute\";\n\nconst createNextProject: FrameworkGenerator = async (\n directory,\n packageManager,\n runner = runCommand,\n cwd,\n) => {\n const args = [\n \"create-next-app@latest\",\n directory,\n \"--ts\",\n \"--app\",\n \"--src-dir\",\n \"--skip-install\",\n \"--disable-git\",\n \"--no-tailwind\",\n \"--yes\",\n packageManager === \"bun\" ? \"--use-bun\" : \"--use-npm\",\n ];\n\n const command = packageManager === \"bun\" ? \"bunx\" : \"npx\";\n const commandArgs = packageManager === \"bun\" ? args : [\"--yes\", ...args];\n\n if (cwd) {\n await runner(command, commandArgs, { cwd });\n return;\n }\n\n await runner(command, commandArgs);\n};\n\nexport { createNextProject };\n","import type { FrameworkGenerator } from \"../types\";\n\nimport { runCommand } from \"../utils/execute\";\n\nconst createTanStackProject: FrameworkGenerator = async (\n directory,\n packageManager,\n runner = runCommand,\n cwd,\n) => {\n const args = [\n \"@tanstack/cli@latest\",\n \"create\",\n directory,\n \"--framework\",\n \"React\",\n \"--package-manager\",\n packageManager,\n \"--blank\",\n \"--no-install\",\n \"--no-git\",\n \"--yes\",\n ];\n\n const command = packageManager === \"bun\" ? \"bunx\" : \"npx\";\n const commandArgs = packageManager === \"bun\" ? args : [\"--yes\", ...args];\n\n if (cwd) {\n await runner(command, commandArgs, { cwd });\n return;\n }\n\n await runner(command, commandArgs);\n};\n\nexport { createTanStackProject };\n","import { mkdir, writeFile } from \"node:fs/promises\";\n\nimport path from \"node:path\";\n\nimport type { FrameworkGenerator } from \"../types\";\n\nconst createReactProject: FrameworkGenerator = async (\n directory,\n _packageManager,\n _runner,\n) => {\n await mkdir(path.join(directory, \"src\"), {\n recursive: true,\n });\n\n const packageJson = {\n name: path.basename(directory),\n private: true,\n version: \"0.0.0\",\n type: \"module\",\n scripts: {\n dev: \"vite\",\n build: \"tsc --noEmit -p tsconfig.app.json && vite build\",\n preview: \"vite preview\",\n },\n dependencies: {\n react: \"^19.0.0\",\n \"react-dom\": \"^19.0.0\",\n },\n devDependencies: {\n \"@types/node\": \"latest\",\n \"@types/react\": \"^19.0.0\",\n \"@types/react-dom\": \"^19.0.0\",\n \"@vitejs/plugin-react\": \"latest\",\n typescript: \"latest\",\n vite: \"latest\",\n },\n };\n\n const files: Record<string, string> = {\n \"package.json\": JSON.stringify(packageJson, null, 2),\n\n \"index.html\": `<!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>Puzzle App</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 \"tsconfig.json\": JSON.stringify(\n {\n files: [],\n references: [\n { path: \"./tsconfig.app.json\" },\n { path: \"./tsconfig.node.json\" },\n ],\n },\n null,\n 2,\n ),\n\n \"tsconfig.app.json\": JSON.stringify(\n {\n compilerOptions: {\n tsBuildInfoFile: \"./node_modules/.tmp/tsconfig.app.tsbuildinfo\",\n target: \"ES2022\",\n useDefineForClassFields: true,\n lib: [\"ES2022\", \"DOM\", \"DOM.Iterable\"],\n module: \"ESNext\",\n skipLibCheck: true,\n moduleResolution: \"bundler\",\n allowImportingTsExtensions: true,\n verbatimModuleSyntax: true,\n moduleDetection: \"force\",\n noEmit: true,\n jsx: \"react-jsx\",\n strict: true,\n noUnusedLocals: true,\n noUnusedParameters: true,\n noFallthroughCasesInSwitch: true,\n types: [\"vite/client\"],\n },\n include: [\"src\"],\n },\n null,\n 2,\n ),\n\n \"tsconfig.node.json\": JSON.stringify(\n {\n compilerOptions: {\n tsBuildInfoFile: \"./node_modules/.tmp/tsconfig.node.tsbuildinfo\",\n target: \"ES2023\",\n lib: [\"ES2023\"],\n module: \"ESNext\",\n skipLibCheck: true,\n moduleResolution: \"bundler\",\n allowImportingTsExtensions: true,\n verbatimModuleSyntax: true,\n moduleDetection: \"force\",\n noEmit: true,\n strict: true,\n },\n include: [\"vite.config.ts\"],\n },\n null,\n 2,\n ),\n\n \"vite.config.ts\": `import { defineConfig } from \"vite\";\nimport react from \"@vitejs/plugin-react\";\n\nexport default defineConfig({\n plugins: [react()],\n});`,\n\n \"src/main.tsx\": \"\",\n \"src/App.tsx\": \"\",\n \"src/index.css\": `* {\n box-sizing: border-box;\n}\n\nhtml,\nbody,\n#root {\n min-height: 100%;\n}\n\nbody {\n margin: 0;\n font-family: var(--puzzle-font-family-body, sans-serif);\n}`,\n };\n\n await Promise.all(\n Object.entries(files).map(([file, content]) =>\n writeFile(path.join(directory, file), content, \"utf8\"),\n ),\n );\n};\n\nexport { createReactProject };\n","import { createNextProject } from \"./next\";\nimport { createTanStackProject } from \"./tanstack\";\nimport { createReactProject } from \"./react\";\n\nimport type { Framework, FrameworkGenerator } from \"../types\";\n\nconst frameworkGenerators: Record<Framework, FrameworkGenerator> = {\n next: createNextProject,\n tanstack: createTanStackProject,\n react: createReactProject,\n};\n\nexport {\n createNextProject,\n createTanStackProject,\n createReactProject,\n frameworkGenerators,\n};\n","const nextProviders = `\"use client\";\n\nimport type { ReactNode } from \"react\";\n\nimport { Theme } from \"@puzzle-ui/theme\";\n\ntype ProvidersProps = {\n children: ReactNode;\n};\n\nconst Providers = ({ children }: ProvidersProps) => (\n <Theme theme=\"system\">\n {children}\n </Theme>\n);\n\nexport { Providers };\n`;\n\nconst nextLayout = `import \"./globals.css\";\n\nimport type { ReactNode } from \"react\";\n\nimport { Providers } from \"./providers\";\n\ntype RootLayoutProps = {\n children: ReactNode;\n};\n\nconst RootLayout = ({ children }: RootLayoutProps) => (\n <html lang=\"en\">\n <body>\n <Providers>\n {children}\n </Providers>\n </body>\n </html>\n);\n\nexport default RootLayout;\n`;\n\nconst nextPage = `\"use client\";\nimport { Button } from \"@puzzle-ui/ui\";\n\nconst HomePage = () => (\n <main style={{ padding: \"2rem\" }}>\n <h1>Welcome to Puzzle</h1>\n <p>Your new Puzzle application is ready.</p>\n\n <Button onClick={() => console.log(\"Hello, Puzzle!\")}>\n Get started\n </Button>\n </main>\n);\n\nexport default HomePage;\n`;\n\nconst tanstackRootRoute = `import {\n createRootRoute,\n HeadContent,\n Outlet,\n Scripts,\n} from \"@tanstack/react-router\";\n\nimport { Theme } from \"@puzzle-ui/theme\";\n\nconst RootComponent = () => (\n <html lang=\"en\">\n <head>\n <HeadContent />\n </head>\n <body>\n <Theme theme=\"system\">\n <Outlet />\n </Theme>\n <Scripts />\n </body>\n </html>\n);\n\nexport const Route = createRootRoute({\n component: RootComponent,\n});\n`;\n\nconst tanstackIndexRoute = `import { createFileRoute } from \"@tanstack/react-router\";\n\nimport { Button } from \"@puzzle-ui/ui\";\n\nconst HomePage = () => (\n <main style={{ padding: \"2rem\" }}>\n <h1>Welcome to Puzzle</h1>\n <p>Your new Puzzle application is ready.</p>\n\n <Button onClick={() => console.log(\"Hello, Puzzle!\")}>\n Get started\n </Button>\n </main>\n);\n\nexport const Route = createFileRoute(\"/\")({\n component: HomePage,\n});\n`;\n\nconst reactMain = `import React from \"react\";\nimport ReactDOM from \"react-dom/client\";\n\nimport { Theme } from \"@puzzle-ui/theme\";\n\nimport App from \"./App\";\n\nimport \"./index.css\";\n\nReactDOM.createRoot(\n document.getElementById(\"root\")!,\n).render(\n <React.StrictMode>\n <Theme theme=\"system\">\n <App />\n </Theme>\n </React.StrictMode>,\n);\n`;\n\nconst reactApp = `import { Button } from \"@puzzle-ui/ui\";\n\nconst App = () => (\n <main style={{ padding: \"2rem\" }}>\n <h1>Welcome to Puzzle</h1>\n <p>Your new Puzzle application is ready.</p>\n\n <Button onClick={() => console.log(\"Hello, Puzzle!\")}>\n Get started\n </Button>\n </main>\n);\n\nexport default App;\n`;\n\nconst themeTemplates = {\n next: {\n \"src/app/providers.tsx\": nextProviders,\n \"src/app/layout.tsx\": nextLayout,\n \"src/app/page.tsx\": nextPage,\n },\n tanstack: {\n \"src/routes/__root.tsx\": tanstackRootRoute,\n \"src/routes/index.tsx\": tanstackIndexRoute,\n },\n react: {\n \"src/main.tsx\": reactMain,\n \"src/App.tsx\": reactApp,\n },\n} as const;\n\nexport {\n nextProviders,\n nextLayout,\n nextPage,\n tanstackRootRoute,\n tanstackIndexRoute,\n reactMain,\n reactApp,\n themeTemplates,\n};\n","import { mkdir, writeFile } from \"node:fs/promises\";\n\nimport path from \"node:path\";\n\nimport type { Framework } from \"../types\";\n\nimport { themeTemplates } from \"./templates\";\n\nconst configureTheme = async (\n directory: string,\n framework: Framework,\n): Promise<void> => {\n const templates = themeTemplates[framework];\n\n await Promise.all(\n Object.entries(templates).map(async ([relativePath, content]) => {\n const filePath = path.join(directory, relativePath);\n\n await mkdir(path.dirname(filePath), {\n recursive: true,\n });\n\n await writeFile(filePath, content, \"utf8\");\n }),\n );\n};\n\nexport { configureTheme };\n","import { access } from \"node:fs/promises\";\n\nimport path from \"node:path\";\n\nconst validateProjectDirectory = async (\n directory: string,\n cwd = process.cwd(),\n): Promise<string> => {\n const root = path.resolve(cwd);\n const target = path.resolve(root, directory);\n\n if (target === root || !target.startsWith(`${root}${path.sep}`)) {\n throw new Error(\"Invalid project directory.\");\n }\n\n try {\n await access(target);\n\n throw new Error(\n `The directory \"${directory}\" already exists. Choose another name.`,\n );\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"already exists\")) {\n throw error;\n }\n\n if (\n error &&\n typeof error === \"object\" &&\n \"code\" in error &&\n error.code === \"ENOENT\"\n ) {\n return target;\n }\n\n throw error;\n }\n};\n\nexport { validateProjectDirectory };\n","import { mkdir, readFile, writeFile } from \"node:fs/promises\";\n\nimport path from \"node:path\";\n\nimport type { Framework } from \"../types\";\n\nconst readIfExists = async (filePath: string) => {\n try {\n return await readFile(filePath, \"utf8\");\n } catch {\n return null;\n }\n};\n\nconst writeIfMissingImport = async (\n filePath: string,\n importStatement: string,\n) => {\n const current = await readIfExists(filePath);\n\n if (current === null) {\n await mkdir(path.dirname(filePath), {\n recursive: true,\n });\n\n await writeFile(filePath, `${importStatement}\\n`, \"utf8\");\n\n return;\n }\n\n if (current.includes(importStatement)) {\n return;\n }\n\n await writeFile(filePath, `${importStatement}\\n\\n${current}`, \"utf8\");\n};\n\nconst prependCssImport = async (filePath: string) => {\n const importStatement = '@import \"tailwindcss\";';\n const current = await readIfExists(filePath);\n\n if (current === null) {\n await mkdir(path.dirname(filePath), {\n recursive: true,\n });\n\n await writeFile(filePath, `${importStatement}\\n`, \"utf8\");\n\n return;\n }\n\n if (current.includes(importStatement)) {\n return;\n }\n\n await writeFile(filePath, `${importStatement}\\n\\n${current}`, \"utf8\");\n};\n\nconst configureNextTailwind = async (directory: string) => {\n const cssPath = path.join(directory, \"src\", \"app\", \"globals.css\");\n\n await prependCssImport(cssPath);\n\n const postcssConfigPath = path.join(directory, \"postcss.config.mjs\");\n\n await writeFile(\n postcssConfigPath,\n `const config = {\n plugins: {\n \"@tailwindcss/postcss\": {},\n },\n};\n\nexport default config;\n`,\n \"utf8\",\n );\n};\n\nconst findTanStackCssPath = async (directory: string) => {\n const rootRoutePath = path.join(directory, \"src\", \"routes\", \"__root.tsx\");\n\n const rootRoute = await readFile(rootRoutePath, \"utf8\");\n\n const cssImportPattern =\n /import\\s+(?:[\\w{}\\s,*]+\\s+from\\s+)?[\"']([^\"']+\\.css(?:\\?url)?)[\"']/g;\n\n const matches = [...rootRoute.matchAll(cssImportPattern)];\n\n for (const match of matches) {\n const importedPath = match[1];\n\n if (!importedPath?.startsWith(\".\")) {\n continue;\n }\n\n const cleanPath = importedPath.replace(/\\?[^/]*$/, \"\");\n\n return path.resolve(path.dirname(rootRoutePath), cleanPath);\n }\n\n // Default stylesheet location used by TanStack Start templates.\n return path.join(directory, \"src\", \"styles.css\");\n};\n\nconst configureTanStackTailwind = async (directory: string) => {\n const cssPath = await findTanStackCssPath(directory);\n\n await prependCssImport(cssPath);\n\n const rootRoutePath = path.join(directory, \"src\", \"routes\", \"__root.tsx\");\n\n const rootRoute = await readFile(rootRoutePath, \"utf8\");\n\n if (!rootRoute.includes(\".css\")) {\n await writeFile(\n rootRoutePath,\n `import \"../styles.css\";\\n${rootRoute}`,\n \"utf8\",\n );\n }\n\n const viteConfigPath = path.join(directory, \"vite.config.ts\");\n\n let viteConfig = await readFile(viteConfigPath, \"utf8\");\n\n if (!viteConfig.includes(\"@tailwindcss/vite\")) {\n viteConfig = `import tailwindcss from \"@tailwindcss/vite\";\\n` + viteConfig;\n }\n\n if (!viteConfig.includes(\"tailwindcss()\")) {\n viteConfig = viteConfig.replace(\n /plugins:\\s*\\[/,\n \"plugins: [\\n tailwindcss(),\",\n );\n }\n\n if (!viteConfig.includes(\"noExternal\")) {\n viteConfig = viteConfig.replace(\n /defineConfig\\(\\s*\\{/,\n `defineConfig({\n ssr: {\n noExternal: [\"@puzzle-ui/ui\", \"@puzzle-ui/theme\"],\n },`,\n );\n }\n\n await writeFile(viteConfigPath, viteConfig, \"utf8\");\n};\n\nconst configureReactTailwind = async (directory: string) => {\n const cssPath = path.join(directory, \"src\", \"index.css\");\n\n await prependCssImport(cssPath);\n\n const viteConfigPath = path.join(directory, \"vite.config.ts\");\n\n let viteConfig = await readFile(viteConfigPath, \"utf8\");\n\n if (!viteConfig.includes(\"@tailwindcss/vite\")) {\n viteConfig = `import tailwindcss from \"@tailwindcss/vite\";\\n` + viteConfig;\n }\n\n if (!viteConfig.includes(\"tailwindcss()\")) {\n viteConfig = viteConfig.replace(\n /plugins:\\s*\\[/,\n \"plugins: [\\n tailwindcss(),\",\n );\n }\n\n await writeFile(viteConfigPath, viteConfig, \"utf8\");\n};\n\nconst configureTailwind = async (directory: string, framework: Framework) => {\n if (framework === \"next\") {\n await configureNextTailwind(directory);\n return;\n }\n\n if (framework === \"tanstack\") {\n await configureTanStackTailwind(directory);\n return;\n }\n\n await configureReactTailwind(directory);\n};\n\nexport { configureTailwind };\n","import type { CommandRunner, Framework, PackageManager } from \"../types\";\n\nconst getTailwindPackages = (framework: Framework) => {\n if (framework === \"next\") {\n return [\n \"tailwindcss@latest\",\n \"@tailwindcss/postcss@latest\",\n \"postcss@latest\",\n ];\n }\n\n return [\"tailwindcss@latest\", \"@tailwindcss/vite@latest\"];\n};\n\nconst installTailwind = async ({\n directory,\n framework,\n packageManager,\n runner,\n}: {\n directory: string;\n framework: Framework;\n packageManager: PackageManager;\n runner: CommandRunner;\n}) => {\n const packages = getTailwindPackages(framework);\n\n if (packageManager === \"bun\") {\n await runner(\"bun\", [\"add\", \"-d\", ...packages], { cwd: directory });\n\n return;\n }\n\n await runner(\"npm\", [\"install\", \"--save-dev\", ...packages], {\n cwd: directory,\n });\n};\n\nexport { installTailwind };\n","import { readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport * as p from \"@clack/prompts\";\n\nimport type { CommandRunner, ProjectOptions } from \"./types\";\nimport { frameworkGenerators } from \"./frameworks\";\nimport { configureTheme } from \"./theme/configure-theme\";\nimport { runCommand } from \"./utils/execute\";\nimport { validateProjectDirectory } from \"./utils/validate-project\";\nimport { PUZZLE_PACKAGES } from \"./constants\";\nimport { configureTailwind } from \"./tailwind/configure-tailwind\";\nimport { installTailwind } from \"./tailwind/install-tailwind\";\n\ntype CreateProjectContext = {\n /** Directory the project directory is resolved from. Defaults to `process.cwd()`. */\n cwd?: string;\n /** Runs external commands. Defaults to spawning a child process. */\n runner?: CommandRunner;\n};\n\nconst installDependencies = async (\n directory: string,\n packageManager: ProjectOptions[\"packageManager\"],\n runner: CommandRunner,\n) => {\n const packages = [...PUZZLE_PACKAGES];\n\n if (packageManager === \"bun\") {\n await runner(\"bun\", [\"add\", ...packages], { cwd: directory });\n return;\n }\n\n await runner(\"npm\", [\"install\", ...packages], { cwd: directory });\n};\n\nconst configureProjectName = async (directory: string, projectName: string) => {\n const packageJsonPath = path.join(directory, \"package.json\");\n\n const packageJson = JSON.parse(await readFile(packageJsonPath, \"utf8\")) as {\n name?: string;\n [key: string]: unknown;\n };\n\n packageJson.name = projectName;\n\n await writeFile(\n packageJsonPath,\n `${JSON.stringify(packageJson, null, 2)}\\n`,\n \"utf8\",\n );\n};\n\nconst createProject = async (\n options: ProjectOptions,\n { cwd = process.cwd(), runner = runCommand }: CreateProjectContext = {},\n) => {\n // Validate before starting the spinner, so nothing is generated or reported\n // as a failed step when the target directory cannot be used.\n const targetDirectory = await validateProjectDirectory(\n options.directory,\n cwd,\n );\n\n const projectName = path.basename(targetDirectory);\n const projectParent = path.dirname(targetDirectory);\n\n const spinner = p.spinner();\n let spinnerActive = false;\n\n const startStep = (message: string) => {\n spinner.start(message);\n spinnerActive = true;\n };\n\n const finishStep = (message: string) => {\n spinner.stop(message);\n spinnerActive = false;\n };\n\n try {\n startStep(\"Generating framework\");\n\n if (options.framework === \"react\") {\n // The Basic React generator writes directly into its target directory.\n await frameworkGenerators.react(\n targetDirectory,\n options.packageManager,\n runner,\n );\n } else {\n // Next.js and TanStack CLI create their own project directory.\n await frameworkGenerators[options.framework](\n projectName,\n options.packageManager,\n runner,\n projectParent,\n );\n }\n\n finishStep(\"Framework generated\");\n\n startStep(\"Configuring Puzzle theme\");\n await configureTheme(targetDirectory, options.framework);\n await configureProjectName(targetDirectory, projectName);\n finishStep(\"Puzzle theme configured\");\n\n if (options.tailwind) {\n startStep(\"Configuring Tailwind CSS\");\n await configureTailwind(targetDirectory, options.framework);\n finishStep(\"Tailwind CSS configured\");\n\n startStep(\"Installing Tailwind CSS\");\n await installTailwind({\n directory: targetDirectory,\n framework: options.framework,\n packageManager: options.packageManager,\n runner,\n });\n finishStep(\"Tailwind CSS installed\");\n }\n\n startStep(\"Installing Puzzle\");\n await installDependencies(targetDirectory, options.packageManager, runner);\n finishStep(\"Puzzle installed\");\n } catch (error) {\n if (spinnerActive) {\n spinner.error(\"Project creation failed\");\n }\n\n throw error;\n }\n\n p.log.success(`Project \"${projectName}\" created successfully.`);\n\n p.outro(\n `Next steps:\\n\\n cd ${path.relative(process.cwd(), targetDirectory) || \".\"}\\n ${options.packageManager} run dev`,\n );\n};\n\nexport { createProject, type CreateProjectContext };\n","#!/usr/bin/env node\n\nimport * as p from \"@clack/prompts\";\n\nimport { getProjectOptions } from \"./prompts\";\n\nimport { createProject } from \"./create-project\";\n\nconst main = async (): Promise<void> => {\n const options = await getProjectOptions();\n\n if (!options) {\n p.cancel(\"Project creation cancelled.\");\n return;\n }\n\n await createProject(options);\n};\n\nmain().catch((error: unknown) => {\n p.log.error(error instanceof Error ? error.message : String(error));\n\n process.exitCode = 1;\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["getExecutor"],"sources":["../src/constants.ts","../src/utils/kebab-case.ts","../src/utils/detect-package-manager.ts","../src/prompts.ts","../src/utils/execute.ts","../src/frameworks/next.ts","../src/frameworks/tanstack.ts","../src/frameworks/react.ts","../src/frameworks/index.ts","../src/frameworks/configure-framework.ts","../src/theme/templates.ts","../src/theme/configure-theme.ts","../src/auth/templates.ts","../src/auth/configure-auth.ts","../src/utils/validate-project.ts","../src/tailwind/configure-tailwind.ts","../src/tailwind/install-tailwind.ts","../src/create-project.ts","../src/index.ts"],"sourcesContent":["import type { Framework } from \"./types\";\n\nexport const PACKAGE_NAME = \"@puzzle-ui/create\";\n\nexport const PUZZLE_PACKAGES = [\n \"@puzzle-ui/ui@latest\",\n \"@puzzle-ui/theme@latest\",\n] as const;\n\nexport const PUZZLE_AUTH_PACKAGES = [\n \"@puzzle-ui/auth@latest\",\n \"@puzzle-ui/fullstack@latest\",\n \"@puzzle-ui/session@latest\",\n] as const;\n\nexport const FRAMEWORKS: {\n value: Framework;\n label: string;\n hint: string;\n}[] = [\n {\n value: \"react\",\n label: \"Basic React Project\",\n hint: \"React + Vite + TypeScript\",\n },\n {\n value: \"tanstack\",\n label: \"TanStack Start\",\n hint: \"Full-stack React framework\",\n },\n {\n value: \"next\",\n label: \"Next.js\",\n hint: \"React framework with App Router\",\n },\n];\n","const toKebabCase = (value: string): string =>\n value\n .normalize(\"NFKD\")\n .replace(/[\\u0300-\\u036f]/g, \"\")\n .replace(/([a-z0-9])([A-Z])/g, \"$1-$2\")\n .replace(/([A-Z])([A-Z][a-z])/g, \"$1-$2\")\n .replace(/[^a-zA-Z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .toLowerCase();\n\nexport { toKebabCase };\n","import type { PackageManager } from \"../types\";\n\nconst detectPackageManager = (\n userAgent = process.env.npm_config_user_agent ?? \"\",\n): PackageManager => {\n const match = userAgent.match(/(?:^|\\s)(bun|pnpm|yarn|npm)\\/[^\\s]+/);\n\n return (match?.[1] as PackageManager | undefined) ?? \"npm\";\n};\n\nexport { detectPackageManager };\n","import * as p from \"@clack/prompts\";\n\nimport { FRAMEWORKS } from \"./constants\";\n\nimport type { Framework, ProjectOptions } from \"./types\";\n\nimport { toKebabCase } from \"./utils/kebab-case\";\n\nimport { detectPackageManager } from \"./utils/detect-package-manager\";\n\nconst getProjectOptions = async (): Promise<ProjectOptions | null> => {\n p.intro(\"Create a Puzzle application\");\n\n const name = await p.text({\n message: \"What is the name of your project?\",\n placeholder: \"my-awesome-app\",\n validate: (value) => {\n if (!value?.trim()) {\n return \"Project name is required.\";\n }\n\n if (!toKebabCase(value)) {\n return \"Please enter a valid project name.\";\n }\n },\n });\n\n if (p.isCancel(name)) {\n return null;\n }\n\n const directory = toKebabCase(name);\n\n const framework = await p.select({\n message: \"Which framework would you like to use?\",\n options: FRAMEWORKS.map((item) => ({\n value: item.value,\n label: item.label,\n hint: item.hint,\n })),\n });\n\n if (p.isCancel(framework)) {\n return null;\n }\n\n const tailwind = await p.confirm({\n message: \"Would you like to install Tailwind CSS?\",\n initialValue: true,\n });\n\n if (p.isCancel(tailwind)) {\n p.cancel(\"Project creation cancelled.\");\n return null;\n }\n\n const auth = await p.confirm({\n message: \"Would you like to add Puzzle Auth?\",\n initialValue: false,\n });\n\n if (p.isCancel(auth)) {\n p.cancel(\"Project creation cancelled.\");\n return null;\n }\n\n return {\n name: directory,\n directory,\n framework: framework as Framework,\n packageManager: detectPackageManager(),\n tailwind,\n auth,\n };\n};\n\nexport { getProjectOptions };\n","import { spawn } from \"node:child_process\";\n\nimport type { CommandRunner } from \"../types\";\n\nconst runCommand: CommandRunner = (command, args, options = {}) =>\n new Promise((resolve, reject) => {\n const child = spawn(command, args, {\n cwd: options.cwd ?? process.cwd(),\n stdio: options.stdio ?? \"inherit\",\n shell: false,\n env: process.env,\n });\n\n child.once(\"error\", reject);\n\n child.once(\"close\", (code, signal) => {\n if (code === 0) {\n resolve();\n return;\n }\n\n reject(\n new Error(\n signal\n ? `${command} terminated with signal ${signal}`\n : `${command} exited with code ${code ?? \"unknown\"}`,\n ),\n );\n });\n });\n\nexport { runCommand };\n","import type { FrameworkGenerator, PackageManager } from \"../types\";\n\nimport { runCommand } from \"../utils/execute\";\n\nconst getExecutor = (packageManager: PackageManager) => {\n if (packageManager === \"bun\") {\n return {\n command: \"bunx\",\n prefix: [],\n };\n }\n\n if (packageManager === \"pnpm\" || packageManager === \"yarn\") {\n return {\n command: packageManager,\n prefix: [\"dlx\"],\n };\n }\n\n return {\n command: \"npx\",\n prefix: [\"--yes\"],\n };\n};\n\nconst createNextProject: FrameworkGenerator = async (\n directory,\n packageManager,\n runner = runCommand,\n cwd,\n) => {\n const args = [\n \"create-next-app@latest\",\n directory,\n \"--ts\",\n \"--app\",\n \"--src-dir\",\n \"--skip-install\",\n \"--disable-git\",\n \"--no-tailwind\",\n \"--yes\",\n `--use-${packageManager}`,\n ];\n\n const executor = getExecutor(packageManager);\n\n await runner(\n executor.command,\n [...executor.prefix, ...args],\n cwd ? { cwd } : undefined,\n );\n};\n\nexport { createNextProject };\n","import type { FrameworkGenerator, PackageManager } from \"../types\";\n\nimport { runCommand } from \"../utils/execute\";\n\nconst getExecutor = (packageManager: PackageManager) => {\n if (packageManager === \"bun\") {\n return {\n command: \"bunx\",\n prefix: [],\n };\n }\n\n if (packageManager === \"pnpm\" || packageManager === \"yarn\") {\n return {\n command: packageManager,\n prefix: [\"dlx\"],\n };\n }\n\n return {\n command: \"npx\",\n prefix: [\"--yes\"],\n };\n};\n\nconst createTanStackProject: FrameworkGenerator = async (\n directory,\n packageManager,\n runner = runCommand,\n cwd,\n) => {\n const args = [\n \"@tanstack/cli@latest\",\n \"create\",\n directory,\n \"--framework\",\n \"React\",\n \"--package-manager\",\n packageManager,\n \"--blank\",\n \"--no-install\",\n \"--no-git\",\n \"--yes\",\n ];\n\n const executor = getExecutor(packageManager);\n\n await runner(\n executor.command,\n [...executor.prefix, ...args],\n cwd ? { cwd } : undefined,\n );\n};\n\nexport { createTanStackProject };\n","import { mkdir, writeFile } from \"node:fs/promises\";\n\nimport path from \"node:path\";\n\nimport type { FrameworkGenerator } from \"../types\";\n\nconst createReactProject: FrameworkGenerator = async (\n directory,\n _packageManager,\n _runner,\n) => {\n await mkdir(path.join(directory, \"src\"), {\n recursive: true,\n });\n\n const packageJson = {\n name: path.basename(directory),\n private: true,\n version: \"0.0.0\",\n type: \"module\",\n scripts: {\n dev: \"vite\",\n build: \"tsc --noEmit -p tsconfig.app.json && vite build\",\n preview: \"vite preview\",\n },\n dependencies: {\n react: \"^19.0.0\",\n \"react-dom\": \"^19.0.0\",\n },\n devDependencies: {\n \"@types/node\": \"latest\",\n \"@types/react\": \"^19.0.0\",\n \"@types/react-dom\": \"^19.0.0\",\n \"@vitejs/plugin-react\": \"latest\",\n typescript: \"latest\",\n vite: \"latest\",\n },\n };\n\n const files: Record<string, string> = {\n \"package.json\": JSON.stringify(packageJson, null, 2),\n\n \"index.html\": `<!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>Puzzle App</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 \"tsconfig.json\": JSON.stringify(\n {\n files: [],\n references: [\n { path: \"./tsconfig.app.json\" },\n { path: \"./tsconfig.node.json\" },\n ],\n },\n null,\n 2,\n ),\n\n \"tsconfig.app.json\": JSON.stringify(\n {\n compilerOptions: {\n tsBuildInfoFile: \"./node_modules/.tmp/tsconfig.app.tsbuildinfo\",\n target: \"ES2022\",\n useDefineForClassFields: true,\n lib: [\"ES2022\", \"DOM\", \"DOM.Iterable\"],\n module: \"ESNext\",\n skipLibCheck: true,\n moduleResolution: \"bundler\",\n allowImportingTsExtensions: true,\n verbatimModuleSyntax: true,\n moduleDetection: \"force\",\n noEmit: true,\n jsx: \"react-jsx\",\n strict: true,\n noUnusedLocals: true,\n noUnusedParameters: true,\n noFallthroughCasesInSwitch: true,\n types: [\"vite/client\"],\n },\n include: [\"src\"],\n },\n null,\n 2,\n ),\n\n \"tsconfig.node.json\": JSON.stringify(\n {\n compilerOptions: {\n tsBuildInfoFile: \"./node_modules/.tmp/tsconfig.node.tsbuildinfo\",\n target: \"ES2023\",\n lib: [\"ES2023\"],\n module: \"ESNext\",\n skipLibCheck: true,\n moduleResolution: \"bundler\",\n allowImportingTsExtensions: true,\n verbatimModuleSyntax: true,\n moduleDetection: \"force\",\n noEmit: true,\n strict: true,\n },\n include: [\"vite.config.ts\"],\n },\n null,\n 2,\n ),\n\n \"vite.config.ts\": `import { defineConfig } from \"vite\";\nimport react from \"@vitejs/plugin-react\";\n\nexport default defineConfig({\n plugins: [react()],\n});`,\n\n \"src/main.tsx\": \"\",\n \"src/App.tsx\": \"\",\n \"src/index.css\": `* {\n box-sizing: border-box;\n}\n\nhtml,\nbody,\n#root {\n min-height: 100%;\n}\n\nbody {\n margin: 0;\n font-family: var(--puzzle-font-family-body, sans-serif);\n}`,\n };\n\n await Promise.all(\n Object.entries(files).map(([file, content]) =>\n writeFile(path.join(directory, file), content, \"utf8\"),\n ),\n );\n};\n\nexport { createReactProject };\n","import { createNextProject } from \"./next\";\nimport { createTanStackProject } from \"./tanstack\";\nimport { createReactProject } from \"./react\";\n\nimport type { Framework, FrameworkGenerator } from \"../types\";\n\nconst frameworkGenerators: Record<Framework, FrameworkGenerator> = {\n next: createNextProject,\n tanstack: createTanStackProject,\n react: createReactProject,\n};\n\nexport {\n createNextProject,\n createTanStackProject,\n createReactProject,\n frameworkGenerators,\n};\n","import { readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { Framework } from \"../types\";\n\nconst getTranspiledPackages = (auth: boolean) => [\n \"@puzzle-ui/ui\",\n \"@puzzle-ui/theme\",\n ...(auth ? [\"@puzzle-ui/fullstack\"] : []),\n];\n\nconst configureNext = async (directory: string, auth: boolean) => {\n const configPath = path.join(directory, \"next.config.ts\");\n const packages = getTranspiledPackages(auth);\n\n const config = `import type { NextConfig } from \"next\";\n\nconst nextConfig: NextConfig = {\n transpilePackages: ${JSON.stringify(packages, null, 4)},\n};\n\nexport default nextConfig;\n`;\n\n await writeFile(configPath, config, \"utf8\");\n};\n\nconst configureTanStack = async (directory: string, auth: boolean) => {\n const configPath = path.join(directory, \"vite.config.ts\");\n\n let config = await readFile(configPath, \"utf8\");\n\n const packages = getTranspiledPackages(auth);\n\n if (!config.includes(\"noExternal\")) {\n config = config.replace(\n /defineConfig\\(\\s*\\{/,\n `defineConfig({\n ssr: {\n noExternal: ${JSON.stringify(packages)},\n },`,\n );\n } else if (auth && !config.includes('\"@puzzle-ui/fullstack\"')) {\n config = config.replace(\n /noExternal:\\s*\\[([^\\]]*)\\]/,\n `noExternal: [$1, \"@puzzle-ui/fullstack\"]`,\n );\n }\n\n await writeFile(configPath, config, \"utf8\");\n};\n\nconst configureFramework = async (\n directory: string,\n framework: Framework,\n auth = false,\n) => {\n if (framework === \"next\") {\n await configureNext(directory, auth);\n return;\n }\n\n if (framework === \"tanstack\") {\n await configureTanStack(directory, auth);\n }\n};\n\nexport { configureFramework };\n","const nextProviders = `\"use client\";\n\nimport type { ReactNode } from \"react\";\n\nimport { Theme } from \"@puzzle-ui/theme\";\n\ntype ProvidersProps = {\n children: ReactNode;\n};\n\nconst Providers = ({ children }: ProvidersProps) => (\n <Theme theme=\"system\">\n {children}\n </Theme>\n);\n\nexport { Providers };\n`;\n\nconst nextLayout = `import \"./globals.css\";\n\nimport type { ReactNode } from \"react\";\n\nimport { Providers } from \"./providers\";\n\ntype RootLayoutProps = {\n children: ReactNode;\n};\n\nconst RootLayout = ({ children }: RootLayoutProps) => (\n <html lang=\"en\">\n <body>\n <Providers>\n {children}\n </Providers>\n </body>\n </html>\n);\n\nexport default RootLayout;\n`;\n\nconst nextPage = `\"use client\";\nimport { Button } from \"@puzzle-ui/ui\";\n\nconst HomePage = () => (\n <main style={{ padding: \"2rem\" }}>\n <h1>Welcome to Puzzle</h1>\n <p>Your new Puzzle application is ready.</p>\n\n <Button onClick={() => console.log(\"Hello, Puzzle!\")}>\n Get started\n </Button>\n </main>\n);\n\nexport default HomePage;\n`;\n\nconst tanstackRootRoute = `import {\n createRootRoute,\n HeadContent,\n Outlet,\n Scripts,\n} from \"@tanstack/react-router\";\n\nimport { Theme } from \"@puzzle-ui/theme\";\n\nconst RootComponent = () => (\n <html lang=\"en\">\n <head>\n <HeadContent />\n </head>\n <body>\n <Theme theme=\"system\">\n <Outlet />\n </Theme>\n <Scripts />\n </body>\n </html>\n);\n\nexport const Route = createRootRoute({\n component: RootComponent,\n});\n`;\n\nconst tanstackIndexRoute = `import { createFileRoute } from \"@tanstack/react-router\";\n\nimport { Button } from \"@puzzle-ui/ui\";\n\nconst HomePage = () => (\n <main style={{ padding: \"2rem\" }}>\n <h1>Welcome to Puzzle</h1>\n <p>Your new Puzzle application is ready.</p>\n\n <Button onClick={() => console.log(\"Hello, Puzzle!\")}>\n Get started\n </Button>\n </main>\n);\n\nexport const Route = createFileRoute(\"/\")({\n component: HomePage,\n});\n`;\n\nconst reactMain = `import React from \"react\";\nimport ReactDOM from \"react-dom/client\";\n\nimport { Theme } from \"@puzzle-ui/theme\";\n\nimport App from \"./App\";\n\nimport \"./index.css\";\n\nReactDOM.createRoot(\n document.getElementById(\"root\")!,\n).render(\n <React.StrictMode>\n <Theme theme=\"system\">\n <App />\n </Theme>\n </React.StrictMode>,\n);\n`;\n\nconst reactApp = `import { Button } from \"@puzzle-ui/ui\";\n\nconst App = () => (\n <main style={{ padding: \"2rem\" }}>\n <h1>Welcome to Puzzle</h1>\n <p>Your new Puzzle application is ready.</p>\n\n <Button onClick={() => console.log(\"Hello, Puzzle!\")}>\n Get started\n </Button>\n </main>\n);\n\nexport default App;\n`;\n\nconst themeTemplates = {\n next: {\n \"src/app/providers.tsx\": nextProviders,\n \"src/app/layout.tsx\": nextLayout,\n \"src/app/page.tsx\": nextPage,\n },\n tanstack: {\n \"src/routes/__root.tsx\": tanstackRootRoute,\n \"src/routes/index.tsx\": tanstackIndexRoute,\n },\n react: {\n \"src/main.tsx\": reactMain,\n \"src/App.tsx\": reactApp,\n },\n} as const;\n\nexport {\n nextProviders,\n nextLayout,\n nextPage,\n tanstackRootRoute,\n tanstackIndexRoute,\n reactMain,\n reactApp,\n themeTemplates,\n};\n","import { mkdir, writeFile } from \"node:fs/promises\";\n\nimport path from \"node:path\";\n\nimport type { Framework } from \"../types\";\n\nimport { themeTemplates } from \"./templates\";\n\nconst configureTheme = async (\n directory: string,\n framework: Framework,\n): Promise<void> => {\n const templates = themeTemplates[framework];\n\n await Promise.all(\n Object.entries(templates).map(async ([relativePath, content]) => {\n const filePath = path.join(directory, relativePath);\n\n await mkdir(path.dirname(filePath), {\n recursive: true,\n });\n\n await writeFile(filePath, content, \"utf8\");\n }),\n );\n};\n\nexport { configureTheme };\n","import type { Framework } from \"../types\";\n\nconst authServer = `import type { AuthServer } from \"@puzzle-ui/fullstack/auth/server\";\n\nlet authServer: AuthServer | null = null;\n\n/**\n * Register the server configured by your application.\n *\n * Create the AuthServer with your own storage adapter, password hasher,\n * rate limiter, session manager, MFA manager and CSRF configuration.\n *\n * Never import this module from browser-facing code.\n */\nexport const configureAuthServer = (server: AuthServer): void => {\n if (authServer && authServer !== server) {\n throw new Error(\"Puzzle Auth has already been configured.\");\n }\n\n authServer = server;\n};\n\n/**\n * Returns null until the application has registered its AuthServer.\n */\nexport const getAuthServer = (): AuthServer | null => authServer;\n`;\n\nconst authBootstrap = `/**\n * Initialize Puzzle Auth once for this server runtime.\n *\n * Configure your storage adapter and security providers here.\n *\n * Example:\n *\n * configureAuthServer(\n * createAuthServer({\n * auth,\n * mfa,\n * stepUp,\n * sessions,\n * cookie,\n * csrf,\n * resolveClientIp,\n * }),\n * );\n *\n * Do not use development-only or in-memory providers in production.\n */\nconst configure = async (): Promise<void> => {\n // TODO: initialize your application-specific AuthServer.\n};\n\nlet initialization: Promise<void> | null = null;\n\nexport const initializePuzzleAuth = (): Promise<void> => {\n if (!initialization) {\n initialization = configure().catch((error: unknown) => {\n initialization = null;\n throw error;\n });\n }\n\n return initialization;\n};\n`;\n\nconst authUnavailableResponse = `const createAuthUnavailableResponse = (): Response =>\n new Response(\n JSON.stringify({\n error: {\n code: \"AUTH_NOT_CONFIGURED\",\n message: \"Puzzle Auth has not been configured by the application.\",\n },\n }),\n {\n status: 503,\n headers: {\n \"Content-Type\": \"application/json; charset=utf-8\",\n \"Cache-Control\": \"no-store\",\n Pragma: \"no-cache\",\n },\n },\n );\n\nexport { createAuthUnavailableResponse };\n`;\n\nconst nextProviders = `\"use client\";\n\nimport type { ReactNode } from \"react\";\n\nimport { Theme } from \"@puzzle-ui/theme\";\nimport { AuthProvider } from \"@puzzle-ui/fullstack/auth/client\";\n\ntype ProvidersProps = {\n children: ReactNode;\n};\n\nconst Providers = ({ children }: ProvidersProps) => (\n <Theme theme=\"system\">\n <AuthProvider options={{ basePath: \"/api/auth\" }}>\n {children}\n </AuthProvider>\n </Theme>\n);\n\nexport { Providers };\n`;\n\nconst nextSignIn = `\"use client\";\n\nimport { AuthExperience } from \"@puzzle-ui/fullstack/auth/client\";\n\nconst SignInPage = () => <AuthExperience mode=\"sign-in\" />;\n\nexport default SignInPage;\n`;\n\nconst nextSignUp = `\"use client\";\n\nimport { AuthExperience } from \"@puzzle-ui/fullstack/auth/client\";\n\nconst SignUpPage = () => <AuthExperience mode=\"sign-up\" />;\n\nexport default SignUpPage;\n`;\n\nconst nextAuthRoute = `import { createNextAuthHandler } from \"@puzzle-ui/fullstack/auth/next\";\n\nimport { getAuthServer } from \"../../../../lib/auth/server\";\nimport { initializePuzzleAuth } from \"../../../../lib/auth/bootstrap\";\nimport { createAuthUnavailableResponse } from \"../../../../lib/auth/unavailable\";\n\nconst handle = async (request: Request): Promise<Response> => {\n await initializePuzzleAuth();\n\n const auth = getAuthServer();\n\n if (!auth) {\n return createAuthUnavailableResponse();\n }\n\n const handlers = createNextAuthHandler({ auth });\n\n return request.method.toUpperCase() === \"GET\"\n ? handlers.GET(request)\n : handlers.POST(request);\n};\n\nexport { handle as GET, handle as POST };\n`;\n\nconst tanstackRoot = `import {\n createRootRoute,\n HeadContent,\n Outlet,\n Scripts,\n} from \"@tanstack/react-router\";\n\nimport { Theme } from \"@puzzle-ui/theme\";\nimport { AuthProvider } from \"@puzzle-ui/fullstack/auth/client\";\n\nconst RootComponent = () => (\n <html lang=\"en\">\n <head>\n <HeadContent />\n </head>\n <body>\n <Theme theme=\"system\">\n <AuthProvider options={{ basePath: \"/api/auth\" }}>\n <Outlet />\n </AuthProvider>\n </Theme>\n <Scripts />\n </body>\n </html>\n);\n\nexport const Route = createRootRoute({\n component: RootComponent,\n});\n`;\n\nconst tanstackSignIn = `import { createFileRoute } from \"@tanstack/react-router\";\n\nimport { AuthExperience } from \"@puzzle-ui/fullstack/auth/client\";\n\nconst SignInPage = () => <AuthExperience mode=\"sign-in\" />;\n\nexport const Route = createFileRoute(\"/sign-in\")({\n component: SignInPage,\n});\n`;\n\nconst tanstackSignUp = `import { createFileRoute } from \"@tanstack/react-router\";\n\nimport { AuthExperience } from \"@puzzle-ui/fullstack/auth/client\";\n\nconst SignUpPage = () => <AuthExperience mode=\"sign-up\" />;\n\nexport const Route = createFileRoute(\"/sign-up\")({\n component: SignUpPage,\n});\n`;\n\nconst tanstackAuthRoute = `import { createFileRoute } from \"@tanstack/react-router\";\n\nimport { createTanStackAuthHandler } from \"@puzzle-ui/fullstack/auth/tanstack\";\n\nimport { getAuthServer } from \"../../../lib/auth/server\";\nimport { initializePuzzleAuth } from \"../../../lib/auth/bootstrap\";\nimport { createAuthUnavailableResponse } from \"../../../lib/auth/unavailable\";\n\nconst handle = async (request: Request): Promise<Response> => {\n await initializePuzzleAuth();\n\n const auth = getAuthServer();\n\n if (!auth) {\n return createAuthUnavailableResponse();\n }\n\n return createTanStackAuthHandler({ auth })(request);\n};\n\nexport const Route = createFileRoute(\"/api/auth/$\")({\n server: {\n handlers: {\n GET: ({ request }) => handle(request),\n POST: ({ request }) => handle(request),\n },\n },\n});\n`;\n\nconst reactMain = `import React from \"react\";\nimport ReactDOM from \"react-dom/client\";\n\nimport { Theme } from \"@puzzle-ui/theme\";\nimport { AuthProvider } from \"@puzzle-ui/fullstack/auth/client\";\n\nimport App from \"./App\";\n\nimport \"./index.css\";\n\nReactDOM.createRoot(\n document.getElementById(\"root\")!,\n).render(\n <React.StrictMode>\n <Theme theme=\"system\">\n <AuthProvider options={{ basePath: \"/api/auth\" }}>\n <App />\n </AuthProvider>\n </Theme>\n </React.StrictMode>,\n);\n`;\n\nconst reactSignIn = `import { AuthExperience } from \"@puzzle-ui/fullstack/auth/client\";\n\nexport const SignInPage = () => <AuthExperience mode=\"sign-in\" />;\n`;\n\nconst reactSignUp = `import { AuthExperience } from \"@puzzle-ui/fullstack/auth/client\";\n\nexport const SignUpPage = () => <AuthExperience mode=\"sign-up\" />;\n`;\n\nconst authTemplates: Record<Framework, Record<string, string>> = {\n next: {\n \"src/app/providers.tsx\": nextProviders,\n \"src/app/sign-in/page.tsx\": nextSignIn,\n \"src/app/sign-up/page.tsx\": nextSignUp,\n \"src/app/api/auth/[...auth]/route.ts\": nextAuthRoute,\n \"src/lib/auth/server.ts\": authServer,\n \"src/lib/auth/bootstrap.ts\": authBootstrap,\n \"src/lib/auth/unavailable.ts\": authUnavailableResponse,\n },\n tanstack: {\n \"src/routes/__root.tsx\": tanstackRoot,\n \"src/routes/sign-in.tsx\": tanstackSignIn,\n \"src/routes/sign-up.tsx\": tanstackSignUp,\n \"src/routes/api/auth/$.ts\": tanstackAuthRoute,\n \"src/lib/auth/server.ts\": authServer,\n \"src/lib/auth/bootstrap.ts\": authBootstrap,\n \"src/lib/auth/unavailable.ts\": authUnavailableResponse,\n },\n react: {\n \"src/main.tsx\": reactMain,\n \"src/auth/sign-in.tsx\": reactSignIn,\n \"src/auth/sign-up.tsx\": reactSignUp,\n },\n};\n\nexport { authTemplates };\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { Framework } from \"../types\";\n\nimport { authTemplates } from \"./templates\";\n\nconst configureAuth = async (\n directory: string,\n framework: Framework,\n): Promise<void> => {\n const templates = authTemplates[framework];\n\n await Promise.all(\n Object.entries(templates).map(async ([relativePath, content]) => {\n const filePath = path.join(directory, relativePath);\n\n await mkdir(path.dirname(filePath), {\n recursive: true,\n });\n\n await writeFile(filePath, content, \"utf8\");\n }),\n );\n};\n\nexport { configureAuth };\n","import { access } from \"node:fs/promises\";\n\nimport path from \"node:path\";\n\nconst validateProjectDirectory = async (\n directory: string,\n cwd = process.cwd(),\n): Promise<string> => {\n const root = path.resolve(cwd);\n const target = path.resolve(root, directory);\n\n if (target === root || !target.startsWith(`${root}${path.sep}`)) {\n throw new Error(\"Invalid project directory.\");\n }\n\n try {\n await access(target);\n\n throw new Error(\n `The directory \"${directory}\" already exists. Choose another name.`,\n );\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"already exists\")) {\n throw error;\n }\n\n if (\n error &&\n typeof error === \"object\" &&\n \"code\" in error &&\n error.code === \"ENOENT\"\n ) {\n return target;\n }\n\n throw error;\n }\n};\n\nexport { validateProjectDirectory };\n","import { mkdir, readFile, writeFile } from \"node:fs/promises\";\n\nimport path from \"node:path\";\n\nimport type { Framework } from \"../types\";\n\nconst readIfExists = async (filePath: string) => {\n try {\n return await readFile(filePath, \"utf8\");\n } catch {\n return null;\n }\n};\n\nconst writeIfMissingImport = async (\n filePath: string,\n importStatement: string,\n) => {\n const current = await readIfExists(filePath);\n\n if (current === null) {\n await mkdir(path.dirname(filePath), {\n recursive: true,\n });\n\n await writeFile(filePath, `${importStatement}\\n`, \"utf8\");\n\n return;\n }\n\n if (current.includes(importStatement)) {\n return;\n }\n\n await writeFile(filePath, `${importStatement}\\n\\n${current}`, \"utf8\");\n};\n\nconst prependCssImport = async (filePath: string) => {\n const importStatement = '@import \"tailwindcss\";';\n const current = await readIfExists(filePath);\n\n if (current === null) {\n await mkdir(path.dirname(filePath), {\n recursive: true,\n });\n\n await writeFile(filePath, `${importStatement}\\n`, \"utf8\");\n\n return;\n }\n\n if (current.includes(importStatement)) {\n return;\n }\n\n await writeFile(filePath, `${importStatement}\\n\\n${current}`, \"utf8\");\n};\n\nconst configureNextTailwind = async (directory: string) => {\n const cssPath = path.join(directory, \"src\", \"app\", \"globals.css\");\n\n await prependCssImport(cssPath);\n\n const postcssConfigPath = path.join(directory, \"postcss.config.mjs\");\n\n await writeFile(\n postcssConfigPath,\n `const config = {\n plugins: {\n \"@tailwindcss/postcss\": {},\n },\n};\n\nexport default config;\n`,\n \"utf8\",\n );\n};\n\nconst findTanStackCssPath = async (directory: string) => {\n const rootRoutePath = path.join(directory, \"src\", \"routes\", \"__root.tsx\");\n\n const rootRoute = await readFile(rootRoutePath, \"utf8\");\n\n const cssImportPattern =\n /import\\s+(?:[\\w{}\\s,*]+\\s+from\\s+)?[\"']([^\"']+\\.css(?:\\?url)?)[\"']/g;\n\n const matches = [...rootRoute.matchAll(cssImportPattern)];\n\n for (const match of matches) {\n const importedPath = match[1];\n\n if (!importedPath?.startsWith(\".\")) {\n continue;\n }\n\n const cleanPath = importedPath.replace(/\\?[^/]*$/, \"\");\n\n return path.resolve(path.dirname(rootRoutePath), cleanPath);\n }\n\n // Default stylesheet location used by TanStack Start templates.\n return path.join(directory, \"src\", \"styles.css\");\n};\n\nconst configureTanStackTailwind = async (directory: string) => {\n const cssPath = await findTanStackCssPath(directory);\n\n await prependCssImport(cssPath);\n\n const rootRoutePath = path.join(directory, \"src\", \"routes\", \"__root.tsx\");\n\n const rootRoute = await readFile(rootRoutePath, \"utf8\");\n\n if (!rootRoute.includes(\".css\")) {\n await writeFile(\n rootRoutePath,\n `import \"../styles.css\";\\n${rootRoute}`,\n \"utf8\",\n );\n }\n\n const viteConfigPath = path.join(directory, \"vite.config.ts\");\n\n let viteConfig = await readFile(viteConfigPath, \"utf8\");\n\n if (!viteConfig.includes(\"@tailwindcss/vite\")) {\n viteConfig = `import tailwindcss from \"@tailwindcss/vite\";\\n` + viteConfig;\n }\n\n if (!viteConfig.includes(\"tailwindcss()\")) {\n viteConfig = viteConfig.replace(\n /plugins:\\s*\\[/,\n \"plugins: [\\n tailwindcss(),\",\n );\n }\n\n if (!viteConfig.includes(\"noExternal\")) {\n viteConfig = viteConfig.replace(\n /defineConfig\\(\\s*\\{/,\n `defineConfig({\n ssr: {\n noExternal: [\"@puzzle-ui/ui\", \"@puzzle-ui/theme\"],\n },`,\n );\n }\n\n await writeFile(viteConfigPath, viteConfig, \"utf8\");\n};\n\nconst configureReactTailwind = async (directory: string) => {\n const cssPath = path.join(directory, \"src\", \"index.css\");\n\n await prependCssImport(cssPath);\n\n const viteConfigPath = path.join(directory, \"vite.config.ts\");\n\n let viteConfig = await readFile(viteConfigPath, \"utf8\");\n\n if (!viteConfig.includes(\"@tailwindcss/vite\")) {\n viteConfig = `import tailwindcss from \"@tailwindcss/vite\";\\n` + viteConfig;\n }\n\n if (!viteConfig.includes(\"tailwindcss()\")) {\n viteConfig = viteConfig.replace(\n /plugins:\\s*\\[/,\n \"plugins: [\\n tailwindcss(),\",\n );\n }\n\n await writeFile(viteConfigPath, viteConfig, \"utf8\");\n};\n\nconst configureTailwind = async (directory: string, framework: Framework) => {\n if (framework === \"next\") {\n await configureNextTailwind(directory);\n return;\n }\n\n if (framework === \"tanstack\") {\n await configureTanStackTailwind(directory);\n return;\n }\n\n await configureReactTailwind(directory);\n};\n\nexport { configureTailwind };\n","import type { CommandRunner, Framework, PackageManager } from \"../types\";\n\nconst getTailwindPackages = (framework: Framework) => {\n if (framework === \"next\") {\n return [\n \"tailwindcss@latest\",\n \"@tailwindcss/postcss@latest\",\n \"postcss@latest\",\n ];\n }\n\n return [\"tailwindcss@latest\", \"@tailwindcss/vite@latest\"];\n};\n\nconst getInstallArguments = (\n packageManager: PackageManager,\n packages: string[],\n) => {\n if (packageManager === \"npm\") {\n return [\"install\", \"--save-dev\", ...packages];\n }\n\n if (packageManager === \"yarn\") {\n return [\"add\", \"--dev\", ...packages];\n }\n\n return [\"add\", \"-D\", ...packages];\n};\n\nconst installTailwind = async ({\n directory,\n framework,\n packageManager,\n runner,\n}: {\n directory: string;\n framework: Framework;\n packageManager: PackageManager;\n runner: CommandRunner;\n}) => {\n const packages = getTailwindPackages(framework);\n const args = getInstallArguments(packageManager, packages);\n\n await runner(packageManager, args, {\n cwd: directory,\n });\n};\n\nexport { installTailwind };\n","import { readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport * as p from \"@clack/prompts\";\n\nimport type { CommandRunner, ProjectOptions } from \"./types\";\n\nimport { frameworkGenerators } from \"./frameworks\";\nimport { configureFramework } from \"./frameworks/configure-framework\";\nimport { configureTheme } from \"./theme/configure-theme\";\nimport { configureAuth } from \"./auth/configure-auth\";\nimport { runCommand } from \"./utils/execute\";\nimport { validateProjectDirectory } from \"./utils/validate-project\";\n\nimport { PUZZLE_PACKAGES, PUZZLE_AUTH_PACKAGES } from \"./constants\";\n\nimport { configureTailwind } from \"./tailwind/configure-tailwind\";\nimport { installTailwind } from \"./tailwind/install-tailwind\";\n\ntype CreateProjectContext = {\n cwd?: string;\n runner?: CommandRunner;\n};\n\nconst installDependencies = async (\n directory: string,\n packageManager: ProjectOptions[\"packageManager\"],\n auth: boolean,\n runner: CommandRunner,\n) => {\n const packages = [...PUZZLE_PACKAGES, ...(auth ? PUZZLE_AUTH_PACKAGES : [])];\n\n const args =\n packageManager === \"npm\" ? [\"install\", ...packages] : [\"add\", ...packages];\n\n await runner(packageManager, args, {\n cwd: directory,\n });\n};\n\nconst configureProjectName = async (directory: string, projectName: string) => {\n const packageJsonPath = path.join(directory, \"package.json\");\n\n const packageJson = JSON.parse(await readFile(packageJsonPath, \"utf8\")) as {\n name?: string;\n [key: string]: unknown;\n };\n\n packageJson.name = projectName;\n\n await writeFile(\n packageJsonPath,\n `${JSON.stringify(packageJson, null, 2)}\\n`,\n \"utf8\",\n );\n};\n\nconst createProject = async (\n options: ProjectOptions,\n { cwd = process.cwd(), runner = runCommand }: CreateProjectContext = {},\n) => {\n const targetDirectory = await validateProjectDirectory(\n options.directory,\n cwd,\n );\n\n const projectName = path.basename(targetDirectory);\n const projectParent = path.dirname(targetDirectory);\n\n const spinner = p.spinner();\n let spinnerActive = false;\n\n const startStep = (message: string) => {\n spinner.start(message);\n spinnerActive = true;\n };\n\n const finishStep = (message: string) => {\n spinner.stop(message);\n spinnerActive = false;\n };\n\n try {\n startStep(\"Generating framework\");\n\n if (options.framework === \"react\") {\n await frameworkGenerators.react(\n targetDirectory,\n options.packageManager,\n runner,\n );\n } else {\n await frameworkGenerators[options.framework](\n projectName,\n options.packageManager,\n runner,\n projectParent,\n );\n }\n\n finishStep(\"Framework generated\");\n\n startStep(\"Configuring framework\");\n\n await configureFramework(targetDirectory, options.framework, options.auth);\n\n finishStep(\"Framework configured\");\n\n startStep(\"Configuring Puzzle theme\");\n\n await configureTheme(targetDirectory, options.framework);\n await configureProjectName(targetDirectory, projectName);\n\n finishStep(\"Puzzle theme configured\");\n\n if (options.auth) {\n startStep(\"Configuring Puzzle Auth\");\n\n await configureAuth(targetDirectory, options.framework);\n\n finishStep(\"Puzzle Auth configured\");\n }\n\n if (options.tailwind) {\n startStep(\"Configuring Tailwind CSS\");\n\n await configureTailwind(targetDirectory, options.framework);\n\n finishStep(\"Tailwind CSS configured\");\n\n startStep(\"Installing Tailwind CSS\");\n\n await installTailwind({\n directory: targetDirectory,\n framework: options.framework,\n packageManager: options.packageManager,\n runner,\n });\n\n finishStep(\"Tailwind CSS installed\");\n }\n\n startStep(\"Installing Puzzle\");\n\n await installDependencies(\n targetDirectory,\n options.packageManager,\n options.auth,\n runner,\n );\n\n finishStep(options.auth ? \"Puzzle and Auth installed\" : \"Puzzle installed\");\n } catch (error) {\n if (spinnerActive) {\n spinner.error(\"Project creation failed\");\n }\n\n throw error;\n }\n\n p.log.success(`Project \"${projectName}\" created successfully.`);\n\n p.outro(\n `Next steps:\\n\\n cd ${path.relative(cwd, targetDirectory) || \".\"}\\n ${options.packageManager} run dev`,\n );\n};\n\nexport { createProject, type CreateProjectContext };\n","#!/usr/bin/env node\n\nimport * as p from \"@clack/prompts\";\n\nimport { getProjectOptions } from \"./prompts\";\n\nimport { createProject } from \"./create-project\";\n\nconst main = async (): Promise<void> => {\n const options = await getProjectOptions();\n\n if (!options) {\n p.cancel(\"Project creation cancelled.\");\n return;\n }\n\n await createProject(options);\n};\n\nmain().catch((error: unknown) => {\n p.log.error(error instanceof Error ? error.message : String(error));\n\n process.exitCode = 1;\n});\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,12 @@
1
1
  {
2
2
  "name": "@puzzle-ui/create",
3
- "version": "0.4.0",
4
- "description": "Create Beautiful React applications fast with Puzzle UI",
3
+ "version": "0.5.1",
4
+ "description": "Create React applications with Puzzle UI.",
5
+ "homepage": "https://puzzle-ui.com",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/senorprogramador/puzzle.git"
9
+ },
5
10
  "license": "MIT",
6
11
  "type": "module",
7
12
  "bin": {
@@ -11,6 +16,13 @@
11
16
  "dist",
12
17
  "README.md"
13
18
  ],
19
+ "keywords": [
20
+ "puzzle-ui",
21
+ "react",
22
+ "create",
23
+ "scaffolding",
24
+ "cli"
25
+ ],
14
26
  "engines": {
15
27
  "node": ">=20.19.0"
16
28
  },
@@ -27,7 +39,7 @@
27
39
  "devDependencies": {
28
40
  "@types/node": "^26.0.0",
29
41
  "tsdown": "^0.23.1",
30
- "typescript": "^6.0.3",
42
+ "typescript": "^7.0.2",
31
43
  "vitest": "^5.1.0"
32
44
  },
33
45
  "publishConfig": {