portosaurus 1.18.16 → 2.0.0
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 +21 -10
- package/bin/portosaurus.mjs +357 -0
- package/package.json +46 -53
- package/src/assets/img/icon-old.png +0 -0
- package/src/assets/img/project-blank.png +0 -0
- package/src/assets/img/social-card.jpeg +0 -0
- package/src/assets/img/svg/icon-blog.svg +2 -0
- package/src/assets/img/svg/icon-close.svg +3 -0
- package/src/assets/img/svg/icon-dock.svg +4 -0
- package/src/assets/img/svg/icon-link.svg +5 -0
- package/src/assets/img/svg/icon-note.svg +2 -0
- package/src/assets/img/svg/icon-popup.svg +1 -0
- package/src/assets/img/svg/icon-save.svg +5 -0
- package/src/components/AboutSection/styles.module.css +12 -13
- package/src/components/ContactSection/index.js +27 -35
- package/src/components/ContactSection/styles.module.css +4 -4
- package/src/components/ExperienceSection/styles.module.css +1 -1
- package/src/components/HeroSection/index.js +18 -17
- package/src/components/HeroSection/styles.module.css +3 -3
- package/src/components/NoteIndex/index.js +78 -40
- package/src/components/NoteIndex/styles.module.css +60 -32
- package/src/components/Preview/components/FeedbackStates.js +62 -0
- package/src/components/Preview/components/FileTabs.js +38 -0
- package/src/components/Preview/components/PreviewHeader.js +170 -0
- package/src/components/Preview/components/Triggers/Pv.js +164 -0
- package/src/components/Preview/components/Triggers/SrcPv.js +32 -0
- package/src/components/Preview/components/Triggers/index.js +2 -0
- package/src/components/Preview/components/ViewerWindow.js +443 -0
- package/src/components/Preview/hooks/useDeepLinkHash.js +38 -0
- package/src/components/Preview/hooks/useDockLayout.js +70 -0
- package/src/components/Preview/hooks/useFileFetch.js +48 -0
- package/src/components/Preview/index.js +3 -0
- package/src/components/Preview/renderers/CodeRenderer.js +63 -0
- package/src/components/Preview/renderers/ImageRenderer.js +43 -0
- package/src/components/Preview/renderers/PdfRenderer.js +88 -0
- package/src/components/Preview/renderers/WebRenderer.js +55 -0
- package/src/components/Preview/state/index.js +140 -0
- package/src/components/Preview/styles.module.css +640 -0
- package/src/components/Preview/utils/index.js +96 -0
- package/src/components/ProjectsSection/index.js +226 -282
- package/src/components/ProjectsSection/styles.module.css +13 -13
- package/src/components/ScrollToTop/styles.module.css +1 -1
- package/src/components/SocialLinks/index.js +61 -56
- package/src/components/Tooltip/index.js +75 -23
- package/src/components/Tooltip/styles.module.css +34 -21
- package/src/config/iconMappings.js +8 -8
- package/src/config/metaTags.js +119 -118
- package/src/config/sidebar.js +20 -0
- package/src/core/build-utils/cssUtils.mjs +30 -0
- package/src/core/build-utils/generateFavicon.mjs +206 -0
- package/src/core/build-utils/generateRobotsTxt.mjs +59 -0
- package/src/core/build-utils/iconExtractor.mjs +31 -0
- package/src/core/build-utils/imageDownloader.mjs +98 -0
- package/src/core/build-utils/imageProcessor.mjs +55 -0
- package/src/core/createDocuConf.mjs +456 -0
- package/src/core/defaults.mjs +67 -0
- package/src/core/logger.mjs +17 -0
- package/src/core/packageManager.mjs +60 -0
- package/src/core/themePlugin.mjs +23 -0
- package/src/css/custom.css +1 -0
- package/src/css/tasks.css +5 -5
- package/src/pages/{Home.js → index.js} +39 -24
- package/src/pages/notes.js +87 -0
- package/src/pages/{Tasks.js → tasks.js} +56 -115
- package/src/template/blog/authors.yml +3 -4
- package/src/template/blog/welcome.md +7 -6
- package/src/template/config.js +15 -193
- package/src/template/notes/welcome.md +2 -7
- package/src/template/static/README.md +1 -33
- package/src/theme/MDXComponents.js +23 -0
- package/src/theme/Root.js +21 -0
- package/bin/portosaurus.js +0 -443
- package/src/config/sidebars.js +0 -20
- package/src/img/social card.svg +0 -108
- package/src/internal/README.md +0 -3
- package/src/internal/notes/index.md +0 -10
- package/src/internal/src/pages/index.js +0 -1
- package/src/internal/src/pages/notes.js +0 -1
- package/src/internal/src/pages/tasks.js +0 -1
- package/src/pages/Notes.js +0 -84
- package/src/template/.github/workflows/deploy.yml +0 -57
- package/src/template/README.md +0 -82
- package/src/utils/appVersion.js +0 -28
- package/src/utils/createDocuConf.js +0 -334
- package/src/utils/cssUtils.js +0 -127
- package/src/utils/filterEnabledItems.js +0 -21
- package/src/utils/generateFavicon.js +0 -256
- package/src/utils/generateRobotsTxt.js +0 -97
- package/src/utils/iconExtractor.js +0 -165
- package/src/utils/imageDownloader.js +0 -92
- package/src/utils/imageProcessor.js +0 -134
- package/src/utils/linkShortner.js +0 -0
- package/src/utils/logger.js +0 -19
- package/src/utils/packageManager.js +0 -91
- package/src/utils/transpilePlugin.js +0 -18
- /package/src/{img → assets/img}/icon.png +0 -0
- /package/src/{img → assets/img}/icon.svg +0 -0
- /package/src/{utils → core/client-utils}/HashNavigation.js +0 -0
- /package/src/{utils → core/client-utils}/updateTitle.js +0 -0
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<div align="center">
|
|
2
|
-
<img src="./src/img/icon.
|
|
2
|
+
<img src="./src/assets/img/icon.svg" width=150>
|
|
3
3
|
<h1>Portosaurus</h1>
|
|
4
4
|
<p>Complete portfolio cum personal website solution for your digital personality.</p>
|
|
5
5
|
</div>
|
|
@@ -10,14 +10,13 @@
|
|
|
10
10
|
|
|
11
11
|
- **📝 Full-featured Portfolio Site** — Showcase your work, skills, experience, social identity.
|
|
12
12
|
- **🎨 Beautiful UI** — Responsive design with Catppuccin color scheme.
|
|
13
|
+
- **🛠️ Highly Configurable** — Extensive customization options in a central config file
|
|
13
14
|
- **🖼️ Project Showcase** — Interactive project cards with support for featured projects, project status badges, and tags
|
|
14
|
-
- **📚 Knowledge Base** — Integrated notes
|
|
15
|
-
- **✏️ Blog Platform** — Built-in blogging
|
|
15
|
+
- **📚 Knowledge Base** — Integrated notes vault with many usefull utilities
|
|
16
|
+
- **✏️ Blog Platform** — Built-in blogging platform.
|
|
16
17
|
- **📋 Task Tracking** — Track your plans with priority levels and completion status
|
|
17
|
-
- **🛠️ Highly Configurable** — Extensive customization options in a central config file
|
|
18
18
|
- **🔍 Powerful Search** — Integrated search functionality for notes and blog content
|
|
19
19
|
- **📱 Mobile-Friendly** — Fully responsive design works on all devices
|
|
20
|
-
- **🚀 Auto Deployment** — Ready for GitHub Pages or any static hosting
|
|
21
20
|
|
|
22
21
|
<br/>
|
|
23
22
|
|
|
@@ -47,11 +46,11 @@ Navigate to your project and start the development server:
|
|
|
47
46
|
```bash
|
|
48
47
|
cd my-portfolio
|
|
49
48
|
|
|
50
|
-
# With npm
|
|
51
|
-
npm run dev
|
|
52
|
-
|
|
53
49
|
# With Bun
|
|
54
50
|
bun run dev
|
|
51
|
+
|
|
52
|
+
# With npm
|
|
53
|
+
npm run dev
|
|
55
54
|
```
|
|
56
55
|
|
|
57
56
|
Your site will be available at `http://localhost:3000`.
|
|
@@ -73,10 +72,9 @@ Your site will be available at `http://localhost:3000`.
|
|
|
73
72
|
|
|
74
73
|
A portosaurus project can be deployed to any static hosting provider like:
|
|
75
74
|
|
|
75
|
+
- Cloudflare Pages
|
|
76
76
|
- Netlify
|
|
77
77
|
- Vercel
|
|
78
|
-
- Cloudflare Pages
|
|
79
|
-
- Other static providers
|
|
80
78
|
|
|
81
79
|
To generate the static site for production:
|
|
82
80
|
|
|
@@ -119,6 +117,19 @@ module.exports = {
|
|
|
119
117
|
};
|
|
120
118
|
```
|
|
121
119
|
|
|
120
|
+
## Development
|
|
121
|
+
|
|
122
|
+
### Setup Environment
|
|
123
|
+
|
|
124
|
+
0. Fork This Repo
|
|
125
|
+
1. Clone forked repo: `git clone https://github.com/yourUserName/portosaurus.git`
|
|
126
|
+
2. Install Mise, visit [official guide](https://mise.jdx.dev/installing-mise.html)
|
|
127
|
+
3. Install Dependencies: `mise install`
|
|
128
|
+
4. Make changes
|
|
129
|
+
5. Stage & commit: `mise commit`
|
|
130
|
+
6. Push Changes: `git push`
|
|
131
|
+
7. Open PR: `mise pr`
|
|
132
|
+
|
|
122
133
|
<br>
|
|
123
134
|
|
|
124
135
|
## 📄 Credits
|
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
import { Command } from "commander";
|
|
4
|
+
import fs from "fs";
|
|
5
|
+
import path from "path";
|
|
6
|
+
import { fileURLToPath } from "url";
|
|
7
|
+
import { spawn, execSync } from "child_process";
|
|
8
|
+
|
|
9
|
+
import { logger } from "../src/core/logger.mjs";
|
|
10
|
+
import {
|
|
11
|
+
detectPackageManager,
|
|
12
|
+
getInstallCommand,
|
|
13
|
+
findDocusaurusBin,
|
|
14
|
+
} from "../src/core/packageManager.mjs";
|
|
15
|
+
|
|
16
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
17
|
+
const portosaurusRoot = path.resolve(__dirname, "..");
|
|
18
|
+
|
|
19
|
+
const packageJson = JSON.parse(
|
|
20
|
+
fs.readFileSync(path.resolve(portosaurusRoot, "package.json"), "utf8"),
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
const program = new Command();
|
|
24
|
+
|
|
25
|
+
program
|
|
26
|
+
.name("portosaurus")
|
|
27
|
+
.description("CLI for Portosaurus — The complete portfolio solution")
|
|
28
|
+
.version(packageJson.version, "-v, --version", "output the current version");
|
|
29
|
+
|
|
30
|
+
// ─── Helpers ────────────────────────────────────────────────
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Write the ephemeral .portosaurus/docusaurus.config.mjs shim.
|
|
34
|
+
* This tiny file imports the user's config.js and passes it
|
|
35
|
+
* to the portosaurus config generator using absolute paths.
|
|
36
|
+
*/
|
|
37
|
+
function writeConfigShim(projectRoot) {
|
|
38
|
+
const dotDir = path.join(projectRoot, ".docusaurus", "portosaurus");
|
|
39
|
+
fs.mkdirSync(dotDir, { recursive: true });
|
|
40
|
+
|
|
41
|
+
const configJsAbsolute = path
|
|
42
|
+
.join(projectRoot, "config.js")
|
|
43
|
+
.replace(/\\/g, "/");
|
|
44
|
+
const createDocuConfAbsolute = path
|
|
45
|
+
.resolve(portosaurusRoot, "src/core/createDocuConf.mjs")
|
|
46
|
+
.replace(/\\/g, "/");
|
|
47
|
+
|
|
48
|
+
// Docusaurus 3 supports ESM and async config functions.
|
|
49
|
+
const shimContent = `// Auto-generated by Portosaurus CLI — do not edit
|
|
50
|
+
/** @type {import('@docusaurus/types').Config} */
|
|
51
|
+
export default async function getConfig() {
|
|
52
|
+
const { createDocuConf } = await import("file://${createDocuConfAbsolute}");
|
|
53
|
+
const { usrConf } = await import("file://${configJsAbsolute}");
|
|
54
|
+
return createDocuConf(usrConf, "${projectRoot.replace(/\\/g, "/")}");
|
|
55
|
+
}
|
|
56
|
+
`;
|
|
57
|
+
|
|
58
|
+
const shimPath = path.join(dotDir, "docusaurus.config.js");
|
|
59
|
+
fs.writeFileSync(shimPath, shimContent);
|
|
60
|
+
logger.debug(`Config shim written to ${shimPath}`);
|
|
61
|
+
|
|
62
|
+
return shimPath;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Validate that the current directory is a Portosaurus project.
|
|
67
|
+
*/
|
|
68
|
+
function validateProject(projectRoot) {
|
|
69
|
+
const configPath = path.join(projectRoot, "config.js");
|
|
70
|
+
if (!fs.existsSync(configPath)) {
|
|
71
|
+
console.log();
|
|
72
|
+
logger.error(
|
|
73
|
+
"config.js not found. Are you in a Portosaurus project directory?",
|
|
74
|
+
);
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Ensure essential user content directories exist.
|
|
81
|
+
*/
|
|
82
|
+
function ensureContentDirs(projectRoot) {
|
|
83
|
+
for (const dir of ["notes", "blog", "static"]) {
|
|
84
|
+
fs.mkdirSync(path.join(projectRoot, dir), { recursive: true });
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Ensure notes has at least an index.mdx so Docusaurus doesn't error
|
|
88
|
+
const notesIndex = path.join(projectRoot, "notes", "index.mdx");
|
|
89
|
+
if (!fs.existsSync(notesIndex)) {
|
|
90
|
+
fs.writeFileSync(
|
|
91
|
+
notesIndex,
|
|
92
|
+
`---\nhide_table_of_contents: true\n---\n\nimport NoteCards from "@site/src/components/NoteIndex";\n\n# Notes\n\n<NoteCards />\n`,
|
|
93
|
+
);
|
|
94
|
+
logger.debug("Created default notes/index.mdx");
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Spawn a Docusaurus command and wait for it to complete.
|
|
100
|
+
*/
|
|
101
|
+
function runDocusaurus(command, extraArgs, projectRoot, configPath) {
|
|
102
|
+
const {
|
|
103
|
+
command: cmd,
|
|
104
|
+
args: pmArgs,
|
|
105
|
+
packageManager,
|
|
106
|
+
} = findDocusaurusBin(projectRoot);
|
|
107
|
+
|
|
108
|
+
logger.info(`Running docusaurus ${command} (via ${packageManager})`);
|
|
109
|
+
|
|
110
|
+
// Use the dynamically detected package manager command instead of hardcoding
|
|
111
|
+
const spawnCommand = cmd;
|
|
112
|
+
const finalArgs = [
|
|
113
|
+
...pmArgs,
|
|
114
|
+
command,
|
|
115
|
+
projectRoot,
|
|
116
|
+
"--config",
|
|
117
|
+
configPath,
|
|
118
|
+
...extraArgs,
|
|
119
|
+
];
|
|
120
|
+
|
|
121
|
+
const child = spawn(spawnCommand, finalArgs, {
|
|
122
|
+
stdio: "inherit",
|
|
123
|
+
cwd: projectRoot,
|
|
124
|
+
env: { ...process.env, FORCE_COLOR: "true" },
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
return new Promise((resolve, reject) => {
|
|
128
|
+
child.on("error", (err) => {
|
|
129
|
+
logger.error(`Failed to run docusaurus ${command}: ${err.message}`);
|
|
130
|
+
reject(err);
|
|
131
|
+
});
|
|
132
|
+
child.on("close", (code) => {
|
|
133
|
+
if (code === 0) resolve();
|
|
134
|
+
else process.exit(code);
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// ─── INIT COMMAND ───────────────────────────────────────────
|
|
140
|
+
|
|
141
|
+
program
|
|
142
|
+
.command("init")
|
|
143
|
+
.description("Initialize a new Portosaurus project")
|
|
144
|
+
.argument("<project-name>", "Name of the project directory")
|
|
145
|
+
.option("--no-install", "Skip dependency installation")
|
|
146
|
+
.option("--no-github-pages", "Skip GitHub Pages deployment setup")
|
|
147
|
+
.action(async (projectName, options) => {
|
|
148
|
+
const projectPath = path.resolve(process.cwd(), projectName);
|
|
149
|
+
|
|
150
|
+
if (fs.existsSync(projectPath)) {
|
|
151
|
+
logger.error(`Directory "${projectName}" already exists.`);
|
|
152
|
+
process.exit(1);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
logger.info(`Creating new Portosaurus project in ${projectName}...`);
|
|
156
|
+
|
|
157
|
+
try {
|
|
158
|
+
fs.mkdirSync(projectPath, { recursive: true });
|
|
159
|
+
|
|
160
|
+
// Copy template files if they exist
|
|
161
|
+
const templatePath = path.resolve(portosaurusRoot, "src/template");
|
|
162
|
+
if (fs.existsSync(templatePath)) {
|
|
163
|
+
copyDirSync(templatePath, projectPath);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Ensure content directories
|
|
167
|
+
for (const dir of ["blog", "notes", "static"]) {
|
|
168
|
+
fs.mkdirSync(path.join(projectPath, dir), { recursive: true });
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Create a minimal config.js if the template didn't provide one
|
|
172
|
+
const configDest = path.join(projectPath, "config.js");
|
|
173
|
+
if (!fs.existsSync(configDest)) {
|
|
174
|
+
fs.writeFileSync(
|
|
175
|
+
configDest,
|
|
176
|
+
`exports.usrConf = {\n dark_mode: true,\n site_url: "auto",\n site_path: "auto",\n\n hero_section: {\n title: "${projectName}",\n profession: "Your Profession",\n description: "Short description about you.",\n },\n};\n`,
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Create package.json
|
|
181
|
+
const pkg = {
|
|
182
|
+
name: projectName,
|
|
183
|
+
version: "0.0.1",
|
|
184
|
+
private: true,
|
|
185
|
+
scripts: {
|
|
186
|
+
dev: "portosaurus dev",
|
|
187
|
+
start: "portosaurus start",
|
|
188
|
+
build: "portosaurus build",
|
|
189
|
+
serve: "portosaurus serve",
|
|
190
|
+
},
|
|
191
|
+
dependencies: {
|
|
192
|
+
portosaurus: `^${packageJson.version}`,
|
|
193
|
+
},
|
|
194
|
+
};
|
|
195
|
+
fs.writeFileSync(
|
|
196
|
+
path.join(projectPath, "package.json"),
|
|
197
|
+
JSON.stringify(pkg, null, 2),
|
|
198
|
+
);
|
|
199
|
+
|
|
200
|
+
// Create .gitignore
|
|
201
|
+
fs.writeFileSync(
|
|
202
|
+
path.join(projectPath, ".gitignore"),
|
|
203
|
+
`node_modules/\nbuild/\n.docusaurus/\n.cache-loader/\n`,
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
// Git init
|
|
207
|
+
try {
|
|
208
|
+
execSync("git init", { cwd: projectPath, stdio: "ignore" });
|
|
209
|
+
} catch {
|
|
210
|
+
logger.warn("Failed to initialize git repository.");
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// GitHub Pages setup
|
|
214
|
+
if (options.githubPages === false) {
|
|
215
|
+
const ghDir = path.join(projectPath, ".github");
|
|
216
|
+
if (fs.existsSync(ghDir)) {
|
|
217
|
+
fs.rmSync(ghDir, { recursive: true, force: true });
|
|
218
|
+
logger.info("Skipped GitHub Pages setup.");
|
|
219
|
+
}
|
|
220
|
+
} else {
|
|
221
|
+
fs.writeFileSync(path.join(projectPath, "static", ".nojekyll"), "");
|
|
222
|
+
logger.success("GitHub Pages deployment configured.");
|
|
223
|
+
logger.tip(
|
|
224
|
+
"Enable GitHub Pages: Settings > Pages > Source: GitHub Actions",
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
logger.success(`Created ${projectName} at ${projectPath}`);
|
|
229
|
+
|
|
230
|
+
// Install dependencies
|
|
231
|
+
const pm = detectPackageManager(projectPath) || "npm";
|
|
232
|
+
const installCmd = getInstallCommand(pm);
|
|
233
|
+
const runCmd = pm === "npm" ? "npm run" : `${pm} run`;
|
|
234
|
+
|
|
235
|
+
if (options.install !== false) {
|
|
236
|
+
logger.info(`Running ${installCmd}...`);
|
|
237
|
+
try {
|
|
238
|
+
execSync(installCmd, { cwd: projectPath, stdio: "inherit" });
|
|
239
|
+
logger.success("Dependencies installed!");
|
|
240
|
+
} catch {
|
|
241
|
+
logger.error("Failed to install dependencies.");
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
logger.tip("You can now run:");
|
|
246
|
+
logger.info(` cd ${projectName}`);
|
|
247
|
+
logger.info(` ${runCmd} dev`);
|
|
248
|
+
} catch (error) {
|
|
249
|
+
logger.error(`Failed to initialize project: ${error.message}`);
|
|
250
|
+
process.exit(1);
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
// ─── DEV / START COMMAND ────────────────────────────────────
|
|
255
|
+
|
|
256
|
+
program
|
|
257
|
+
.command("start [extraArgs...]")
|
|
258
|
+
.alias("dev")
|
|
259
|
+
.description("Start the development server")
|
|
260
|
+
.allowUnknownOption()
|
|
261
|
+
.action(async function (extraArgs) {
|
|
262
|
+
const projectRoot = process.cwd();
|
|
263
|
+
validateProject(projectRoot);
|
|
264
|
+
ensureContentDirs(projectRoot);
|
|
265
|
+
|
|
266
|
+
logger.info("Starting development server...");
|
|
267
|
+
try {
|
|
268
|
+
const configPath = writeConfigShim(projectRoot);
|
|
269
|
+
runDocusaurus("start", extraArgs || [], projectRoot, configPath);
|
|
270
|
+
} catch (error) {
|
|
271
|
+
logger.error(`Failed to start: ${error.message}`);
|
|
272
|
+
process.exit(1);
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
// ─── BUILD COMMAND ──────────────────────────────────────────
|
|
277
|
+
|
|
278
|
+
program
|
|
279
|
+
.command("build [extraArgs...]")
|
|
280
|
+
.description("Build the static site")
|
|
281
|
+
.allowUnknownOption()
|
|
282
|
+
.action(async function (extraArgs) {
|
|
283
|
+
const projectRoot = process.cwd();
|
|
284
|
+
validateProject(projectRoot);
|
|
285
|
+
ensureContentDirs(projectRoot);
|
|
286
|
+
|
|
287
|
+
logger.info("Building Portosaurus site...");
|
|
288
|
+
try {
|
|
289
|
+
const configPath = writeConfigShim(projectRoot);
|
|
290
|
+
const buildDir = path.join(projectRoot, "build");
|
|
291
|
+
const args = ["--out-dir", buildDir, ...(extraArgs || [])];
|
|
292
|
+
|
|
293
|
+
await runDocusaurus("build", args, projectRoot, configPath);
|
|
294
|
+
|
|
295
|
+
// Create .nojekyll for GitHub Pages compatibility
|
|
296
|
+
if (fs.existsSync(buildDir)) {
|
|
297
|
+
fs.writeFileSync(path.join(buildDir, ".nojekyll"), "");
|
|
298
|
+
logger.info("Created .nojekyll");
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
logger.success("Build completed successfully!");
|
|
302
|
+
logger.info(`Output directory: ${buildDir}`);
|
|
303
|
+
} catch (error) {
|
|
304
|
+
logger.error(`Failed to build: ${error.message}`);
|
|
305
|
+
process.exit(1);
|
|
306
|
+
}
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
// ─── SERVE COMMAND ──────────────────────────────────────────
|
|
310
|
+
|
|
311
|
+
program
|
|
312
|
+
.command("serve")
|
|
313
|
+
.description("Serve the built static site locally")
|
|
314
|
+
.action(async () => {
|
|
315
|
+
const projectRoot = process.cwd();
|
|
316
|
+
validateProject(projectRoot);
|
|
317
|
+
|
|
318
|
+
const buildDir = path.join(projectRoot, "build");
|
|
319
|
+
if (!fs.existsSync(buildDir)) {
|
|
320
|
+
logger.error("Build directory not found. Run 'portosaurus build' first.");
|
|
321
|
+
process.exit(1);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
logger.info("Serving Portosaurus site...");
|
|
325
|
+
try {
|
|
326
|
+
const configPath = writeConfigShim(projectRoot);
|
|
327
|
+
await runDocusaurus(
|
|
328
|
+
"serve",
|
|
329
|
+
["--dir", buildDir],
|
|
330
|
+
projectRoot,
|
|
331
|
+
configPath,
|
|
332
|
+
);
|
|
333
|
+
} catch (error) {
|
|
334
|
+
logger.error(`Failed to serve: ${error.message}`);
|
|
335
|
+
process.exit(1);
|
|
336
|
+
}
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
// ─── Utility ────────────────────────────────────────────────
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Recursively copy a directory.
|
|
343
|
+
*/
|
|
344
|
+
function copyDirSync(src, dest) {
|
|
345
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
346
|
+
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
|
347
|
+
const srcPath = path.join(src, entry.name);
|
|
348
|
+
const destPath = path.join(dest, entry.name);
|
|
349
|
+
if (entry.isDirectory()) {
|
|
350
|
+
copyDirSync(srcPath, destPath);
|
|
351
|
+
} else {
|
|
352
|
+
fs.copyFileSync(srcPath, destPath);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
program.parse();
|
package/package.json
CHANGED
|
@@ -1,71 +1,64 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "portosaurus",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"license": "GPL-3.0-only",
|
|
6
|
-
"description": "Complete portfolio cum personal website solution for your digital personality.",
|
|
7
|
-
"homepage": "https://github.com/soymadip/portosaurus#readme",
|
|
8
|
-
"repository": {
|
|
9
|
-
"type": "git",
|
|
10
|
-
"url": "git+https://github.com/soymadip/portosaurus.git"
|
|
11
|
-
},
|
|
12
|
-
"bugs": {
|
|
13
|
-
"url": "https://github.com/soymadip/portosaurus/issues"
|
|
14
|
-
},
|
|
15
|
-
"keywords": [
|
|
16
|
-
"portfolio",
|
|
17
|
-
"docusaurus",
|
|
18
|
-
"cli",
|
|
19
|
-
"static-site-generator",
|
|
20
|
-
"documentation",
|
|
21
|
-
"blog"
|
|
22
|
-
],
|
|
23
|
-
"type": "module",
|
|
24
|
-
"imports": {
|
|
25
|
-
"#config/*": "./src/config/*",
|
|
26
|
-
"#utils/*": "./src/utils/*.js",
|
|
27
|
-
"#css/*": "./src/css/*.css",
|
|
28
|
-
"#pages/*": "./src/pages/*.js",
|
|
29
|
-
"#components/*": "./src/components/*",
|
|
30
|
-
"#internal/*": "./src/internal/src/*"
|
|
31
|
-
},
|
|
32
|
-
"exports": {
|
|
33
|
-
"./components/*": "./src/components/*",
|
|
34
|
-
"./utils/*": "./src/utils/*.js",
|
|
35
|
-
"./config/*": "./src/config/*.js",
|
|
36
|
-
"./css/*": "./src/css/*.css",
|
|
37
|
-
"./pages/*": "./src/pages/*.js"
|
|
38
|
-
},
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"private": false,
|
|
39
5
|
"bin": {
|
|
40
|
-
"portosaurus": "bin/portosaurus.
|
|
6
|
+
"portosaurus": "bin/portosaurus.mjs"
|
|
41
7
|
},
|
|
42
8
|
"files": [
|
|
43
9
|
"bin/",
|
|
44
|
-
"src/
|
|
45
|
-
"src/template/",
|
|
46
|
-
"src/utils/",
|
|
10
|
+
"src/components/",
|
|
47
11
|
"src/config/",
|
|
12
|
+
"src/core/",
|
|
48
13
|
"src/css/",
|
|
49
|
-
"src/img",
|
|
50
14
|
"src/pages/",
|
|
51
|
-
"src/
|
|
15
|
+
"src/theme/",
|
|
16
|
+
"src/template/",
|
|
17
|
+
"src/assets/"
|
|
52
18
|
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"dev": "$npm_execpath bin/portosaurus.mjs dev",
|
|
21
|
+
"build": "$npm_execpath bin/portosaurus.mjs build",
|
|
22
|
+
"serve": "$npm_execpath bin/portosaurus.mjs serve"
|
|
23
|
+
},
|
|
53
24
|
"dependencies": {
|
|
54
|
-
"@docusaurus/core": "^3.
|
|
55
|
-
"@docusaurus/preset-classic": "^3.
|
|
56
|
-
"@easyops-cn/docusaurus-search-local": "^0.52.
|
|
57
|
-
"
|
|
25
|
+
"@docusaurus/core": "^3.10.0",
|
|
26
|
+
"@docusaurus/preset-classic": "^3.10.0",
|
|
27
|
+
"@easyops-cn/docusaurus-search-local": "^0.52.1",
|
|
28
|
+
"@mdx-js/react": "^3.1.1",
|
|
29
|
+
"chalk": "^5.4.1",
|
|
58
30
|
"clsx": "^2.1.1",
|
|
59
|
-
"commander": "^
|
|
60
|
-
"favicons": "
|
|
61
|
-
"
|
|
31
|
+
"commander": "^13.1.0",
|
|
32
|
+
"favicons": "7.2.0",
|
|
33
|
+
"framer-motion": "^12.38.0",
|
|
62
34
|
"plugin-image-zoom": "github:flexanalytics/plugin-image-zoom",
|
|
63
35
|
"prism-react-renderer": "^2.4.1",
|
|
64
|
-
"
|
|
65
|
-
"react": "^18.
|
|
66
|
-
"react-dom": "^18.3.1",
|
|
36
|
+
"react": "^18.0.0",
|
|
37
|
+
"react-dom": "^18.0.0",
|
|
67
38
|
"react-icons": "^5.5.0",
|
|
68
|
-
"react-
|
|
39
|
+
"react-pdf": "^10.4.1",
|
|
40
|
+
"react-rnd": "^10.5.3",
|
|
41
|
+
"react-slick": "^0.31.0",
|
|
42
|
+
"sharp": "^0.34.4",
|
|
69
43
|
"slick-carousel": "^1.8.1"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@docusaurus/module-type-aliases": "^3.10.0",
|
|
47
|
+
"@docusaurus/types": "^3.10.0"
|
|
48
|
+
},
|
|
49
|
+
"browserslist": {
|
|
50
|
+
"production": [
|
|
51
|
+
">0.5%",
|
|
52
|
+
"not dead",
|
|
53
|
+
"not op_mini all"
|
|
54
|
+
],
|
|
55
|
+
"development": [
|
|
56
|
+
"last 3 chrome version",
|
|
57
|
+
"last 3 firefox version",
|
|
58
|
+
"last 5 safari version"
|
|
59
|
+
]
|
|
60
|
+
},
|
|
61
|
+
"engines": {
|
|
62
|
+
"node": ">=20.0"
|
|
70
63
|
}
|
|
71
64
|
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
2
|
+
<svg stroke="#fab387" fill="#2e8555" stroke-width="0" viewBox="0 0 448 512" color="#fab387" style="color:#fab387" height="24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M162.4 196c4.8-4.9 6.2-5.1 36.4-5.1 27.2 0 28.1.1 32.1 2.1 5.8 2.9 8.3 7 8.3 13.6 0 5.9-2.4 10-7.6 13.4-2.8 1.8-4.5 1.9-31.1 2.1-16.4.1-29.5-.2-31.5-.8-10.3-2.9-14.1-17.7-6.6-25.3zm61.4 94.5c-53.9 0-55.8.2-60.2 4.1-3.5 3.1-5.7 9.4-5.1 13.9.7 4.7 4.8 10.1 9.2 12 2.2 1 14.1 1.7 56.3 1.2l47.9-.6 9.2-1.5c9-5.1 10.5-17.4 3.1-24.4-5.3-4.7-5-4.7-60.4-4.7zm223.4 130.1c-3.5 28.4-23 50.4-51.1 57.5-7.2 1.8-9.7 1.9-172.9 1.8-157.8 0-165.9-.1-172-1.8-8.4-2.2-15.6-5.5-22.3-10-5.6-3.8-13.9-11.8-17-16.4-3.8-5.6-8.2-15.3-10-22C.1 423 0 420.3 0 256.3 0 93.2 0 89.7 1.8 82.6 8.1 57.9 27.7 39 53 33.4c7.3-1.6 332.1-1.9 340-.3 21.2 4.3 37.9 17.1 47.6 36.4 7.7 15.3 7-1.5 7.3 180.6.2 115.8 0 164.5-.7 170.5zm-85.4-185.2c-1.1-5-4.2-9.6-7.7-11.5-1.1-.6-8-1.3-15.5-1.7-12.4-.6-13.8-.8-17.8-3.1-6.2-3.6-7.9-7.6-8-18.3 0-20.4-8.5-39.4-25.3-56.5-12-12.2-25.3-20.5-40.6-25.1-3.6-1.1-11.8-1.5-39.2-1.8-42.9-.5-52.5.4-67.1 6.2-27 10.7-46.3 33.4-53.4 62.4-1.3 5.4-1.6 14.2-1.9 64.3-.4 62.8 0 72.1 4 84.5 9.7 30.7 37.1 53.4 64.6 58.4 9.2 1.7 122.2 2.1 133.7.5 20.1-2.7 35.9-10.8 50.7-25.9 10.7-10.9 17.4-22.8 21.8-38.5 3.2-10.9 2.9-88.4 1.7-93.9z"></path></svg>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
2
|
+
<path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" />
|
|
3
|
+
<polyline points="15 3 21 3 21 9" />
|
|
4
|
+
<line x1="10" y1="14" x2="21" y2="3" />
|
|
5
|
+
</svg>
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
2
|
+
<svg stroke="#fab387" fill="#2e8555" stroke-width="0" viewBox="0 0 448 512" color="#fab387" style="color:#fab387" height="24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M162.4 196c4.8-4.9 6.2-5.1 36.4-5.1 27.2 0 28.1.1 32.1 2.1 5.8 2.9 8.3 7 8.3 13.6 0 5.9-2.4 10-7.6 13.4-2.8 1.8-4.5 1.9-31.1 2.1-16.4.1-29.5-.2-31.5-.8-10.3-2.9-14.1-17.7-6.6-25.3zm61.4 94.5c-53.9 0-55.8.2-60.2 4.1-3.5 3.1-5.7 9.4-5.1 13.9.7 4.7 4.8 10.1 9.2 12 2.2 1 14.1 1.7 56.3 1.2l47.9-.6 9.2-1.5c9-5.1 10.5-17.4 3.1-24.4-5.3-4.7-5-4.7-60.4-4.7zm223.4 130.1c-3.5 28.4-23 50.4-51.1 57.5-7.2 1.8-9.7 1.9-172.9 1.8-157.8 0-165.9-.1-172-1.8-8.4-2.2-15.6-5.5-22.3-10-5.6-3.8-13.9-11.8-17-16.4-3.8-5.6-8.2-15.3-10-22C.1 423 0 420.3 0 256.3 0 93.2 0 89.7 1.8 82.6 8.1 57.9 27.7 39 53 33.4c7.3-1.6 332.1-1.9 340-.3 21.2 4.3 37.9 17.1 47.6 36.4 7.7 15.3 7-1.5 7.3 180.6.2 115.8 0 164.5-.7 170.5zm-85.4-185.2c-1.1-5-4.2-9.6-7.7-11.5-1.1-.6-8-1.3-15.5-1.7-12.4-.6-13.8-.8-17.8-3.1-6.2-3.6-7.9-7.6-8-18.3 0-20.4-8.5-39.4-25.3-56.5-12-12.2-25.3-20.5-40.6-25.1-3.6-1.1-11.8-1.5-39.2-1.8-42.9-.5-52.5.4-67.1 6.2-27 10.7-46.3 33.4-53.4 62.4-1.3 5.4-1.6 14.2-1.9 64.3-.4 62.8 0 72.1 4 84.5 9.7 30.7 37.1 53.4 64.6 58.4 9.2 1.7 122.2 2.1 133.7.5 20.1-2.7 35.9-10.8 50.7-25.9 10.7-10.9 17.4-22.8 21.8-38.5 3.2-10.9 2.9-88.4 1.7-93.9z"></path></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" image-rendering="optimizeQuality" fill-rule="evenodd" clip-rule="evenodd" viewBox="0 0 509 511.54"><path fill-rule="nonzero" d="M447.19 347.03c0-17.06 13.85-30.91 30.91-30.91 17.05 0 30.9 13.85 30.9 30.91v87.82c0 21.08-8.63 40.29-22.51 54.18-13.88 13.88-33.09 22.51-54.18 22.51H76.69c-21.09 0-40.3-8.63-54.18-22.51C8.63 475.14 0 455.93 0 434.85V76.69c0-21.09 8.63-40.3 22.51-54.18C36.39 8.63 55.6 0 76.69 0h86.98c17.06 0 30.9 13.85 30.9 30.9 0 17.06-13.84 30.91-30.9 30.91H76.69c-4.07 0-7.82 1.69-10.51 4.37-2.68 2.69-4.37 6.44-4.37 10.51v358.16c0 4.06 1.69 7.82 4.37 10.5 2.69 2.68 6.44 4.38 10.51 4.38h355.62c4.07 0 7.82-1.7 10.51-4.38 2.68-2.68 4.37-6.44 4.37-10.5v-87.82zm0-243.56L308.15 244.28c-11.91 12.12-31.45 12.28-43.56.37-12.11-11.91-12.28-31.45-.37-43.56L401.77 61.81H309.7c-17.06 0-30.9-13.85-30.9-30.91 0-17.05 13.84-30.9 30.9-30.9h168.4C495.15 0 509 13.85 509 30.9v165.04c0 17.06-13.85 30.9-30.9 30.9-17.06 0-30.91-13.84-30.91-30.9v-92.47z"/></svg>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="3" stroke-linecap="round" stroke-linejoin="round">
|
|
2
|
+
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
|
|
3
|
+
<polyline points="7 10 12 15 17 10" />
|
|
4
|
+
<line x1="12" y1="15" x2="12" y2="3" />
|
|
5
|
+
</svg>
|