portosaurus 1.14.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.
Files changed (57) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +116 -0
  3. package/bin/portosaurus.js +337 -0
  4. package/internal/notes/index.md +10 -0
  5. package/internal/sidebars.js +20 -0
  6. package/internal/src/components/AboutSection/index.js +67 -0
  7. package/internal/src/components/AboutSection/styles.module.css +492 -0
  8. package/internal/src/components/ContactSection/index.js +94 -0
  9. package/internal/src/components/ContactSection/styles.module.css +327 -0
  10. package/internal/src/components/ExperienceSection/index.js +25 -0
  11. package/internal/src/components/ExperienceSection/styles.module.css +180 -0
  12. package/internal/src/components/HeroSection/index.js +61 -0
  13. package/internal/src/components/HeroSection/styles.module.css +471 -0
  14. package/internal/src/components/NoteIndex/index.js +127 -0
  15. package/internal/src/components/NoteIndex/styles.module.css +143 -0
  16. package/internal/src/components/ProjectsSection/index.js +529 -0
  17. package/internal/src/components/ProjectsSection/styles.module.css +830 -0
  18. package/internal/src/components/ScrollToTop/index.js +98 -0
  19. package/internal/src/components/ScrollToTop/styles.module.css +96 -0
  20. package/internal/src/components/SocialLinks/index.js +129 -0
  21. package/internal/src/components/SocialLinks/styles.module.css +55 -0
  22. package/internal/src/components/Tooltip/index.js +30 -0
  23. package/internal/src/components/Tooltip/styles.module.css +92 -0
  24. package/internal/src/config/iconMappings.js +329 -0
  25. package/internal/src/config/metaTags.js +240 -0
  26. package/internal/src/config/prism.js +179 -0
  27. package/internal/src/config/sidebar.js +20 -0
  28. package/internal/src/css/bootstrap.css +6 -0
  29. package/internal/src/css/catppuccin.css +632 -0
  30. package/internal/src/css/custom.css +186 -0
  31. package/internal/src/css/tasks.css +868 -0
  32. package/internal/src/pages/index.js +98 -0
  33. package/internal/src/pages/notes.js +88 -0
  34. package/internal/src/pages/tasks.js +310 -0
  35. package/internal/src/utils/HashNavigation.js +250 -0
  36. package/internal/src/utils/appVersion.js +27 -0
  37. package/internal/src/utils/compileConfig.js +82 -0
  38. package/internal/src/utils/cssUtils.js +99 -0
  39. package/internal/src/utils/filterEnabledItems.js +21 -0
  40. package/internal/src/utils/generateFavicon.js +256 -0
  41. package/internal/src/utils/generateRobotsTxt.js +97 -0
  42. package/internal/src/utils/iconExtractor.js +159 -0
  43. package/internal/src/utils/imageDownloader.js +88 -0
  44. package/internal/src/utils/imageProcessor.js +134 -0
  45. package/internal/src/utils/linkShortner.js +0 -0
  46. package/internal/src/utils/updateTitle.js +107 -0
  47. package/package.json +51 -0
  48. package/template/.github/workflows/deploy.yml +57 -0
  49. package/template/README.md +70 -0
  50. package/template/blog/authors.yml +5 -0
  51. package/template/blog/welcome.md +10 -0
  52. package/template/config.js +233 -0
  53. package/template/notes/getting-started.md +7 -0
  54. package/template/static/README.md +33 -0
  55. package/utils/createConfig.js +227 -0
  56. package/utils/logger.js +19 -0
  57. package/utils/packageManager.js +88 -0
@@ -0,0 +1,33 @@
1
+ # Static Assets
2
+
3
+ Place your static files here. Everything in this directory will be copied to the root of your built website.
4
+
5
+ ## Common Files
6
+
7
+ - **Binaries/scripts:** Install scripts or binaries
8
+ - **Favicon:** `favicon.ico` or `favicon.png`
9
+ - **Images:** `img/` directory for site images
10
+ - **Documents:** PDFs, downloads, etc.
11
+ - **robots.txt:** Search engine instructions
12
+ - **CNAME:** Custom domain configuration (for GitHub Pages)
13
+
14
+ ## Example Structure
15
+
16
+ ```
17
+ static/
18
+ ├── favicon.ico
19
+ ├── img/
20
+ │ ├── logo.svg
21
+ │ └── social-card.jpg
22
+ ├── downloads/
23
+ │ └── resume.pdf
24
+ └── robots.txt
25
+ ```
26
+
27
+ ## Usage
28
+
29
+ Files in this directory are served at the root URL:
30
+
31
+ - `static/favicon.ico` → `https://yoursite.com/favicon.ico`
32
+ - `static/img/logo.svg` → `https://yoursite.com/img/logo.svg`
33
+ - `static/downloads/resume.pdf` → `https://yoursite.com/downloads/resume.pdf`
@@ -0,0 +1,227 @@
1
+ import { themes } from "prism-react-renderer";
2
+ import { createRequire } from "module";
3
+ import path from "path";
4
+ import { fileURLToPath } from "url";
5
+
6
+ const require = createRequire(import.meta.url);
7
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
8
+
9
+ const internalUtils = path.resolve(__dirname, "../internal/src/utils");
10
+
11
+ /**
12
+ * Resolves the site URL based on config value and environment.
13
+ * @param {string} configValue - The site_url value from user config.
14
+ * @returns {string} Resolved URL.
15
+ */
16
+ function resolveSiteUrl(configValue) {
17
+ if (configValue === "auto") {
18
+ if (process.env.GITHUB_ACTIONS === "true") {
19
+ const repoOwner = process.env.GITHUB_REPOSITORY_OWNER;
20
+ return `https://${repoOwner}.github.io`;
21
+ }
22
+ return "http://localhost";
23
+ }
24
+ return configValue;
25
+ }
26
+
27
+ /**
28
+ * Resolves the base path based on config value and environment.
29
+ * @param {string} configValue - The site_path value from user config.
30
+ * @returns {string} Resolved base path.
31
+ */
32
+ function resolveBasePath(configValue) {
33
+ if (configValue === "auto") {
34
+ if (process.env.GITHUB_ACTIONS === "true") {
35
+ const repoName = process.env.GITHUB_REPOSITORY?.split("/")[1];
36
+ const repoOwner = process.env.GITHUB_REPOSITORY_OWNER;
37
+
38
+ // User/org pages use root path, project pages use /repo-name/
39
+ return repoName === `${repoOwner}.github.io` ? "/" : `/${repoName}/`;
40
+ }
41
+ return "/";
42
+ }
43
+ return configValue;
44
+ }
45
+
46
+ /**
47
+ * Creates a Docusaurus config from the Portosaurus user config.
48
+ * @param {Object} userConfig - The user configuration object (export of config.js).
49
+ * @returns {Object} Docusaurus configuration object.
50
+ **/
51
+ export function createConfig(userConfig, projectRoot = process.cwd()) {
52
+ const usrConf = userConfig.usrConf || {};
53
+
54
+ //------------- Basic mapping -------------
55
+
56
+ const projName = usrConf.hero_section?.title || "Portosaurus Site";
57
+ const projDesc =
58
+ usrConf.hero_section?.description ||
59
+ "Complete portfolio cum personal website solution for your digital personality.";
60
+
61
+ const siteUrl = resolveSiteUrl(usrConf.site_url);
62
+ const sitePath = resolveBasePath(usrConf.site_path);
63
+ const faviconPath =
64
+ usrConf.hero_section?.profile_pic || "https://github.com/soymadip.png";
65
+
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");
73
+
74
+ // ---------- Docusaurus Config -----------
75
+ const config = {
76
+ projectName: projName,
77
+
78
+ title: projName,
79
+ tagline: projDesc,
80
+
81
+ favicon: faviconPath,
82
+ url: siteUrl,
83
+ baseUrl: sitePath,
84
+
85
+ onBrokenLinks: "warn",
86
+ organizationName: projName,
87
+
88
+ customFields: {
89
+ heroSection: usrConf.hero_section || {},
90
+ aboutMe: usrConf.about_section || {},
91
+ projects: usrConf.projects_section || {},
92
+ socialLinks: usrConf.social_links || {},
93
+ experience: usrConf.experience_section || {},
94
+ tasksPage: usrConf.tasks_page || {},
95
+ },
96
+
97
+ // Markdown configuration
98
+ markdown: {
99
+ hooks: {
100
+ onBrokenMarkdownLinks: "warn",
101
+ },
102
+ },
103
+
104
+ presets: [
105
+ [
106
+ "classic",
107
+ /** @type {import('@docusaurus/preset-classic').Options} */
108
+ ({
109
+ docs: {
110
+ path: notesPath,
111
+ routeBasePath: "notes",
112
+ sidebarPath: "./sidebars.js", // Inside .portosaurus
113
+ // editUrl: '...',
114
+ },
115
+ blog: {
116
+ path: blogPath,
117
+ showReadingTime: true,
118
+ onUntruncatedBlogPosts: "ignore",
119
+ // editUrl: '...',
120
+ },
121
+ theme: {
122
+ customCss: "./src/css/custom.css", // Inside .portosaurus
123
+ },
124
+ }),
125
+ ],
126
+ ],
127
+
128
+ staticDirectories: [staticPath],
129
+
130
+ themeConfig:
131
+ /** @type {import('@docusaurus/preset-classic').ThemeConfig} */
132
+ ({
133
+ // Replace with your project's social card
134
+ image: usrConf.social_card || "img/social-card.jpg",
135
+
136
+ docs: {
137
+ sidebar: {
138
+ hideable: usrConf.collapsable_sidebar ?? true,
139
+ },
140
+ },
141
+
142
+ imageZoom: {
143
+ options: {
144
+ margin: 2,
145
+ background: "rgba(var(--ifm-background-color-rgb), 0.9)",
146
+ },
147
+ },
148
+
149
+ // Default: Dark mode
150
+ colorMode: {
151
+ defaultMode: usrConf.dark_mode ? "dark" : "light",
152
+ disableSwitch: usrConf.disable_theme_switch || false,
153
+ },
154
+
155
+ navbar: {
156
+ title: projName,
157
+ hideOnScroll: usrConf.hide_navbar_on_scroll ?? true,
158
+ logo: {
159
+ alt: "Logo",
160
+ src: usrConf.hero_section?.profile_pic || "img/logo.svg",
161
+ },
162
+ items: [
163
+ // Search will be added by plugin
164
+ {
165
+ type: "search",
166
+ position: "right",
167
+ className: "navbar-search-bar",
168
+ },
169
+ {
170
+ // About/Projects/Experience handled by home page logic
171
+ label: "About Me",
172
+ to: "/#about",
173
+ position: "right",
174
+ },
175
+ {
176
+ label: "Projects",
177
+ to: "/#projects",
178
+ position: "right",
179
+ },
180
+ {
181
+ type: "docSidebar",
182
+ sidebarId: "notes",
183
+ position: "right",
184
+ label: "Notes",
185
+ },
186
+ { to: "/blog", label: "Blog", position: "right" },
187
+ // TODO: Add Tasks link
188
+ ],
189
+ },
190
+ footer: {
191
+ style: "dark",
192
+ links: [
193
+ // TODO: Add footer links based on config
194
+ ],
195
+ copyright: `Copyright © ${new Date().getFullYear()} ${projName}. Built with Portosaurus.`,
196
+ },
197
+ prism: {
198
+ theme: themes.github,
199
+ darkTheme: themes.dracula,
200
+ additionalLanguages: ["java", "php", "bash"],
201
+ },
202
+ }),
203
+
204
+ plugins: [
205
+ // require.resolve(`${internalUtils}/generateFavicon.js`),
206
+ require.resolve(`${internalUtils}/generateRobotsTxt.js`),
207
+ [
208
+ require.resolve("@easyops-cn/docusaurus-search-local"),
209
+ {
210
+ hashed: true,
211
+ indexDocs: true,
212
+ docsDir: notesPath,
213
+ blogDir: blogPath,
214
+ docsRouteBasePath: "notes",
215
+ highlightSearchTermsOnTargetPage: true,
216
+ explicitSearchResultPath: true,
217
+ hideSearchBarWithNoSearchContext: true,
218
+ searchContextByPaths: ["notes", "blog"],
219
+ language: ["en"],
220
+ },
221
+ ],
222
+ "plugin-image-zoom",
223
+ ],
224
+ };
225
+
226
+ return config;
227
+ }
@@ -0,0 +1,19 @@
1
+ import chalk from 'chalk';
2
+
3
+ export const logger = {
4
+ info: (msg) => {
5
+ console.log(`${chalk.blue('ℹ')} ${msg}`);
6
+ },
7
+ success: (msg) => {
8
+ console.log(`${chalk.green('✔')} ${msg}`);
9
+ },
10
+ warn: (msg) => {
11
+ console.log(`${chalk.yellow('⚠')} ${msg}`);
12
+ },
13
+ error: (msg) => {
14
+ console.error(`${chalk.red('✖')} ${msg}`);
15
+ },
16
+ tip: (msg) => {
17
+ console.log(`${chalk.cyan('💡')} ${msg}`);
18
+ }
19
+ };
@@ -0,0 +1,88 @@
1
+ import fs from "fs-extra";
2
+ import path from "path";
3
+ import { execSync } from "child_process";
4
+
5
+ /**
6
+ * Detect which package manager is being used in the project
7
+ **/
8
+ export function detectPackageManager(projectRoot) {
9
+ // Check for lockfiles
10
+ if (
11
+ fs.existsSync(path.join(projectRoot, "bun.lockb")) ||
12
+ fs.existsSync(path.join(projectRoot, "bun.lock"))
13
+ ) {
14
+ return "bun";
15
+ }
16
+ if (fs.existsSync(path.join(projectRoot, "pnpm-lock.yaml"))) {
17
+ return "pnpm";
18
+ }
19
+ if (fs.existsSync(path.join(projectRoot, "yarn.lock"))) {
20
+ return "yarn";
21
+ }
22
+ if (fs.existsSync(path.join(projectRoot, "package-lock.json"))) {
23
+ return "npm";
24
+ }
25
+
26
+ // Fallback: check which is available in PATH
27
+ const managers = ["bun", "pnpm", "yarn", "npm"];
28
+ for (const manager of managers) {
29
+ try {
30
+ execSync(`${manager} --version`, { stdio: "ignore" });
31
+ return manager;
32
+ } catch {
33
+ // Not available
34
+ }
35
+ }
36
+
37
+ return "npm"; // Ultimate fallback
38
+ }
39
+
40
+ /**
41
+ * Get the command to run a package binary
42
+ * Different package managers have different ways to run binaries
43
+ */
44
+ export function getRunCommand(packageManager, binaryName, args = []) {
45
+ switch (packageManager) {
46
+ case "bun":
47
+ // Bun can run binaries directly with `bun run`
48
+ return {
49
+ command: "bun",
50
+ args: ["run", binaryName, ...args],
51
+ };
52
+ case "pnpm":
53
+ // pnpm uses `pnpm exec`
54
+ return {
55
+ command: "pnpm",
56
+ args: ["exec", binaryName, ...args],
57
+ };
58
+ case "yarn":
59
+ // Yarn uses `yarn run`
60
+ return {
61
+ command: "yarn",
62
+ args: ["run", binaryName, ...args],
63
+ };
64
+ case "npm":
65
+ default:
66
+ // npm uses `npx`
67
+ return {
68
+ command: "npx",
69
+ args: [binaryName, ...args],
70
+ };
71
+ }
72
+ }
73
+
74
+ /**
75
+ * Find the docusaurus binary path
76
+ * Falls back to using package manager's run command if not found
77
+ */
78
+ export function findDocusaurusBin(projectRoot) {
79
+ const packageManager = detectPackageManager(projectRoot);
80
+ const runCmd = getRunCommand(packageManager, "docusaurus");
81
+
82
+ return {
83
+ type: "managed",
84
+ command: runCmd.command,
85
+ args: runCmd.args,
86
+ packageManager,
87
+ };
88
+ }