@docubook/create 1.9.1 → 1.11.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.
Files changed (129) hide show
  1. package/README.md +1 -3
  2. package/package.json +4 -5
  3. package/src/cli/program.js +32 -0
  4. package/src/cli/promptHandler.js +73 -0
  5. package/src/dist/LICENSE +21 -0
  6. package/src/dist/README.md +37 -0
  7. package/src/dist/app/docs/[[...slug]]/page.tsx +105 -0
  8. package/src/dist/app/docs/layout.tsx +16 -0
  9. package/src/dist/app/error.tsx +44 -0
  10. package/src/dist/app/layout.tsx +96 -0
  11. package/src/dist/app/not-found.tsx +19 -0
  12. package/src/dist/app/page.tsx +96 -0
  13. package/src/dist/components/GithubStart.tsx +44 -0
  14. package/src/dist/components/Sponsor.tsx +69 -0
  15. package/src/dist/components/anchor.tsx +84 -0
  16. package/src/dist/components/contexts/theme-provider.tsx +9 -0
  17. package/src/dist/components/docs-breadcrumb.tsx +47 -0
  18. package/src/dist/components/docs-menu.tsx +45 -0
  19. package/src/dist/components/edit-on-github.tsx +33 -0
  20. package/src/dist/components/footer.tsx +85 -0
  21. package/src/dist/components/leftbar.tsx +95 -0
  22. package/src/dist/components/markdown/AccordionMdx.tsx +47 -0
  23. package/src/dist/components/markdown/ButtonMdx.tsx +52 -0
  24. package/src/dist/components/markdown/CardGroupMdx.tsx +28 -0
  25. package/src/dist/components/markdown/CardMdx.tsx +41 -0
  26. package/src/dist/components/markdown/CopyMdx.tsx +33 -0
  27. package/src/dist/components/markdown/ImageMdx.tsx +25 -0
  28. package/src/dist/components/markdown/KeyboardMdx.tsx +102 -0
  29. package/src/dist/components/markdown/LinkMdx.tsx +14 -0
  30. package/src/dist/components/markdown/NoteMdx.tsx +52 -0
  31. package/src/dist/components/markdown/OutletMdx.tsx +29 -0
  32. package/src/dist/components/markdown/PreMdx.tsx +19 -0
  33. package/src/dist/components/markdown/ReleaseMdx.tsx +109 -0
  34. package/src/dist/components/markdown/StepperMdx.tsx +41 -0
  35. package/src/dist/components/markdown/TooltipsMdx.tsx +28 -0
  36. package/src/dist/components/markdown/YoutubeMdx.tsx +22 -0
  37. package/src/dist/components/markdown/mdx-provider.tsx +29 -0
  38. package/src/dist/components/mob-toc.tsx +128 -0
  39. package/src/dist/components/navbar.tsx +87 -0
  40. package/src/dist/components/pagination.tsx +49 -0
  41. package/src/dist/components/scroll-to-top.tsx +86 -0
  42. package/src/dist/components/search.tsx +214 -0
  43. package/src/dist/components/sublink.tsx +133 -0
  44. package/src/dist/components/theme-toggle.tsx +71 -0
  45. package/src/dist/components/toc-observer.tsx +264 -0
  46. package/src/dist/components/toc.tsx +27 -0
  47. package/src/dist/components/typography.tsx +9 -0
  48. package/src/dist/components/ui/accordion.tsx +58 -0
  49. package/src/dist/components/ui/animated-shiny-text.tsx +40 -0
  50. package/src/dist/components/ui/aurora.tsx +45 -0
  51. package/src/dist/components/ui/avatar.tsx +50 -0
  52. package/src/dist/components/ui/badge.tsx +37 -0
  53. package/src/dist/components/ui/breadcrumb.tsx +115 -0
  54. package/src/dist/components/ui/button.tsx +57 -0
  55. package/src/dist/components/ui/card.tsx +76 -0
  56. package/src/dist/components/ui/collapsible.tsx +11 -0
  57. package/src/dist/components/ui/command.tsx +153 -0
  58. package/src/dist/components/ui/dialog.tsx +124 -0
  59. package/src/dist/components/ui/dropdown-menu.tsx +200 -0
  60. package/src/dist/components/ui/icon-cloud.tsx +324 -0
  61. package/src/dist/components/ui/input.tsx +25 -0
  62. package/src/dist/components/ui/interactive-hover-button.tsx +35 -0
  63. package/src/dist/components/ui/popover.tsx +33 -0
  64. package/src/dist/components/ui/scroll-area.tsx +48 -0
  65. package/src/dist/components/ui/separator.tsx +30 -0
  66. package/src/dist/components/ui/sheet.tsx +140 -0
  67. package/src/dist/components/ui/shine-border.tsx +64 -0
  68. package/src/dist/components/ui/skeleton.tsx +15 -0
  69. package/src/dist/components/ui/sonner.tsx +31 -0
  70. package/src/dist/components/ui/table.tsx +117 -0
  71. package/src/dist/components/ui/tabs.tsx +55 -0
  72. package/src/dist/components/ui/toggle-group.tsx +61 -0
  73. package/src/dist/components/ui/toggle.tsx +46 -0
  74. package/src/dist/components.json +17 -0
  75. package/src/dist/contents/docs/getting-started/changelog/index.mdx +512 -0
  76. package/src/dist/contents/docs/getting-started/components/accordion/index.mdx +72 -0
  77. package/src/dist/contents/docs/getting-started/components/button/index.mdx +42 -0
  78. package/src/dist/contents/docs/getting-started/components/card/index.mdx +70 -0
  79. package/src/dist/contents/docs/getting-started/components/card-group/index.mdx +49 -0
  80. package/src/dist/contents/docs/getting-started/components/code-block/index.mdx +41 -0
  81. package/src/dist/contents/docs/getting-started/components/custom/index.mdx +38 -0
  82. package/src/dist/contents/docs/getting-started/components/image/index.mdx +37 -0
  83. package/src/dist/contents/docs/getting-started/components/index.mdx +9 -0
  84. package/src/dist/contents/docs/getting-started/components/keyboard/index.mdx +117 -0
  85. package/src/dist/contents/docs/getting-started/components/link/index.mdx +34 -0
  86. package/src/dist/contents/docs/getting-started/components/note/index.mdx +46 -0
  87. package/src/dist/contents/docs/getting-started/components/release-note/index.mdx +130 -0
  88. package/src/dist/contents/docs/getting-started/components/stepper/index.mdx +47 -0
  89. package/src/dist/contents/docs/getting-started/components/tabs/index.mdx +70 -0
  90. package/src/dist/contents/docs/getting-started/components/tooltips/index.mdx +22 -0
  91. package/src/dist/contents/docs/getting-started/components/youtube/index.mdx +21 -0
  92. package/src/dist/contents/docs/getting-started/customize/index.mdx +94 -0
  93. package/src/dist/contents/docs/getting-started/installation/index.mdx +84 -0
  94. package/src/dist/contents/docs/getting-started/introduction/index.mdx +50 -0
  95. package/src/dist/contents/docs/getting-started/project-structure/index.mdx +87 -0
  96. package/src/dist/contents/docs/getting-started/quick-start-guide/index.mdx +127 -0
  97. package/src/dist/docu.json +100 -0
  98. package/src/dist/hooks/index.ts +2 -0
  99. package/src/dist/hooks/useActiveSection.ts +68 -0
  100. package/src/dist/hooks/useScrollPosition.ts +28 -0
  101. package/src/dist/lib/markdown.ts +244 -0
  102. package/src/dist/lib/routes-config.ts +28 -0
  103. package/src/dist/lib/toc.ts +9 -0
  104. package/src/dist/lib/utils.ts +80 -0
  105. package/src/dist/next-env.d.ts +5 -0
  106. package/src/dist/next.config.mjs +14 -0
  107. package/src/dist/package.json +58 -0
  108. package/src/dist/postcss.config.js +6 -0
  109. package/src/dist/public/favicon.ico +0 -0
  110. package/src/dist/public/images/docu.svg +6 -0
  111. package/src/dist/public/images/example-img.png +0 -0
  112. package/src/dist/public/images/img-playground.png +0 -0
  113. package/src/dist/public/images/new-editor.png +0 -0
  114. package/src/dist/public/images/og-image.png +0 -0
  115. package/src/dist/public/images/release-note.png +0 -0
  116. package/src/dist/public/images/snippet.png +0 -0
  117. package/src/dist/public/images/vercel.png +0 -0
  118. package/src/dist/public/images/view-changelog.png +0 -0
  119. package/src/dist/styles/editor.css +57 -0
  120. package/src/dist/styles/globals.css +156 -0
  121. package/src/dist/styles/syntax.css +100 -0
  122. package/src/dist/tailwind.config.ts +112 -0
  123. package/src/dist/tsconfig.json +26 -0
  124. package/src/index.js +19 -0
  125. package/src/installer/projectInstaller.js +125 -0
  126. package/src/utils/display.js +83 -0
  127. package/src/utils/logger.js +11 -0
  128. package/src/utils/packageManager.js +54 -0
  129. package/create.js +0 -211
@@ -0,0 +1,156 @@
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
4
+
5
+ @import url("../styles/syntax.css");
6
+ @import url("../styles/editor.css");
7
+
8
+ /* ocean */
9
+ @layer base {
10
+ :root {
11
+ --background: 210 60% 97%; /* Lighter sky blue */
12
+ --foreground: 220 30% 10%; /* Deep navy */
13
+ --card: 210 50% 99%; /* Almost white blue */
14
+ --card-foreground: 220 30% 10%;
15
+ --popover: 210 50% 99%;
16
+ --popover-foreground: 220 30% 10%;
17
+ --primary: 220 85% 55%; /* Vibrant azure blue */
18
+ --primary-foreground: 210 60% 97%;
19
+ --secondary: 220 40% 80%; /* Softer sky blue */
20
+ --secondary-foreground: 220 30% 10%;
21
+ --muted: 220 40% 80%;
22
+ --muted-foreground: 220 30% 30%; /* Deeper steel blue */
23
+ --accent: 200 75% 38%; /* Stronger ocean blue */
24
+ --accent-foreground: 0 0% 100%; /* Pure white */
25
+ --destructive: 0 70% 50%; /* More vivid red */
26
+ --destructive-foreground: 220 30% 95%; /* Lightened foreground */
27
+ --border: 220 20% 85%; /* Slightly darker grey-blue */
28
+ --input: 220 20% 85%;
29
+ --ring: 220 50% 50%; /* More noticeable blue ring */
30
+ --radius: 0.5rem;
31
+ --chart-1: 210 65% 45%; /* Classic blue */
32
+ --chart-2: 220 45% 60%; /* Softer sky */
33
+ --chart-3: 220 75% 45%; /* Azure blue */
34
+ --chart-4: 200 65% 50%; /* Ocean blue */
35
+ --chart-5: 240 35% 35%; /* Deeper teal */
36
+ --line-number-color: rgba(0, 0, 0, 0.05);
37
+ }
38
+
39
+ .dark {
40
+ --background: 220 20% 8%; /* Deeper midnight navy */
41
+ --foreground: 220 85% 92%; /* Brighter sky blue */
42
+ --card: 220 20% 10%; /* Slightly darker midnight */
43
+ --card-foreground: 220 85% 92%;
44
+ --popover: 220 20% 10%;
45
+ --popover-foreground: 220 85% 92%;
46
+ --primary: 210 75% 65%; /* Softer but bright blue */
47
+ --primary-foreground: 220 20% 8%;
48
+ --secondary: 220 35% 12%; /* Darker steel blue */
49
+ --secondary-foreground: 220 85% 92%;
50
+ --muted: 220 35% 12%;
51
+ --muted-foreground: 210 25% 80%; /* Pale navy */
52
+ --accent: 220 85% 55%; /* Vibrant azure blue */
53
+ --accent-foreground: 220 85% 92%;
54
+ --destructive: 0 75% 50%; /* More noticeable red */
55
+ --destructive-foreground: 220 85% 92%;
56
+ --border: 220 35% 12%; /* Darker steel blue */
57
+ --input: 220 35% 12%;
58
+ --ring: 220 65% 55%; /* Vivid blue ring */
59
+ --chart-1: 210 65% 45%; /* Classic blue */
60
+ --chart-2: 220 45% 60%; /* Softer sky */
61
+ --chart-3: 220 75% 45%; /* Azure blue */
62
+ --chart-4: 200 65% 50%; /* Ocean blue */
63
+ --chart-5: 240 35% 35%; /* Deeper teal */
64
+ --line-number-color: rgba(255, 255, 255, 0.05);
65
+ }
66
+ }
67
+
68
+ @layer base {
69
+ * {
70
+ @apply border-border;
71
+ }
72
+
73
+ body {
74
+ @apply bg-background text-foreground;
75
+ }
76
+ }
77
+
78
+ .prose {
79
+ margin: 0 !important;
80
+ }
81
+
82
+ pre {
83
+ padding: 2px 0 !important;
84
+ width: inherit !important;
85
+ overflow-x: auto;
86
+ }
87
+
88
+ pre>code {
89
+ display: grid;
90
+ max-width: inherit !important;
91
+ padding: 14px 0 !important;
92
+ }
93
+
94
+ .code-line {
95
+ padding: 0.75px 16px;
96
+ @apply border-l-2 border-transparent
97
+ }
98
+
99
+ .line-number::before {
100
+ display: inline-block;
101
+ width: 1rem;
102
+ margin-right: 22px;
103
+ margin-left: -2px;
104
+ color: rgb(110, 110, 110);
105
+ content: attr(line);
106
+ font-size: 13.5px;
107
+ text-align: right;
108
+ }
109
+
110
+ .highlight-line {
111
+ @apply bg-primary/5 border-l-2 border-primary/30;
112
+ }
113
+
114
+ .rehype-code-title {
115
+ @apply px-2 -mb-8 w-full text-sm pb-5 font-medium mt-5 font-code;
116
+ }
117
+
118
+ .highlight-comp>code {
119
+ background-color: transparent !important;
120
+ }
121
+
122
+ .line-clamp-3 {
123
+ display: -webkit-box;
124
+ -webkit-line-clamp: 3;
125
+ -webkit-box-orient: vertical;
126
+ overflow: hidden;
127
+ text-overflow: ellipsis;
128
+ }
129
+
130
+ .line-clamp-2 {
131
+ display: -webkit-box;
132
+ -webkit-line-clamp: 2;
133
+ -webkit-box-orient: vertical;
134
+ overflow: hidden;
135
+ text-overflow: ellipsis;
136
+ }
137
+
138
+ @layer utilities {
139
+ .animate-shine {
140
+ --animate-shine: shine var(--duration) infinite linear;
141
+ animation: var(--animate-shine);
142
+ background-size: 200% 200%;
143
+ }
144
+
145
+ @keyframes shine {
146
+ 0% {
147
+ background-position: 0% 0%;
148
+ }
149
+ 50% {
150
+ background-position: 100% 100%;
151
+ }
152
+ 100% {
153
+ background-position: 0% 0%;
154
+ }
155
+ }
156
+ }
@@ -0,0 +1,100 @@
1
+ /* ocean */
2
+ /* Light Mode */
3
+ .keyword {
4
+ color: #2563eb;
5
+ /* Vibrant Blue */
6
+ }
7
+
8
+ .function {
9
+ color: #0284c7;
10
+ /* Deep Sky Blue */
11
+ }
12
+
13
+ .punctuation {
14
+ color: #475569;
15
+ /* Cool Slate Gray */
16
+ }
17
+
18
+ .comment {
19
+ color: #64748b;
20
+ /* Muted Slate */
21
+ }
22
+
23
+ .string,
24
+ .constant,
25
+ .annotation,
26
+ .boolean,
27
+ .number {
28
+ color: #0369a1;
29
+ /* Dark Cyan */
30
+ }
31
+
32
+ .tag {
33
+ color: #1e40af;
34
+ /* Indigo */
35
+ }
36
+
37
+ .attr-name {
38
+ color: #0ea5e9;
39
+ /* Light Sky Blue */
40
+ }
41
+
42
+ .attr-value {
43
+ color: #2563eb;
44
+ /* Bright Blue */
45
+ }
46
+
47
+ /* Dark Mode */
48
+ .dark .keyword {
49
+ color: #93c5fd;
50
+ /* Soft Blue */
51
+ }
52
+
53
+ .dark .function {
54
+ color: #38bdf8;
55
+ /* Sky Blue */
56
+ }
57
+
58
+ .dark .string,
59
+ .dark .constant,
60
+ .dark .annotation,
61
+ .dark .boolean,
62
+ .dark .number {
63
+ color: #60a5fa;
64
+ /* Light Blue */
65
+ }
66
+
67
+ .dark .tag {
68
+ color: #3b82f6;
69
+ /* Bold Blue */
70
+ }
71
+
72
+ .dark .attr-name {
73
+ color: #67e8f9;
74
+ /* Aqua */
75
+ }
76
+
77
+ .dark .attr-value {
78
+ color: #93c5fd;
79
+ /* Frosty Blue */
80
+ }
81
+
82
+ .youtube {
83
+ position: relative;
84
+ padding-bottom: 56.25%; /* Rasio aspek 16:9 */
85
+ height: 0;
86
+ overflow: hidden;
87
+ background: #000; /* Latar belakang hitam untuk memadukan player */
88
+ border-radius: 8px; /* Sudut melengkung */
89
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2); /* Bayangan lembut */
90
+ }
91
+
92
+ .youtube iframe {
93
+ position: absolute;
94
+ top: 0;
95
+ left: 0;
96
+ width: 100%;
97
+ height: 100%;
98
+ border: none;
99
+ border-radius: 8px; /* Sudut melengkung pada iframe */
100
+ }
@@ -0,0 +1,112 @@
1
+ import type { Config } from "tailwindcss";
2
+
3
+ const config = {
4
+ darkMode: ["class"],
5
+ content: [
6
+ "./pages/**/*.{ts,tsx}",
7
+ "./components/**/*.{ts,tsx}",
8
+ "./app/**/*.{ts,tsx}",
9
+ "./src/**/*.{ts,tsx}",
10
+ ],
11
+ prefix: "",
12
+ safelist: ["line-clamp-3","line-clam-2"],
13
+ theme: {
14
+ container: {
15
+ center: true,
16
+ padding: '2rem',
17
+ screens: {
18
+ '2xl': '1440px'
19
+ }
20
+ },
21
+ extend: {
22
+ colors: {
23
+ border: 'hsl(var(--border))',
24
+ input: 'hsl(var(--input))',
25
+ ring: 'hsl(var(--ring))',
26
+ background: 'hsl(var(--background))',
27
+ foreground: 'hsl(var(--foreground))',
28
+ primary: {
29
+ DEFAULT: 'hsl(var(--primary))',
30
+ foreground: 'hsl(var(--primary-foreground))'
31
+ },
32
+ secondary: {
33
+ DEFAULT: 'hsl(var(--secondary))',
34
+ foreground: 'hsl(var(--secondary-foreground))'
35
+ },
36
+ destructive: {
37
+ DEFAULT: 'hsl(var(--destructive))',
38
+ foreground: 'hsl(var(--destructive-foreground))'
39
+ },
40
+ muted: {
41
+ DEFAULT: 'hsl(var(--muted))',
42
+ foreground: 'hsl(var(--muted-foreground))'
43
+ },
44
+ accent: {
45
+ DEFAULT: 'hsl(var(--accent))',
46
+ foreground: 'hsl(var(--accent-foreground))'
47
+ },
48
+ popover: {
49
+ DEFAULT: 'hsl(var(--popover))',
50
+ foreground: 'hsl(var(--popover-foreground))'
51
+ },
52
+ card: {
53
+ DEFAULT: 'hsl(var(--card))',
54
+ foreground: 'hsl(var(--card-foreground))'
55
+ },
56
+ sidebar: {
57
+ DEFAULT: 'hsl(var(--sidebar-background))',
58
+ foreground: 'hsl(var(--sidebar-foreground))',
59
+ primary: 'hsl(var(--sidebar-primary))',
60
+ 'primary-foreground': 'hsl(var(--sidebar-primary-foreground))',
61
+ accent: 'hsl(var(--sidebar-accent))',
62
+ 'accent-foreground': 'hsl(var(--sidebar-accent-foreground))',
63
+ border: 'hsl(var(--sidebar-border))',
64
+ ring: 'hsl(var(--sidebar-ring))'
65
+ }
66
+ },
67
+ borderRadius: {
68
+ lg: 'var(--radius)',
69
+ md: 'calc(var(--radius) - 2px)',
70
+ sm: 'calc(var(--radius) - 4px)'
71
+ },
72
+ fontFamily: {
73
+ code: ["var(--font-geist-mono)"],
74
+ regular: ["var(--font-geist-sans)"]
75
+ },
76
+ keyframes: {
77
+ 'accordion-down': {
78
+ from: {
79
+ height: '0'
80
+ },
81
+ to: {
82
+ height: 'var(--radix-accordion-content-height)'
83
+ }
84
+ },
85
+ 'accordion-up': {
86
+ from: {
87
+ height: 'var(--radix-accordion-content-height)'
88
+ },
89
+ to: {
90
+ height: '0'
91
+ }
92
+ },
93
+ 'shiny-text': {
94
+ '0%, 90%, 100%': {
95
+ 'background-position': 'calc(-100% - var(--shiny-width)) 0'
96
+ },
97
+ '30%, 60%': {
98
+ 'background-position': 'calc(100% + var(--shiny-width)) 0'
99
+ }
100
+ }
101
+ },
102
+ animation: {
103
+ 'accordion-down': 'accordion-down 0.2s ease-out',
104
+ 'accordion-up': 'accordion-up 0.2s ease-out',
105
+ 'shiny-text': 'shiny-text 8s infinite'
106
+ }
107
+ }
108
+ },
109
+ plugins: [require("tailwindcss-animate"), require("@tailwindcss/typography")],
110
+ } satisfies Config;
111
+
112
+ export default config;
@@ -0,0 +1,26 @@
1
+ {
2
+ "compilerOptions": {
3
+ "lib": ["dom", "dom.iterable", "esnext"],
4
+ "allowJs": true,
5
+ "skipLibCheck": true,
6
+ "strict": true,
7
+ "noEmit": true,
8
+ "esModuleInterop": true,
9
+ "module": "esnext",
10
+ "moduleResolution": "bundler",
11
+ "resolveJsonModule": true,
12
+ "isolatedModules": true,
13
+ "jsx": "preserve",
14
+ "incremental": true,
15
+ "plugins": [
16
+ {
17
+ "name": "next"
18
+ }
19
+ ],
20
+ "paths": {
21
+ "@/*": ["./*"]
22
+ }
23
+ },
24
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
25
+ "exclude": ["node_modules"]
26
+ }
package/src/index.js ADDED
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { initializeProgram } from "./cli/program.js";
4
+ import fs from "fs";
5
+ import path from "path";
6
+ import { fileURLToPath } from "url";
7
+
8
+ // Get the directory name of the current module
9
+ const __filename = fileURLToPath(import.meta.url);
10
+ const __dirname = path.dirname(__filename);
11
+
12
+ // Read version from package.json
13
+ const packageJsonPath = path.join(__dirname, '..', 'package.json');
14
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
15
+ const VERSION = packageJson.version;
16
+
17
+ // Initialize and parse CLI arguments
18
+ const program = initializeProgram(VERSION);
19
+ program.parse(process.argv);
@@ -0,0 +1,125 @@
1
+ import path from "path";
2
+ import fs from "fs";
3
+ import ora from "ora";
4
+ import chalk from "chalk";
5
+ import { execSync } from "child_process";
6
+ import { fileURLToPath } from "url";
7
+ import log from "../utils/logger.js";
8
+ import { configurePackageManager } from "../utils/packageManager.js";
9
+ import { displayManualSteps, simulateInstallation, displayNextSteps } from "../utils/display.js";
10
+
11
+ /**
12
+ * Creates a new DocuBook project
13
+ * @param {Object} options - Installation options
14
+ * @param {string} options.directoryName - Project directory name
15
+ * @param {string} options.packageManager - Package manager to use
16
+ * @param {string} options.version - Package manager version
17
+ * @param {boolean} options.installNow - Whether to install dependencies immediately
18
+ * @returns {Promise<void>}
19
+ */
20
+ export async function createProject({ directoryName, packageManager, version, installNow }) {
21
+ const projectPath = path.resolve(process.cwd(), directoryName);
22
+ const spinner = ora("Creating your DocuBook project...").start();
23
+
24
+ try {
25
+ // Get the template directory path
26
+ const __filename = fileURLToPath(import.meta.url);
27
+ const __dirname = path.dirname(__filename);
28
+ const templatePath = path.join(__dirname, "../dist");
29
+
30
+ // Create project directory if it doesn't exist
31
+ if (!fs.existsSync(projectPath)) {
32
+ fs.mkdirSync(projectPath, { recursive: true });
33
+ }
34
+
35
+ // Copy template files to project directory
36
+ copyDirectoryRecursive(templatePath, projectPath);
37
+
38
+ // Configure package manager specific settings
39
+ configurePackageManager(packageManager, projectPath);
40
+
41
+ // Update package.json with package manager info
42
+ const pkgPath = path.join(projectPath, "package.json");
43
+ let pkgVersion = "";
44
+ if (fs.existsSync(pkgPath)) {
45
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
46
+ pkg.packageManager = `${packageManager}@${version}`;
47
+ pkgVersion = pkg.version || "";
48
+ fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2));
49
+ }
50
+
51
+ spinner.succeed();
52
+ log.success(`DocuBook v${pkgVersion} using "${packageManager}"`);
53
+
54
+ if (!installNow) {
55
+ displayManualSteps(directoryName, packageManager);
56
+ return;
57
+ }
58
+
59
+ await installDependencies(directoryName, packageManager, projectPath);
60
+ } catch (err) {
61
+ spinner.fail("Failed to create project.");
62
+ log.error(err.message);
63
+ throw err;
64
+ }
65
+ }
66
+
67
+ /**
68
+ * Recursively copies a directory
69
+ * @param {string} source - Source directory path
70
+ * @param {string} destination - Destination directory path
71
+ */
72
+ function copyDirectoryRecursive(source, destination) {
73
+ // Create destination directory if it doesn't exist
74
+ if (!fs.existsSync(destination)) {
75
+ fs.mkdirSync(destination, { recursive: true });
76
+ }
77
+
78
+ // Read source directory contents
79
+ const entries = fs.readdirSync(source, { withFileTypes: true });
80
+
81
+ // Process each entry
82
+ for (const entry of entries) {
83
+ const srcPath = path.join(source, entry.name);
84
+ const destPath = path.join(destination, entry.name);
85
+
86
+ // If entry is a directory, recursively copy it
87
+ if (entry.isDirectory()) {
88
+ copyDirectoryRecursive(srcPath, destPath);
89
+ } else {
90
+ // Otherwise, copy the file
91
+ fs.copyFileSync(srcPath, destPath);
92
+ }
93
+ }
94
+ }
95
+
96
+ /**
97
+ * Installs project dependencies
98
+ * @param {string} directoryName - Project directory name
99
+ * @param {string} packageManager - Package manager to use
100
+ * @param {string} projectPath - Path to the project directory
101
+ * @returns {Promise<void>}
102
+ */
103
+ async function installDependencies(directoryName, packageManager, projectPath) {
104
+ log.info("Installing dependencies...");
105
+ console.log(chalk.yellow("This is a joke for you:"));
106
+ console.log(
107
+ chalk.white(
108
+ "You don't need to worry about this process not running, you just need the latest device for a faster installation process."
109
+ )
110
+ );
111
+
112
+ const installSpinner = ora(`Using ${packageManager}...`).start();
113
+
114
+ try {
115
+ execSync(`${packageManager} install`, { cwd: projectPath, stdio: "ignore" });
116
+ installSpinner.succeed("Dependencies installed.");
117
+
118
+ await simulateInstallation();
119
+ displayNextSteps(directoryName, packageManager);
120
+ } catch (error) {
121
+ installSpinner.fail("Failed to install dependencies.");
122
+ displayManualSteps(directoryName, packageManager);
123
+ throw new Error("Failed to install dependencies");
124
+ }
125
+ }
@@ -0,0 +1,83 @@
1
+ import chalk from "chalk";
2
+ import figlet from "figlet";
3
+ import boxen from "boxen";
4
+ import cliProgress from "cli-progress";
5
+
6
+ /**
7
+ * Displays ASCII art "DocuBook" when CLI is launched
8
+ * @returns {Promise} Promise that resolves when ASCII art is displayed
9
+ */
10
+ export function displayAsciiArt() {
11
+ return new Promise((resolve, reject) => {
12
+ figlet.text("DocuBook", { horizontalLayout: "full" }, (err, data) => {
13
+ if (err) return reject(err);
14
+ console.log(chalk.green(data));
15
+ resolve();
16
+ });
17
+ });
18
+ }
19
+
20
+ /**
21
+ * Displays a progress bar to simulate final setup
22
+ * @returns {Promise} Promise that resolves when simulation completes
23
+ */
24
+ export async function simulateInstallation() {
25
+ const bar = new cliProgress.SingleBar(
26
+ {
27
+ format: 'Finishing Setup |' + chalk.green('{bar}') + '| {percentage}% || {value}/{total}',
28
+ barCompleteChar: '\u2588',
29
+ barIncompleteChar: '\u2591',
30
+ },
31
+ cliProgress.Presets.shades_classic
32
+ );
33
+
34
+ bar.start(100, 0);
35
+ for (let i = 0; i <= 100; i++) {
36
+ await new Promise((r) => setTimeout(r, 50));
37
+ bar.update(i);
38
+ }
39
+ bar.stop();
40
+ }
41
+
42
+ /**
43
+ * Displays manual installation steps if automatic installation fails
44
+ * @param {string} projectDirectory - Project directory name
45
+ * @param {string} packageManager - Package manager being used
46
+ */
47
+ export function displayManualSteps(projectDirectory, packageManager) {
48
+ const manualInstructions = `
49
+ Please follow these steps manually to finish setting up your project:
50
+
51
+ 1. ${chalk.cyan(`cd ${projectDirectory}`)}
52
+ 2. ${chalk.cyan(`${packageManager} install`)}
53
+ 3. ${chalk.cyan(`${packageManager} run dev`)}
54
+ `;
55
+
56
+ console.log(
57
+ boxen(manualInstructions, {
58
+ padding: 0.5,
59
+ borderStyle: "round",
60
+ borderColor: "cyan",
61
+ })
62
+ );
63
+ }
64
+
65
+ /**
66
+ * Displays next steps after successful installation
67
+ * @param {string} directoryName - Project directory name
68
+ * @param {string} packageManager - Package manager being used
69
+ */
70
+ export function displayNextSteps(directoryName, packageManager) {
71
+ console.log(
72
+ boxen(
73
+ `Next Steps:\n\n` +
74
+ `1. ${chalk.cyan(`cd ${directoryName}`)}\n` +
75
+ `2. ${chalk.cyan(`${packageManager} run dev`)}`,
76
+ {
77
+ padding: 0.5,
78
+ borderStyle: "round",
79
+ borderColor: "cyan",
80
+ }
81
+ )
82
+ );
83
+ }
@@ -0,0 +1,11 @@
1
+ import chalk from "chalk";
2
+
3
+ // Logging helper with styles
4
+ const log = {
5
+ info: (msg) => console.log(chalk.cyan("ℹ️ " + msg)),
6
+ success: (msg) => console.log(chalk.green("✔ " + msg)),
7
+ warn: (msg) => console.log(chalk.yellow("⚠️ " + msg)),
8
+ error: (msg) => console.log(chalk.red("✖ " + msg)),
9
+ };
10
+
11
+ export default log;
@@ -0,0 +1,54 @@
1
+ import { execSync } from "child_process";
2
+ import fs from "fs";
3
+ import path from "path";
4
+
5
+ /**
6
+ * Gets the version of the specified package manager
7
+ * @param {string} pm - Package manager name
8
+ * @returns {string|null} Version string or null if not installed
9
+ */
10
+ export function getPackageManagerVersion(pm) {
11
+ try {
12
+ return execSync(`${pm} --version`).toString().trim();
13
+ } catch {
14
+ return null;
15
+ }
16
+ }
17
+
18
+ /**
19
+ * Detects the default package manager from user environment
20
+ * @returns {string} Default package manager name
21
+ */
22
+ export function detectDefaultPackageManager() {
23
+ const userAgent = process.env.npm_config_user_agent || "";
24
+ if (userAgent.includes("pnpm")) return "pnpm";
25
+ if (userAgent.includes("yarn")) return "yarn";
26
+ if (userAgent.includes("bun")) return "bun";
27
+ return "npm";
28
+ }
29
+
30
+ /**
31
+ * Updates postcss config file extension for Bun compatibility
32
+ * @param {string} projectPath - Path to the project directory
33
+ */
34
+ export function updatePostcssConfig(projectPath) {
35
+ const oldPath = path.join(projectPath, "postcss.config.js");
36
+ const newPath = path.join(projectPath, "postcss.config.cjs");
37
+ if (fs.existsSync(oldPath)) {
38
+ fs.renameSync(oldPath, newPath);
39
+ }
40
+ }
41
+
42
+ /**
43
+ * Configures package manager specific settings
44
+ * @param {string} packageManager - Package manager name
45
+ * @param {string} projectPath - Path to the project directory
46
+ */
47
+ export function configurePackageManager(packageManager, projectPath) {
48
+ if (packageManager === "bun") {
49
+ updatePostcssConfig(projectPath);
50
+ } else if (packageManager === "yarn") {
51
+ const yarnrcPath = path.join(projectPath, ".yarnrc.yml");
52
+ fs.writeFileSync(yarnrcPath, "nodeLinker: node-modules\n");
53
+ }
54
+ }