portosaurus 1.15.2 → 1.16.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.
Files changed (60) hide show
  1. package/README.md +30 -13
  2. package/bin/portosaurus.js +97 -48
  3. package/package.json +4 -4
  4. package/src/internal/README.md +3 -0
  5. package/src/template/README.md +82 -0
  6. package/src/template/blog/authors.yml +5 -0
  7. package/{template → src/template}/blog/welcome.md +1 -1
  8. package/{template/notes/getting-started.md → src/template/notes/welcome.md} +1 -0
  9. package/{utils → src/utils}/createConfig.js +14 -11
  10. package/{utils → src/utils}/packageManager.js +2 -1
  11. package/src/utils/ss.js +294 -0
  12. package/internal/src/config/sidebar.js +0 -20
  13. package/template/README.md +0 -70
  14. package/template/blog/authors.yml +0 -5
  15. /package/{internal → src/internal}/notes/index.md +0 -0
  16. /package/{internal → src/internal}/src/components/AboutSection/index.js +0 -0
  17. /package/{internal → src/internal}/src/components/AboutSection/styles.module.css +0 -0
  18. /package/{internal → src/internal}/src/components/ContactSection/index.js +0 -0
  19. /package/{internal → src/internal}/src/components/ContactSection/styles.module.css +0 -0
  20. /package/{internal → src/internal}/src/components/ExperienceSection/index.js +0 -0
  21. /package/{internal → src/internal}/src/components/ExperienceSection/styles.module.css +0 -0
  22. /package/{internal → src/internal}/src/components/HeroSection/index.js +0 -0
  23. /package/{internal → src/internal}/src/components/HeroSection/styles.module.css +0 -0
  24. /package/{internal → src/internal}/src/components/NoteIndex/index.js +0 -0
  25. /package/{internal → src/internal}/src/components/NoteIndex/styles.module.css +0 -0
  26. /package/{internal → src/internal}/src/components/ProjectsSection/index.js +0 -0
  27. /package/{internal → src/internal}/src/components/ProjectsSection/styles.module.css +0 -0
  28. /package/{internal → src/internal}/src/components/ScrollToTop/index.js +0 -0
  29. /package/{internal → src/internal}/src/components/ScrollToTop/styles.module.css +0 -0
  30. /package/{internal → src/internal}/src/components/SocialLinks/index.js +0 -0
  31. /package/{internal → src/internal}/src/components/SocialLinks/styles.module.css +0 -0
  32. /package/{internal → src/internal}/src/components/Tooltip/index.js +0 -0
  33. /package/{internal → src/internal}/src/components/Tooltip/styles.module.css +0 -0
  34. /package/{internal → src/internal}/src/config/iconMappings.js +0 -0
  35. /package/{internal → src/internal}/src/config/metaTags.js +0 -0
  36. /package/{internal → src/internal}/src/config/prism.js +0 -0
  37. /package/{internal → src/internal/src/config}/sidebars.js +0 -0
  38. /package/{internal → src/internal}/src/css/bootstrap.css +0 -0
  39. /package/{internal → src/internal}/src/css/catppuccin.css +0 -0
  40. /package/{internal → src/internal}/src/css/custom.css +0 -0
  41. /package/{internal → src/internal}/src/css/tasks.css +0 -0
  42. /package/{internal → src/internal}/src/pages/index.js +0 -0
  43. /package/{internal → src/internal}/src/pages/notes.js +0 -0
  44. /package/{internal → src/internal}/src/pages/tasks.js +0 -0
  45. /package/{internal → src/internal}/src/utils/HashNavigation.js +0 -0
  46. /package/{internal → src/internal}/src/utils/appVersion.js +0 -0
  47. /package/{internal → src/internal}/src/utils/compileConfig.js +0 -0
  48. /package/{internal → src/internal}/src/utils/cssUtils.js +0 -0
  49. /package/{internal → src/internal}/src/utils/filterEnabledItems.js +0 -0
  50. /package/{internal → src/internal}/src/utils/generateFavicon.js +0 -0
  51. /package/{internal → src/internal}/src/utils/generateRobotsTxt.js +0 -0
  52. /package/{internal → src/internal}/src/utils/iconExtractor.js +0 -0
  53. /package/{internal → src/internal}/src/utils/imageDownloader.js +0 -0
  54. /package/{internal → src/internal}/src/utils/imageProcessor.js +0 -0
  55. /package/{internal → src/internal}/src/utils/linkShortner.js +0 -0
  56. /package/{internal → src/internal}/src/utils/updateTitle.js +0 -0
  57. /package/{template → src/template}/.github/workflows/deploy.yml +0 -0
  58. /package/{template → src/template}/config.js +0 -0
  59. /package/{template → src/template}/static/README.md +0 -0
  60. /package/{utils → src/utils}/logger.js +0 -0
package/README.md CHANGED
@@ -37,10 +37,10 @@ npx portosaurus init my-portfolio
37
37
 
38
38
  **Options:**
39
39
 
40
- - `-gh`: Automatically sets up GitHub Actions workflow for deployment.
41
- - `--install`: Installs dependencies automatically.
40
+ - `-ngh, --no-github-pages`: Skip setting up GitHub Actions workflow for deployment.
41
+ - `-ni, --no-install`: Skip automatic dependency installation.
42
42
 
43
- ### 2. Start Development
43
+ ### 2. Start Development Server
44
44
 
45
45
  Navigate to your project and start the development server:
46
46
 
@@ -58,6 +58,26 @@ Your site will be available at `http://localhost:3000`.
58
58
 
59
59
  ### 3. Build & Deploy
60
60
 
61
+ #### GitHub Pages
62
+
63
+ 1. Create a repository on GitHub named `yourUsername.github.io`.
64
+ 2. Go to the repo's `Settings` > `Pages` > `Build and deployment` > `Source` > **`GitHub Actions`**.
65
+ 3. Push your code:
66
+ ```bash
67
+ git remote add origin https://github.com/yourUsername/yourUsername.github.io.git
68
+ git branch -M main
69
+ git push -u origin main
70
+ ```
71
+
72
+ #### Other Providers
73
+
74
+ A portosaurus project can be deployed to any static hosting provider like:
75
+
76
+ - Netlify
77
+ - Vercel
78
+ - Cloudflare Pages
79
+ - Other static providers
80
+
61
81
  To generate the static site for production:
62
82
 
63
83
  ```bash
@@ -70,18 +90,15 @@ npm run build
70
90
 
71
91
  The output will be in the `build/` directory.
72
92
 
73
- #### GitHub Pages (Automated)
93
+ To preview the production build locally:
74
94
 
75
- If you used the `-gh` flag during init, just push to your repository:
95
+ ```bash
96
+ # With Bun
97
+ bun run serve
76
98
 
77
- 1. Create a repository on GitHub.
78
- 2. Push your code:
79
- ```bash
80
- git remote add origin https://github.com/username/repo.git
81
- git branch -M main
82
- git push -u origin main
83
- ```
84
- 3. Go to GitHub Settings > Pages > Build and deployment > Source > **GitHub Actions**.
99
+ # With npm
100
+ npm run serve
101
+ ```
85
102
 
86
103
  <br>
87
104
 
@@ -18,8 +18,8 @@ import { fileURLToPath } from "url";
18
18
  import { spawn, execSync } from "child_process";
19
19
  import { createRequire } from "module";
20
20
 
21
- import { logger } from "../utils/logger.js";
22
- import { createConfig } from "../utils/createConfig.js";
21
+ import { logger } from "../src/utils/logger.js";
22
+ import { createConfig } from "../src/utils/createConfig.js";
23
23
 
24
24
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
25
25
 
@@ -32,14 +32,18 @@ const program = new Command();
32
32
  program
33
33
  .name("portosaurus")
34
34
  .description("CLI for Portosaurus - The complete portfolio solution")
35
- .version(
36
- packageJson.version,
37
- "-v, --version",
38
- "output the current version",
39
- );
35
+ .version(packageJson.version, "-v, --version", "output the current version");
40
36
 
41
37
  // ----------- HELPERS -------------
42
38
 
39
+ // Helper to clean up internal index.md from user notes
40
+ function cleanUserNotesIndex(projectRoot) {
41
+ const userNotesIndex = path.join(projectRoot, "notes", "index.md");
42
+ if (existsSync(userNotesIndex)) {
43
+ removeSync(userNotesIndex);
44
+ }
45
+ }
46
+
43
47
  async function prepareDocusaurusRun(projectRoot) {
44
48
  const configPath = path.join(projectRoot, "config.js");
45
49
 
@@ -52,36 +56,42 @@ async function prepareDocusaurusRun(projectRoot) {
52
56
  }
53
57
 
54
58
  // Ensure internal files are synced to .portosaurus
55
- const internalSrc = path.join(__dirname, "../internal/src");
56
- const internalSidebars = path.join(__dirname, "../internal/sidebars.js");
57
- const internalNotesIndex = path.join(__dirname, "../internal/notes/index.md");
58
-
59
- const dotPorto = path.join(projectRoot, ".portosaurus");
60
- const userSrc = path.join(dotPorto, "src");
61
- const userSidebars = path.join(dotPorto, "sidebars.js");
62
-
63
- // Ensure .portosaurus exists
64
- fs.ensureDirSync(dotPorto);
65
-
66
- // Always copy/overwrite src/
67
- fs.copySync(internalSrc, userSrc);
68
-
69
- // Always copy/overwrite sidebars.js
70
- fs.copySync(internalSidebars, userSidebars);
71
-
72
- // Ensure user has essential folders
73
- const userRootNotes = path.join(projectRoot, "notes");
74
- const userRootBlog = path.join(projectRoot, "blog");
75
- const userRootStatic = path.join(projectRoot, "static");
76
-
77
- fs.ensureDirSync(userRootNotes);
78
- fs.ensureDirSync(userRootBlog);
79
- fs.ensureDirSync(userRootStatic);
80
-
81
- // Always ensure index.md exists (framework-managed file)
82
- const userNotesIndex = path.join(userRootNotes, "index.md");
83
- if (!fs.existsSync(userNotesIndex)) {
84
- fs.copySync(internalNotesIndex, userNotesIndex);
59
+ const internalDir = path.join(__dirname, "../src/internal");
60
+ const runtimeDir = path.join(projectRoot, ".portosaurus");
61
+
62
+ // Ensure .portosaurus exists and is clean
63
+ fs.emptyDirSync(runtimeDir);
64
+
65
+ // Ensure user has essential folders in project root
66
+ fs.ensureDirSync(path.join(projectRoot, "notes"));
67
+ fs.ensureDirSync(path.join(projectRoot, "blog"));
68
+ fs.ensureDirSync(path.join(projectRoot, "static"));
69
+
70
+ // 1. Copy everything from internal to .portosaurus
71
+ fs.copySync(internalDir, runtimeDir);
72
+
73
+ // 2. Overwrite with user files if they exist in project root
74
+ const syncItems = [
75
+ ...new Set([...readdirSync(internalDir), "blog", "static"]),
76
+ ];
77
+ for (const file of syncItems) {
78
+ const userFile = path.resolve(projectRoot, file);
79
+ const destFile = path.resolve(runtimeDir, file);
80
+
81
+ if (existsSync(userFile)) {
82
+ if (fs.statSync(userFile).isDirectory()) {
83
+ fs.ensureDirSync(destFile);
84
+ }
85
+ fs.copySync(userFile, destFile, {
86
+ overwrite: true,
87
+ filter: (src) => {
88
+ if (src.endsWith(path.join("notes", "index.md"))) {
89
+ return false;
90
+ }
91
+ return true;
92
+ },
93
+ });
94
+ }
85
95
  }
86
96
 
87
97
  // Load user config
@@ -110,7 +120,7 @@ async function prepareDocusaurusRun(projectRoot) {
110
120
  const docusaurusConfig = createConfig(userConfig, projectRoot);
111
121
 
112
122
  // Write temp config file INSIDE .portosaurus
113
- const tempConfigPath = path.join(dotPorto, "docusaurus.config.js");
123
+ const tempConfigPath = path.join(runtimeDir, "docusaurus.config.js");
114
124
 
115
125
  const configContent = `// Auto-generated by Portosaurus
116
126
  module.exports = ${JSON.stringify(docusaurusConfig, null, 2)};`;
@@ -118,12 +128,12 @@ module.exports = ${JSON.stringify(docusaurusConfig, null, 2)};`;
118
128
  writeFileSync(tempConfigPath, configContent);
119
129
  logger.success("Generated Docusaurus config in .portosaurus.");
120
130
 
121
- return { dotPorto };
131
+ return { runtimeDir };
122
132
  }
123
133
 
124
- async function runDocusaurus(command, args, dotPorto, projectRoot) {
134
+ async function runDocusaurus(command, args, runtimeDir, projectRoot) {
125
135
  // Detect package manager and find docusaurus binary
126
- const { findDocusaurusBin } = await import("../utils/packageManager.js");
136
+ const { findDocusaurusBin } = await import("../src/utils/packageManager.js");
127
137
  const docusaurus = findDocusaurusBin(projectRoot || process.cwd());
128
138
 
129
139
  logger.info(
@@ -132,7 +142,7 @@ async function runDocusaurus(command, args, dotPorto, projectRoot) {
132
142
 
133
143
  const child = spawn(
134
144
  docusaurus.command,
135
- [...docusaurus.args, command, dotPorto, ...args],
145
+ [...docusaurus.args, command, runtimeDir, ...args],
136
146
  {
137
147
  stdio: "inherit",
138
148
  cwd: projectRoot,
@@ -180,7 +190,7 @@ program
180
190
  mkdirSync(projectPath);
181
191
 
182
192
  // Copy template files
183
- const templatePath = path.resolve(__dirname, "../template");
193
+ const templatePath = path.resolve(__dirname, "../src/template");
184
194
 
185
195
  // Check if template exists (it might not be populated yet)
186
196
  if (!existsSync(templatePath)) {
@@ -213,6 +223,7 @@ program
213
223
  scripts: {
214
224
  dev: "portosaurus dev",
215
225
  start: "portosaurus start",
226
+ serve: "portosaurus serve",
216
227
  build: "portosaurus build",
217
228
  },
218
229
  dependencies: {
@@ -255,7 +266,7 @@ program
255
266
 
256
267
  // Detect package manager for install instructions
257
268
  const { detectPackageManager } =
258
- await import("../utils/packageManager.js");
269
+ await import("../src/utils/packageManager.js");
259
270
  const pm = detectPackageManager(projectPath) || "npm";
260
271
  const installCmd = pm === "npm" ? "npm install" : `${pm} install`;
261
272
  const runCmd = pm === "npm" ? "npm run" : `${pm} run`;
@@ -301,11 +312,13 @@ program
301
312
  const projectRoot = process.cwd();
302
313
  logger.info("Starting development server...");
303
314
  try {
304
- const { dotPorto } = await prepareDocusaurusRun(projectRoot);
305
- await runDocusaurus("start", [], dotPorto, projectRoot);
315
+ const { runtimeDir } = await prepareDocusaurusRun(projectRoot);
316
+ await runDocusaurus("start", [], runtimeDir, projectRoot);
306
317
  } catch (error) {
307
318
  logger.error(`Failed to start: ${error.message}`);
308
319
  process.exit(1);
320
+ } finally {
321
+ cleanUserNotesIndex(projectRoot);
309
322
  }
310
323
  });
311
324
 
@@ -319,12 +332,12 @@ program
319
332
  logger.info("Building Portosaurus site...");
320
333
 
321
334
  try {
322
- const { dotPorto } = await prepareDocusaurusRun(projectRoot);
335
+ const { runtimeDir } = await prepareDocusaurusRun(projectRoot);
323
336
 
324
337
  const buildDir = path.join(projectRoot, "build");
325
338
  const args = ["--out-dir", buildDir];
326
339
 
327
- await runDocusaurus("build", args, dotPorto, projectRoot);
340
+ await runDocusaurus("build", args, runtimeDir, projectRoot);
328
341
 
329
342
  // Create .nojekyll for GitHub Pages compatibility
330
343
  const nojekyllPath = path.join(buildDir, ".nojekyll");
@@ -338,6 +351,42 @@ program
338
351
  } catch (error) {
339
352
  logger.error(`Failed to build: ${error.message}`);
340
353
  process.exit(1);
354
+ } finally {
355
+ cleanUserNotesIndex(projectRoot);
356
+ }
357
+ });
358
+
359
+ // --- SERVE COMMAND ---
360
+
361
+ program
362
+ .command("serve")
363
+ .description("Serve the built static site locally")
364
+ .action(async () => {
365
+ const projectRoot = process.cwd();
366
+ logger.info("Serving Portosaurus site...");
367
+
368
+ try {
369
+ const { runtimeDir } = await prepareDocusaurusRun(projectRoot);
370
+ const buildDir = path.join(projectRoot, "build");
371
+
372
+ if (!existsSync(buildDir)) {
373
+ logger.error(
374
+ "Build directory not found. Run 'portosaurus build' first.",
375
+ );
376
+ process.exit(1);
377
+ }
378
+
379
+ await runDocusaurus(
380
+ "serve",
381
+ ["--dir", buildDir],
382
+ runtimeDir,
383
+ projectRoot,
384
+ );
385
+ } catch (error) {
386
+ logger.error(`Failed to serve: ${error.message}`);
387
+ process.exit(1);
388
+ } finally {
389
+ cleanUserNotesIndex(projectRoot);
341
390
  }
342
391
  });
343
392
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "portosaurus",
3
- "version": "1.15.2",
3
+ "version": "1.16.1",
4
4
  "author": "soymadip",
5
5
  "license": "GPL-3.0-only",
6
6
  "description": "Complete portfolio cum personal website solution for your digital personality.",
@@ -26,9 +26,9 @@
26
26
  },
27
27
  "files": [
28
28
  "bin/",
29
- "internal/",
30
- "template/",
31
- "utils/"
29
+ "src/internal/",
30
+ "src/template/",
31
+ "src/utils/"
32
32
  ],
33
33
  "dependencies": {
34
34
  "@docusaurus/core": "^3.9.2",
@@ -0,0 +1,3 @@
1
+ # Inernals
2
+
3
+ Everything in this dir will copied at runtime at portusaurus working dir and will be overriten if user has any duplicate file.
@@ -0,0 +1,82 @@
1
+ <br>
2
+ <div align="center">
3
+ <img src="https://raw.githubusercontent.com/soymadip/portosaurus/refs/heads/compiler/static/img/icon.png" width=90>
4
+ <h1>My Portfolio Site</h1>
5
+ <p>
6
+ Complete portfolio cum personal website for my digital personality
7
+ <br>
8
+ <small>Made with <a href="https://github.com/soymadip/portosaurus">Portosaurus</a></small>
9
+ </p>
10
+ </div>
11
+
12
+ ## Project Structure
13
+
14
+ ```
15
+ .
16
+ ├── config.js # Site configuration
17
+ ├── blog/ # Blog posts (Markdown/MDX)
18
+ ├── notes/ # Documentation (Markdown/MDX)
19
+ ├── static/ # Static assets (images, files, binaries)
20
+ └── package.json # Dependencies
21
+ ```
22
+
23
+ ## Configuration
24
+
25
+ Edit [`config.js`](./config.js) to customize your site. See the [Portosaurus documentation](https://github.com/soymadip/portosaurus#configuration) for all available options.
26
+
27
+ ## Development
28
+
29
+ Start the development server:
30
+
31
+ ```bash
32
+ # With Bun
33
+ bun run dev
34
+
35
+ # With npm
36
+ npm run dev
37
+ ```
38
+
39
+ The site will be available at `http://localhost:3000`.
40
+
41
+ ## Build & Deploy
42
+
43
+ ### GitHub Pages
44
+
45
+ 1. Create a repository on GitHub named `yourUsername.github.io`.
46
+ 2. Go to the repo's `Settings` > `Pages` > `Build and deployment` > `Source` > **`GitHub Actions`**.
47
+ 3. Push your code:
48
+ ```bash
49
+ git remote add origin https://github.com/yourUsername/yourUsername.github.io.git
50
+ git branch -M main
51
+ git push -u origin main
52
+ ```
53
+
54
+ ### Other Providers
55
+
56
+ A portosaurus project can be deployed to any static hosting provider like:
57
+
58
+ - Netlify
59
+ - Vercel
60
+ - Cloudflare pages
61
+ - Other static providers
62
+
63
+ To generate the static site for production:
64
+
65
+ ```bash
66
+ # With Bun
67
+ bun run build
68
+
69
+ # With npm
70
+ npm run build
71
+ ```
72
+
73
+ The output will be in the `build/` directory.
74
+
75
+ ---
76
+
77
+ <div align="center">
78
+
79
+ Made with [Portosaurus](https://github.com/soymadip/portosaurus)
80
+
81
+ <br>
82
+ </div>
@@ -0,0 +1,5 @@
1
+ you:
2
+ name: Your Name
3
+ title: Maintainer
4
+ url: https://github.com/yourUsername
5
+ image_url: https://github.com/yourUsername.png
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  slug: welcome
3
3
  title: Welcome
4
- authors: [soymadip]
4
+ authors: [you]
5
5
  tags: [hello, portosaurus]
6
6
  ---
7
7
 
@@ -1,4 +1,5 @@
1
1
  ---
2
+ title: getting-started
2
3
  sidebar_position: 1
3
4
  ---
4
5
 
@@ -5,9 +5,11 @@ import { fileURLToPath } from "url";
5
5
 
6
6
  const require = createRequire(import.meta.url);
7
7
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
8
-
9
8
  const internalUtils = path.resolve(__dirname, "../internal/src/utils");
10
9
 
10
+
11
+ //---------------------- helpers -------------------------
12
+
11
13
  /**
12
14
  * Resolves the site URL based on config value and environment.
13
15
  * @param {string} configValue - The site_url value from user config.
@@ -43,12 +45,15 @@ function resolveBasePath(configValue) {
43
45
  return configValue;
44
46
  }
45
47
 
48
+ //--------------------- Config Creation ---------------------
49
+
46
50
  /**
47
51
  * Creates a Docusaurus config from the Portosaurus user config.
48
52
  * @param {Object} userConfig - The user configuration object (export of config.js).
49
53
  * @returns {Object} Docusaurus configuration object.
50
54
  **/
51
55
  export function createConfig(userConfig, projectRoot = process.cwd()) {
56
+
52
57
  const usrConf = userConfig.usrConf || {};
53
58
 
54
59
  //------------- Basic mapping -------------
@@ -63,13 +68,11 @@ export function createConfig(userConfig, projectRoot = process.cwd()) {
63
68
  const faviconPath =
64
69
  usrConf.hero_section?.profile_pic || "https://github.com/soymadip.png";
65
70
 
66
- const title = usrConf.hero_section?.title || projName;
67
- const tagline = usrConf.hero_section?.description || projDesc;
68
-
69
- // Resolve paths relative to project root (where config.js is)
70
- const notesPath = path.resolve(projectRoot, "notes");
71
- const blogPath = path.resolve(projectRoot, "blog");
72
- const staticPath = path.resolve(projectRoot, "static");
71
+ // Resolve paths relative to .portosaurus (the build context)
72
+ const runtimeDir = path.resolve(projectRoot, ".portosaurus");
73
+ const notesPath = path.resolve(runtimeDir, "notes");
74
+ const blogPath = path.resolve(runtimeDir, "blog");
75
+ const staticPath = path.resolve(runtimeDir, "static");
73
76
 
74
77
  // ---------- Docusaurus Config -----------
75
78
  const config = {
@@ -109,7 +112,7 @@ export function createConfig(userConfig, projectRoot = process.cwd()) {
109
112
  docs: {
110
113
  path: notesPath,
111
114
  routeBasePath: "notes",
112
- sidebarPath: "./sidebars.js", // Inside .portosaurus
115
+ sidebarPath: "./src/config/sidebars.js", // Inside .portosaurus
113
116
  // editUrl: '...',
114
117
  },
115
118
  blog: {
@@ -209,8 +212,8 @@ export function createConfig(userConfig, projectRoot = process.cwd()) {
209
212
  {
210
213
  hashed: true,
211
214
  indexDocs: true,
212
- docsDir: notesPath,
213
- blogDir: blogPath,
215
+ docsDir: "notes",
216
+ blogDir: "blog",
214
217
  docsRouteBasePath: "notes",
215
218
  highlightSearchTermsOnTargetPage: true,
216
219
  explicitSearchResultPath: true,
@@ -34,7 +34,7 @@ export function detectPackageManager(projectRoot) {
34
34
  }
35
35
  }
36
36
 
37
- return "npm"; // Ultimate fallback
37
+ return "npm"; // fallback
38
38
  }
39
39
 
40
40
  /**
@@ -44,6 +44,7 @@ export function detectPackageManager(projectRoot) {
44
44
  export function getRunCommand(packageManager, binaryName, args = []) {
45
45
  switch (packageManager) {
46
46
  case "bun":
47
+
47
48
  // Bun can run binaries directly with `bun run`
48
49
  return {
49
50
  command: "bun",
@@ -0,0 +1,294 @@
1
+ import { catppuccinMocha, catppuccinLatte } from "./src/config/prism.js";
2
+ import { appVersion } from "./src/utils/appVersion.js";
3
+ import { metaTags } from "./src/config/metaTags.js";
4
+ import { usrConf } from "./src/utils/compileConfig.js";
5
+ import { useEnabled } from "./src/utils/filterEnabledItems.js";
6
+
7
+ const projectName = "Portosaurus";
8
+ const projectVersion = appVersion();
9
+ const faviconPath = 'favicon/favicon.ico';
10
+ const iconPicPath = 'static/img/icon.png';
11
+
12
+ const config = {
13
+
14
+ projectName: `${projectName}`,
15
+
16
+ title: usrConf.hero_section.title || `${projectName}`,
17
+
18
+ tagline: usrConf.hero_section.tagline || "Your complete portfolio solution",
19
+
20
+ favicon: usrConf.favicon || `${faviconPath}`,
21
+
22
+ url: usrConf.site_url,
23
+ baseUrl: usrConf.site_path || "/",
24
+
25
+ // GH Pages config
26
+ organizationName: usrConf.hero_section.title || `${projectName} `,
27
+ deploymentBranch: "gh-pages",
28
+
29
+ onBrokenAnchors: "ignore",
30
+ onBrokenLinks: "warn",
31
+ // onBrokenMarkdownLinks: "warn",
32
+
33
+ i18n: {
34
+ defaultLocale: "en",
35
+ locales: ["en"],
36
+ },
37
+
38
+ headTags: metaTags,
39
+
40
+ customFields: {
41
+ version: `${projectVersion}`,
42
+
43
+ heroSection: {
44
+ profilePic: usrConf.hero_section.profile_pic || `${iconPicPath}`,
45
+ intro: usrConf.hero_section.intro || "Hello there, I'm",
46
+ title: usrConf.hero_section.title || "Your Name",
47
+ subtitle: usrConf.hero_section.subtitle || 'I am a',
48
+ profession: usrConf.hero_section.profession || 'Your Profession',
49
+ description: usrConf.hero_section.description || "Short description about your profession, passion, goals.",
50
+ learnMoreButtonTxt: usrConf.hero_section.learn__more_button_txt || "Learn More",
51
+ },
52
+
53
+ aboutMe: {
54
+ enable: usrConf.about_me.enable || true,
55
+
56
+ image: usrConf.about_me.image || `${iconPicPath}`,
57
+ description: usrConf.about_me.description || [
58
+ "I'm a passionate FOSS developer with expertise in designing and building solutions for real-world problems.",
59
+ "My journey in software development started with a simple desire to automate repetitive tasks, specially in my PC.",
60
+ ],
61
+ skills: usrConf.about_me.skills || ["skill 1", "Skill 2"],
62
+ resumeLink: usrConf.about_me.resume_link || "https://example.com/resume",
63
+ },
64
+
65
+ projects: usrConf.project_shelf,
66
+
67
+ experience: usrConf.experience,
68
+
69
+ socialLinks: {
70
+ enable: usrConf.social_links.enable || true,
71
+
72
+ links: usrConf.social_links.links || [
73
+ {
74
+ name: "Your Instagram",
75
+ icon: "instagram",
76
+ desc: "Your Instagram profile link",
77
+ url: "https://instagram.com/yourprofile",
78
+ },
79
+ ],
80
+ },
81
+
82
+ robotsTxt: {
83
+ enable: usrConf.robots_txt || true,
84
+ rules: [
85
+ {
86
+ disallow: ["/notes/", "/tasks/"],
87
+ },
88
+ ],
89
+ customLines: [],
90
+ },
91
+
92
+ tasksPage: {
93
+ enable: usrConf.tasks_page.enable || true,
94
+ title: usrConf.tasks_page.title || "Tasks",
95
+ description: usrConf.tasks_page.description || "Track your tasks and projects here.",
96
+ taskList: usrConf.tasks_page.tasks || [
97
+ {
98
+ title: "Example Tasks",
99
+ description: "Description of the task",
100
+ status: "active",
101
+ priority: "high",
102
+ },
103
+ ],
104
+ },
105
+ },
106
+
107
+ presets: [
108
+ [
109
+ "classic",
110
+ {
111
+ docs: {
112
+ routeBasePath: "notes",
113
+ path: "notes",
114
+ sidebarPath: "./src/config/sidebar.js",
115
+
116
+ admonitions: {
117
+ keywords: ["note", "tip", "info", "warning", "danger", "question"],
118
+ extendDefaults: true,
119
+ },
120
+ },
121
+
122
+ blog: {
123
+
124
+ feedOptions: usrConf.rss
125
+ ? {
126
+ type: ["rss", "atom"],
127
+ xslt: true,
128
+ }
129
+ : undefined,
130
+
131
+ showReadingTime: false,
132
+
133
+ onInlineTags: "warn",
134
+ onInlineAuthors: "warn",
135
+ onUntruncatedBlogPosts: "warn",
136
+ },
137
+
138
+ theme: {
139
+ customCss: "./src/css/custom.css",
140
+ },
141
+
142
+ },
143
+ ],
144
+ ],
145
+
146
+ // themes: ['@docusaurus/theme-mermaid'],
147
+ markdown: {
148
+ mermaid: true,
149
+ hooks: {
150
+ onBrokenMarkdownLinks: "warn"
151
+ }
152
+ },
153
+
154
+ themeConfig: {
155
+ // Social card
156
+ image: usrConf.social_card || "img/social-card.jpeg",
157
+
158
+ docs: {
159
+ sidebar: {
160
+ hideable: usrConf.collapsable_sidebar || true,
161
+ },
162
+ },
163
+
164
+ imageZoom: {
165
+ options: {
166
+ margin: 2,
167
+ background: "rgba(var(--ifm-background-color-rgb), 0.9)",
168
+ },
169
+ },
170
+
171
+ // Default: Dark mode
172
+ colorMode: {
173
+ defaultMode: usrConf.dark_mode ? "dark" : "light",
174
+ disableSwitch: usrConf.disable_theme_switch || false,
175
+ },
176
+
177
+ navbar: {
178
+ title: usrConf.hero_section.title || `${projectName} `,
179
+ hideOnScroll: usrConf.hide_navbar_on_scroll || true,
180
+
181
+ logo: {
182
+ alt: "Site Logo",
183
+ src: usrConf.favicon || `${faviconPath}`,
184
+ },
185
+
186
+ items: useEnabled([
187
+ {
188
+ type: "search",
189
+ position: "right",
190
+ className: "navbar-search-bar",
191
+ },
192
+ {
193
+ enable: usrConf.about_me?.enable || true,
194
+ value: {
195
+ label: "About Me",
196
+ to: "/#about",
197
+ position: "right",
198
+ activeBaseRegex: "^/#about",
199
+ },
200
+ },
201
+ {
202
+ enable: usrConf.project_shelf?.enable || true,
203
+ value: {
204
+ label: "Projects",
205
+ to: "/#projects",
206
+ position: "right",
207
+ activeBaseRegex: "^/#projects",
208
+ },
209
+ },
210
+ {
211
+ enable: usrConf.experience?.enable || false,
212
+ value: {
213
+ label: "Experience",
214
+ to: "/#experience",
215
+ position: "right",
216
+ activeBaseRegex: "^/#experience",
217
+ },
218
+ },
219
+ {
220
+ enable: usrConf.social_links?.enable || true,
221
+ value: {
222
+ label: "Contact",
223
+ to: "/#contact",
224
+ position: "right",
225
+ activeBaseRegex: "^/$contact",
226
+ },
227
+ },
228
+ {
229
+ type: "dropdown",
230
+ label: "More",
231
+ position: "right",
232
+ className: "_navbar-more-items",
233
+ items: useEnabled([
234
+ { label: "Notes", to: "/notes" },
235
+ { label: "Blog", to: "/blog" },
236
+ { label: "Tasks", to: "/tasks" },
237
+ {
238
+ enable: usrConf.disable_branding ? false : true,
239
+ value: {
240
+ label: `Portosaurus v${projectVersion}`,
241
+ className: "_nav-protosaurus-version",
242
+ to: "https://github.com/soymadip/portosaurus",
243
+ },
244
+ },
245
+ ]),
246
+ }
247
+ ]),
248
+ },
249
+
250
+ tableOfContents: {
251
+ minHeadingLevel: 2,
252
+ maxHeadingLevel: 4,
253
+ },
254
+
255
+ prism: {
256
+ theme: catppuccinLatte,
257
+ darkTheme: catppuccinMocha,
258
+ additionalLanguages: ["java", "php", "bash"],
259
+ },
260
+
261
+ footer: {
262
+ /* links: [
263
+ {
264
+ label: 'GitHub',
265
+ href: 'https://github.com/',
266
+ }
267
+ ],
268
+ copyright: `Copyright © ${new Date().getFullYear()} ` + ownerName,
269
+ */
270
+ },
271
+ },
272
+
273
+ plugins: [
274
+ require.resolve("./src/utils/generateFavicon"),
275
+ require.resolve("./src/utils/generateRobotsTxt"),
276
+ [
277
+ require.resolve("@easyops-cn/docusaurus-search-local"),
278
+ {
279
+ hashed: true,
280
+ indexDocs: true,
281
+ docsDir: "notes",
282
+ docsRouteBasePath: "notes",
283
+ highlightSearchTermsOnTargetPage: true,
284
+ explicitSearchResultPath: true,
285
+ hideSearchBarWithNoSearchContext: true,
286
+ searchContextByPaths: ["notes", "blog"],
287
+ language: ["en"],
288
+ },
289
+ ],
290
+ "plugin-image-zoom",
291
+ ],
292
+ };
293
+
294
+ export default config;
@@ -1,20 +0,0 @@
1
-
2
- const sidebar = {
3
-
4
- notes: [
5
- {
6
- type: 'category',
7
- label: 'Notes',
8
- link: { type: 'doc', id: 'index' },
9
- items: [
10
- {
11
- type: 'autogenerated',
12
- dirName: '.'
13
- }
14
- ]
15
- }
16
- ]
17
- };
18
-
19
-
20
- module.exports = sidebar;
@@ -1,70 +0,0 @@
1
- # Portosaurus Project
2
-
3
- A portfolio website built with [Portosaurus](https://github.com/soymadip/portosaurus).
4
-
5
- ## Getting Started
6
-
7
- ### Development
8
-
9
- Start the development server:
10
-
11
- ```bash
12
- # With Bun
13
- bun run dev
14
-
15
- # With npm
16
- npm run dev
17
- ```
18
-
19
- The site will be available at `http://localhost:3000`.
20
-
21
- ### Build
22
-
23
- Build the static site:
24
-
25
- ```bash
26
- # With Bun
27
- bun run build
28
-
29
- # With npm
30
- npm run build
31
- ```
32
-
33
- The output will be in the `build/` directory.
34
-
35
- ## Project Structure
36
-
37
- ```
38
- .
39
- ├── config.js # Site configuration
40
- ├── blog/ # Blog posts (Markdown)
41
- ├── notes/ # Documentation (Markdown)
42
- ├── static/ # Static assets (images, files)
43
- └── package.json # Dependencies
44
- ```
45
-
46
- ## Configuration
47
-
48
- Edit `config.js` to customize your site. See the [Portosaurus documentation](https://github.com/soymadip/portosaurus) for all available options.
49
-
50
- ## Deployment
51
-
52
- ### GitHub Pages
53
-
54
- 1. Push your project to GitHub
55
- 2. Go to Settings > Pages
56
- 3. Set Source to "GitHub Actions"
57
- 4. The site will deploy automatically on push
58
-
59
- ### Other Platforms
60
-
61
- The `build/` directory contains a static site that can be deployed to:
62
-
63
- - Vercel
64
- - Netlify
65
- - Cloudflare Pages
66
- - Any static hosting service
67
-
68
- ---
69
-
70
- Made with [Portosaurus](https://github.com/soymadip/portosaurus)
@@ -1,5 +0,0 @@
1
- soymadip:
2
- name: soymadip
3
- title: Maintainer
4
- url: https://github.com/soymadip
5
- image_url: https://github.com/soymadip.png
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes