portosaurus 2.1.5 → 2.1.7

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 (48) hide show
  1. package/package.json +5 -3
  2. package/src/cli/README.md +8 -0
  3. package/src/cli/build.mjs +1 -1
  4. package/src/cli/dev.mjs +1 -1
  5. package/src/cli/init.mjs +1 -1
  6. package/src/cli/serve.mjs +1 -1
  7. package/src/core/README.md +5 -0
  8. package/src/core/buildDocuConfig.mjs +32 -279
  9. package/src/plugins/README.md +8 -0
  10. package/src/{utils/build/generateFavicon.mjs → plugins/favicon.mjs} +50 -14
  11. package/src/{utils/build → plugins/lib}/cssUtils.mjs +1 -1
  12. package/src/{utils/build → plugins/lib}/iconExtractor.mjs +1 -1
  13. package/src/{utils/build → plugins/lib}/imageDownloader.mjs +1 -1
  14. package/src/{utils/build → plugins/lib}/imageProcessor.mjs +1 -1
  15. package/src/{utils/build/generateRobotsTxt.mjs → plugins/robots.mjs} +1 -1
  16. package/src/template/.docusaurus/docusaurus-plugin-content-blog/default/blog-post-list-prop-default.json +11 -0
  17. package/src/template/.docusaurus/docusaurus-plugin-content-blog/default/p/blog-archive-f05.json +1 -0
  18. package/src/template/.docusaurus/docusaurus-plugin-content-blog/default/p/blog-authors-790.json +1 -0
  19. package/src/template/.docusaurus/docusaurus-plugin-content-blog/default/p/blog-bd9.json +1 -0
  20. package/src/template/.docusaurus/docusaurus-plugin-content-blog/default/site-blog-ss-md-18f.json +16 -0
  21. package/src/template/.docusaurus/docusaurus-plugin-content-blog/default/site-blog-welcome-md-a95.json +34 -0
  22. package/src/template/.docusaurus/docusaurus-plugin-content-docs/default/p/notes-106.json +1 -0
  23. package/src/template/.docusaurus/docusaurus-plugin-content-docs/default/site-notes-index-mdx-3b5.json +16 -0
  24. package/src/template/.docusaurus/docusaurus-plugin-content-docs/default/site-notes-welcome-mdx-d34.json +14 -0
  25. package/src/template/.docusaurus/docusaurus-plugin-debug/default/p/docusaurus-debug-content-0d5.json +1 -0
  26. package/src/template/.docusaurus/globalData.json +29 -0
  27. package/src/template/.docusaurus/portosaurus/docusaurus.config.js +7 -0
  28. package/src/template/.docusaurus/registry.js +40 -0
  29. package/src/template/.docusaurus/routes.js +122 -0
  30. package/src/template/.docusaurus/routesChunkNames.json +156 -0
  31. package/src/template/config.js +1 -0
  32. package/src/template/gitignore +7 -0
  33. package/src/template/node_modules/.cache/webpack/client-development-en/0.pack +0 -0
  34. package/src/template/node_modules/.cache/webpack/client-development-en/1.pack +0 -0
  35. package/src/template/node_modules/.cache/webpack/client-development-en/2.pack +0 -0
  36. package/src/template/node_modules/.cache/webpack/client-development-en/3.pack +0 -0
  37. package/src/template/node_modules/.cache/webpack/client-development-en/4.pack +0 -0
  38. package/src/template/node_modules/.cache/webpack/client-development-en/5.pack +0 -0
  39. package/src/template/node_modules/.cache/webpack/client-development-en/6.pack +0 -0
  40. package/src/template/node_modules/.cache/webpack/client-development-en/7.pack +0 -0
  41. package/src/template/node_modules/.cache/webpack/client-development-en/index.pack +0 -0
  42. package/src/template/node_modules/.cache/webpack/client-development-en/index.pack.old +0 -0
  43. package/src/template/notes/index.mdx +9 -0
  44. package/src/theme/README.md +9 -0
  45. package/src/utils/README.md +8 -0
  46. package/src/utils/configUtils.mjs +238 -0
  47. /package/src/{core/plugins/themePlugin.mjs → plugins/theme.mjs} +0 -0
  48. /package/src/utils/{helpers.mjs → cliHelpers.mjs} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "portosaurus",
3
- "version": "2.1.5",
3
+ "version": "2.1.7",
4
4
  "private": false,
5
5
  "homepage": "https://github.com/soymadip/portosaurus",
6
6
  "repository": {
@@ -15,9 +15,11 @@
15
15
  "src/assets/",
16
16
  "src/cli/",
17
17
  "src/core/",
18
+ "src/plugins/",
19
+ "src/template/",
20
+ "src/template/.gitignore",
18
21
  "src/theme/",
19
- "src/utils/",
20
- "src/template/"
22
+ "src/utils/"
21
23
  ],
22
24
  "scripts": {
23
25
  "test": "bun test",
@@ -0,0 +1,8 @@
1
+ # Portosaurus CLI Commands
2
+
3
+ This directory contains the entry points for the `porto` CLI. Each command is implemented as an asynchronous function that handles project lifecycle tasks.
4
+
5
+ - **`init.mjs`**: Handles new project creation, template mirroring, and initial setup.
6
+ - **`dev.mjs`**: Wraps the Docusaurus development server, providing automatic config shimming and asset generation.
7
+ - **`build.mjs`**: Orchestrates production builds, ensuring the site is ready for deployment.
8
+ - **`serve.mjs`**: Provides a way to preview the production build locally.
package/src/cli/build.mjs CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  writePortoConfigShim,
8
8
  runDocusaurus,
9
9
  PortoRoot,
10
- } from "../utils/helpers.mjs";
10
+ } from "../utils/cliHelpers.mjs";
11
11
 
12
12
  export async function buildCommand(siteDir, extraArgs) {
13
13
  const UserRoot = siteDir
package/src/cli/dev.mjs CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  writePortoConfigShim,
8
8
  runDocusaurus,
9
9
  PortoRoot,
10
- } from "../utils/helpers.mjs";
10
+ } from "../utils/cliHelpers.mjs";
11
11
 
12
12
  export async function devCommand(siteDir, extraArgs) {
13
13
  const UserRoot = siteDir
package/src/cli/init.mjs CHANGED
@@ -2,7 +2,7 @@ import fs from "fs";
2
2
  import path from "path";
3
3
  import { logger } from "../utils/logger.mjs";
4
4
  import { getPackageManager } from "../utils/packageManager.mjs";
5
- import { PortoRoot, mirrorSync } from "../utils/helpers.mjs";
5
+ import { PortoRoot, mirrorSync } from "../utils/cliHelpers.mjs";
6
6
 
7
7
  export async function initCommand(projectName, options) {
8
8
  const projectDir = path.resolve(process.cwd(), projectName);
package/src/cli/serve.mjs CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  validateProject,
6
6
  writePortoConfigShim,
7
7
  runDocusaurus,
8
- } from "../utils/helpers.mjs";
8
+ } from "../utils/cliHelpers.mjs";
9
9
 
10
10
  export async function serveCommand(siteDir) {
11
11
  const UserRoot = siteDir
@@ -0,0 +1,5 @@
1
+ # Portosaurus Core Engine
2
+
3
+ This directory contains the central configuration engine that transforms user-provided settings into a valid Docusaurus configuration.
4
+
5
+ - **`buildDocuConfig.mjs`**: The main orchestration file. It deep-merges user configs with template defaults, resolves variable placeholders (`{{...}}`), and registers internal plugins and themes.
@@ -4,249 +4,19 @@ import { fileURLToPath } from "url";
4
4
  import { createRequire } from "module";
5
5
  import { logger } from "../utils/logger.mjs";
6
6
 
7
+ import {
8
+ deepMerge,
9
+ resolveVars,
10
+ resolveSiteUrl,
11
+ resolveBasePath,
12
+ getVersion,
13
+ useEnabled,
14
+ createStaticAssetResolver,
15
+ } from "../utils/configUtils.mjs";
16
+
7
17
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
8
18
  const PortoRoot = path.resolve(__dirname, "../../");
9
19
 
10
- // ─── Helpers ────────────────────────────────────────────────
11
-
12
- /**
13
- * Deep merge two objects. Source values override target values.
14
- * Arrays are replaced, not concatenated.
15
- */
16
- function deepMerge(target, source) {
17
- const result = { ...target };
18
-
19
- for (const key of Object.keys(source)) {
20
- if (
21
- source[key] &&
22
- typeof source[key] === "object" &&
23
- !Array.isArray(source[key]) &&
24
- target[key] &&
25
- typeof target[key] === "object" &&
26
- !Array.isArray(target[key])
27
- ) {
28
- result[key] = deepMerge(target[key], source[key]);
29
- } else if (source[key] !== undefined) {
30
- result[key] = source[key];
31
- }
32
- }
33
- return result;
34
- }
35
-
36
- /**
37
- * Resolve {{...}} template references and @alias/ path prefixes
38
- * inside config string values.
39
- *
40
- * Template refs: {{hero_section.profile_pic}} → resolves to the value
41
- * Path aliases: @porto/img/icon.png → img/icon.png (prefix stripped)
42
- *
43
- * @param {*} obj - The value (or tree) to resolve.
44
- * @param {Object} UserConfig - The full config object for {{...}} lookups.
45
- * @param {Object} aliases - Map of prefix → absolute directory path.
46
- * e.g. { "@porto/": "/abs/path/to/assets" }
47
- * @param {Set} pathStack - Internal: tracks {{...}} refs to prevent cycles.
48
- * @param {number} depth - Internal: recursion depth guard.
49
- */
50
- export function resolveVars(
51
- obj,
52
- UserConfig,
53
- aliases = {},
54
- pathStack = new Set(),
55
- depth = 0,
56
- ) {
57
- if (depth > 10) return obj;
58
-
59
- if (typeof obj === "string") {
60
- // If the entire string is exactly one {{tag}}, return the raw value
61
- const singleMatch = obj.match(/^\{\{([^}]+)\}\}$/);
62
-
63
- if (singleMatch && !obj.includes("{{", 2)) {
64
- const refPath = singleMatch[1];
65
- const parts = refPath.split(".");
66
- let val = UserConfig;
67
-
68
- for (const p of parts) {
69
- if (val == null || typeof val !== "object") break;
70
- val = val[p];
71
- }
72
- if (val !== undefined && val !== obj) {
73
- return resolveVars(val, UserConfig, aliases, pathStack, depth + 1);
74
- }
75
- }
76
-
77
- // Resolve {{...}} template variables
78
- let result = obj.replace(
79
- /(\\?)\{\{([^}]+)\}\}/g,
80
- (match, escape, refPath) => {
81
- // If escaped with \, return the literal {{tag}}
82
- if (escape === "\\") {
83
- return `{{${refPath}}}`;
84
- }
85
-
86
- // Check for circularity
87
- if (pathStack.has(refPath)) {
88
- return match;
89
- }
90
-
91
- const parts = refPath.split(".");
92
- let val = UserConfig;
93
-
94
- for (const p of parts) {
95
- if (val == null || typeof val !== "object") return match;
96
- val = val[p];
97
- }
98
-
99
- if (val === undefined) {
100
- return match;
101
- }
102
-
103
- // Recurse in case the resolved value also has template refs
104
- const newStack = new Set(pathStack);
105
- newStack.add(refPath);
106
-
107
- if (
108
- typeof val === "string" &&
109
- (val.includes("{{") || val.startsWith("@"))
110
- ) {
111
- return resolveVars(val, UserConfig, aliases, newStack, depth + 1);
112
- }
113
- return val;
114
- },
115
- );
116
-
117
- // Resolve @alias/ path prefixes
118
- for (const [prefix, dir] of Object.entries(aliases)) {
119
- if (result.startsWith(prefix)) {
120
- const relative = result.slice(prefix.length);
121
- if (dir && !fs.existsSync(path.resolve(dir, relative))) {
122
- logger.warn(`Asset not found: "${result}"`);
123
- }
124
- return relative;
125
- }
126
- }
127
-
128
- return result;
129
- }
130
-
131
- if (Array.isArray(obj)) {
132
- return obj.map((item) =>
133
- resolveVars(item, UserConfig, aliases, pathStack, depth),
134
- );
135
- }
136
-
137
- if (obj && typeof obj === "object") {
138
- const result = {};
139
- for (const [key, value] of Object.entries(obj)) {
140
- result[key] = resolveVars(value, UserConfig, aliases, pathStack, depth);
141
- }
142
- return result;
143
- }
144
- return obj;
145
- }
146
-
147
- /**
148
- * Resolves the site URL based on config value and environment.
149
- */
150
- function resolveSiteUrl(configValue) {
151
- if (configValue === "auto") {
152
- // GitLab Detection
153
- if (process.env.CI_PAGES_URL) {
154
- try {
155
- const url = new URL(process.env.CI_PAGES_URL);
156
- return `${url.protocol}//${url.host}`;
157
- } catch (e) {}
158
- }
159
-
160
- // GitHub/Gitea/Forgejo Detection
161
- if (process.env.GITHUB_ACTIONS === "true") {
162
- const serverUrl = process.env.GITHUB_SERVER_URL || "https://github.com";
163
-
164
- // GitHub specific logic
165
- if (serverUrl === "https://github.com") {
166
- const repoOwner = process.env.GITHUB_REPOSITORY_OWNER;
167
- return `https://${repoOwner}.github.io`;
168
- }
169
-
170
- // Forgejo/Gitea/Other Actions - Best effort based on instance URL
171
- try {
172
- const url = new URL(serverUrl);
173
- return `${url.protocol}//${url.host}`;
174
- } catch (e) {}
175
- }
176
-
177
- return "http://localhost";
178
- }
179
- return configValue;
180
- }
181
-
182
- /**
183
- * Resolves the base path based on config value and environment.
184
- */
185
- function resolveBasePath(configValue) {
186
- if (configValue === "auto") {
187
- // GitLab Detection
188
- if (process.env.CI_PAGES_URL) {
189
- try {
190
- const url = new URL(process.env.CI_PAGES_URL);
191
- return url.pathname.endsWith("/") ? url.pathname : `${url.pathname}/`;
192
- } catch (e) {}
193
- }
194
-
195
- // GitHub/Gitea/Forgejo Detection
196
- if (process.env.GITHUB_ACTIONS === "true") {
197
- const repo = process.env.GITHUB_REPOSITORY; // "owner/repo"
198
-
199
- if (!repo) {
200
- return "/";
201
- }
202
-
203
- const [owner, name] = repo.split("/");
204
- const serverUrl = process.env.GITHUB_SERVER_URL || "https://github.com";
205
-
206
- // GitHub User/Org Pages logic
207
- if (serverUrl === "https://github.com" && name === `${owner}.github.io`) {
208
- return "/";
209
- }
210
-
211
- return `/${name}/`;
212
- }
213
-
214
- return "/";
215
- }
216
- return configValue;
217
- }
218
-
219
- /**
220
- * Read the portosaurus package version.
221
- */
222
- function getVersion() {
223
- try {
224
- const pkgPath = path.resolve(PortoRoot, "package.json");
225
- const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
226
- return pkg.version || "0.0.0";
227
- } catch {
228
- return "N/A";
229
- }
230
- }
231
-
232
- /**
233
- * Filter items that have enable/value conditional structure.
234
- */
235
- function useEnabled(items) {
236
- if (!Array.isArray(items)) return [];
237
- return items.flatMap((item) => {
238
- if (
239
- item &&
240
- typeof item === "object" &&
241
- "enable" in item &&
242
- "value" in item
243
- ) {
244
- return item.enable === true ? [item.value] : [];
245
- }
246
- return [item];
247
- });
248
- }
249
-
250
20
  // ─── Main Config Generator ─────────────────────────────────
251
21
 
252
22
  /**
@@ -302,7 +72,9 @@ export function buildDocuConfig(rawUserConfig, UserRoot) {
302
72
  // Meta tags
303
73
  let PortoMetaTags = [];
304
74
  try {
305
- const meta = require(path.resolve(PortoRoot, "src/theme/config/metaTags.js"));
75
+ const meta = require(
76
+ path.resolve(PortoRoot, "src/theme/config/metaTags.js"),
77
+ );
306
78
  PortoMetaTags = meta.PortoMetaTags ?? meta.metaTags ?? [];
307
79
  } catch {
308
80
  // OK — no meta tags
@@ -322,39 +94,11 @@ export function buildDocuConfig(rawUserConfig, UserRoot) {
322
94
  * - Remote URLs (http/https) pass through as-is.
323
95
  * - Local paths are checked against UserStaticDir, then PortoAssetDir.
324
96
  */
325
- function resolveStaticAsset(userPath, portoFallback) {
326
- // Remote URLs are always valid
327
- if (userPath && /^https?:\/\//.test(userPath)) return userPath;
328
-
329
- // Check user's static directory
330
- if (userPath && fs.existsSync(path.resolve(UserStaticDir, userPath))) {
331
- return userPath;
332
- }
333
-
334
- // Check Porto's bundled assets
335
- if (userPath && fs.existsSync(path.resolve(PortoAssetDir, userPath))) {
336
- return userPath;
337
- }
338
-
339
- // Fallback logic with warnings
340
- if (portoFallback) {
341
- // Only warn if the fallback actually exists and they provided a bad path
342
- if (
343
- userPath &&
344
- userPath !== "favicon/favicon.ico" &&
345
- fs.existsSync(path.resolve(PortoAssetDir, portoFallback))
346
- ) {
347
- logger.warn(`Asset not found: "${userPath}" — using bundled default.`);
348
- }
349
- return portoFallback;
350
- }
351
-
352
- if (userPath && userPath !== "favicon/favicon.ico") {
353
- logger.warn(`Asset not found: "${userPath}" — no fallback available.`);
354
- }
355
-
356
- return userPath || "";
357
- }
97
+ const resolveStaticAsset = createStaticAssetResolver(
98
+ UserStaticDir,
99
+ PortoAssetDir,
100
+ );
101
+
358
102
 
359
103
  // Pages
360
104
  const PortoPagesDir = path.resolve(PortoRoot, "src/theme/pages");
@@ -374,7 +118,10 @@ export function buildDocuConfig(rawUserConfig, UserRoot) {
374
118
  projectName: UserConfig.hero_section.title,
375
119
  title: UserConfig.hero_section.title,
376
120
  tagline: UserConfig.hero_section.description,
377
- favicon: resolveStaticAsset(UserConfig.favicon, "favicon/favicon.ico"),
121
+ favicon: resolveStaticAsset(
122
+ UserConfig.favicon,
123
+ resolveStaticAsset(UserConfig.hero_section.profile_pic, "img/icon.png"),
124
+ ),
378
125
  url: siteUrl,
379
126
  baseUrl: basePath,
380
127
 
@@ -491,7 +238,7 @@ export function buildDocuConfig(rawUserConfig, UserRoot) {
491
238
  // so Root.js and MDXComponents are natively transpiled by Docusaurus.
492
239
  themes: [
493
240
  [
494
- path.resolve(PortoRoot, "src/core/plugins/themePlugin.mjs"),
241
+ path.resolve(PortoRoot, "src/plugins/theme.mjs"),
495
242
  {
496
243
  themeDir: PortoThemeDir,
497
244
  },
@@ -527,7 +274,13 @@ export function buildDocuConfig(rawUserConfig, UserRoot) {
527
274
  hideOnScroll: UserConfig.hide_navbar_on_scroll,
528
275
  logo: {
529
276
  alt: "Site Logo",
530
- src: resolveStaticAsset(UserConfig.favicon, "favicon/favicon.ico"),
277
+ src: resolveStaticAsset(
278
+ UserConfig.favicon,
279
+ resolveStaticAsset(
280
+ UserConfig.hero_section.profile_pic,
281
+ "img/icon.png",
282
+ ),
283
+ ),
531
284
  },
532
285
  items: useEnabled([
533
286
  {
@@ -636,8 +389,8 @@ export function buildDocuConfig(rawUserConfig, UserRoot) {
636
389
  },
637
390
  };
638
391
  },
639
- path.resolve(PortoRoot, "src/utils/build/generateFavicon.mjs"),
640
- path.resolve(PortoRoot, "src/utils/build/generateRobotsTxt.mjs"),
392
+ path.resolve(PortoRoot, "src/plugins/favicon.mjs"),
393
+ path.resolve(PortoRoot, "src/plugins/robots.mjs"),
641
394
  [
642
395
  require.resolve("@easyops-cn/docusaurus-search-local", {
643
396
  paths: [UserRoot, PortoRoot],
@@ -0,0 +1,8 @@
1
+ # Docusaurus Plugins
2
+
3
+ This directory contains internal Docusaurus plugins that extend the site's functionality during build and development.
4
+
5
+ - **`theme.mjs`**: Maps the internal `src/theme` directory so that Docusaurus can pick up Portosaurus components natively.
6
+ - **`favicon.mjs`**: Automates the generation of a complete favicon suite from the user's profile picture.
7
+ - **`robots.mjs`**: Generates a `robots.txt` file based on the configured site URL.
8
+ - **`lib/`**: Contains shared internal utilities used by these plugins (image processing, CSS extraction, etc.).
@@ -2,11 +2,11 @@ import fs from "fs";
2
2
  import path from "path";
3
3
  import { fileURLToPath } from "url";
4
4
  import { favicons } from "favicons";
5
- import { downloadImage } from "./imageDownloader.mjs";
6
- import { reshapeImage } from "./imageProcessor.mjs";
7
- import { getCssVar } from "./cssUtils.mjs";
8
- import { extractSvg } from "./iconExtractor.mjs";
9
- import { logger } from "../logger.mjs";
5
+ import { downloadImage } from "./lib/imageDownloader.mjs";
6
+ import { reshapeImage } from "./lib/imageProcessor.mjs";
7
+ import { getCssVar } from "./lib/cssUtils.mjs";
8
+ import { extractSvg } from "./lib/iconExtractor.mjs";
9
+ import { logger } from "../utils/logger.mjs";
10
10
 
11
11
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
12
12
 
@@ -142,14 +142,47 @@ export async function generateFavicons(context, options = {}) {
142
142
  },
143
143
  };
144
144
 
145
- // 1. Download image with proxy support + caching
146
- const downloadedRes = await downloadImage(
147
- profilePicUrl,
148
- cacheDir,
149
- "profile_pic_src.png",
150
- { proxies, cacheDir: path.join(cacheDir, "downloads") },
151
- );
152
- tempFiles.push(downloadedRes);
145
+ // 1. Resolve image source (Remote URL vs Local Path)
146
+ let downloadedRes;
147
+ const isRemote = /^https?:\/\//.test(profilePicUrl);
148
+
149
+ if (isRemote) {
150
+ // Download remote image with proxy support + caching
151
+ downloadedRes = await downloadImage(
152
+ profilePicUrl,
153
+ cacheDir,
154
+ "profile_pic_src.png",
155
+ { proxies, cacheDir: path.join(cacheDir, "downloads") },
156
+ );
157
+ tempFiles.push(downloadedRes);
158
+ } else {
159
+ // Handle local path
160
+ let localPath = null;
161
+ // Static directories are provided in siteConfig or we check common ones
162
+ const staticDirs = siteConfig.staticDirectories || ["static"];
163
+
164
+ for (const sDir of staticDirs) {
165
+ const fullPath = path.resolve(context.siteDir, sDir, profilePicUrl);
166
+ if (fs.existsSync(fullPath)) {
167
+ localPath = fullPath;
168
+ break;
169
+ }
170
+ }
171
+
172
+ if (!localPath) {
173
+ // Fallback: check Porto asset dir if not found in user static
174
+ const portoAssetDir = path.resolve(__dirname, "../../assets");
175
+ const portoPath = path.resolve(portoAssetDir, profilePicUrl);
176
+ if (fs.existsSync(portoPath)) {
177
+ localPath = portoPath;
178
+ }
179
+ }
180
+
181
+ if (!localPath) {
182
+ throw new Error(`Local profile picture not found: ${profilePicUrl}`);
183
+ }
184
+ downloadedRes = localPath;
185
+ }
153
186
 
154
187
  // 2. Reshape if needed
155
188
  let finalImagePath = downloadedRes;
@@ -159,7 +192,10 @@ export async function generateFavicons(context, options = {}) {
159
192
  reshapedImagePath,
160
193
  shape,
161
194
  );
162
- tempFiles.push(finalImagePath);
195
+ // Only cleanup if it's a generated temp file, not the original local source
196
+ if (finalImagePath !== downloadedRes) {
197
+ tempFiles.push(finalImagePath);
198
+ }
163
199
  }
164
200
 
165
201
  createDirectoryIfNotExists(outputDir);
@@ -11,7 +11,7 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
11
11
  */
12
12
  export function getCssVar(name) {
13
13
  try {
14
- const cssPath = path.resolve(__dirname, "../../css/custom.css");
14
+ const cssPath = path.resolve(__dirname, "../../theme/css/custom.css");
15
15
  const cssContent = fs.readFileSync(cssPath, "utf8");
16
16
 
17
17
  if (name === "--ifm-color-primary") {
@@ -1,7 +1,7 @@
1
1
  import fs from "fs";
2
2
  import path from "path";
3
3
  import { fileURLToPath } from "url";
4
- import { logger } from "../logger.mjs";
4
+ import { logger } from "../../utils/logger.mjs";
5
5
 
6
6
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
7
7
 
@@ -3,7 +3,7 @@ import path from "path";
3
3
  import https from "https";
4
4
  import http from "http";
5
5
  import crypto from "crypto";
6
- import { logger } from "../logger.mjs";
6
+ import { logger } from "../../utils/logger.mjs";
7
7
 
8
8
  /**
9
9
  * Generates a short hash from a URL for use as a cache key.
@@ -1,7 +1,7 @@
1
1
  import fs from "fs";
2
2
  import path from "path";
3
3
  import sharp from "sharp";
4
- import { logger } from "../logger.mjs";
4
+ import { logger } from "../../utils/logger.mjs";
5
5
 
6
6
  /**
7
7
  * Reshapes an image into a circle or square with rounded corners.
@@ -1,6 +1,6 @@
1
1
  import fs from "fs";
2
2
  import path from "path";
3
- import { logger } from "../logger.mjs";
3
+ import { logger } from "../utils/logger.mjs";
4
4
 
5
5
  /**
6
6
  * Generates a robots.txt file in the site's static directory.
@@ -0,0 +1,11 @@
1
+ {
2
+ "title": "Recent posts",
3
+ "items": [
4
+ {
5
+ "title": "Welcome to the Blog",
6
+ "permalink": "/blog/welcome",
7
+ "unlisted": false,
8
+ "date": "2017-03-31T22:00:00.000Z"
9
+ }
10
+ ]
11
+ }
@@ -0,0 +1 @@
1
+ {"archive":{"blogPosts":[{"id":"/welcome","metadata":{"permalink":"/blog/welcome","source":"@site/blog/welcome.md","title":"Welcome to the Blog","description":"Your first blog post! Edit or delete this file to get started.","date":"2017-03-31T22:00:00.000Z","tags":[{"inline":true,"label":"welcome","permalink":"/blog/tags/welcome"}],"hasTruncateMarker":true,"authors":[{"name":"Your Name","title":"Author","url":"https://github.com/yourprofile","key":"you","page":null}],"frontMatter":{"title":"Welcome to the Blog","authors":["you"],"tags":["welcome"]},"unlisted":false},"content":"Your first blog post! Edit or delete this file to get started.\n\n<!-- truncate -->\n\nThis is a blog powered by [Portosaurus](https://github.com/soymadip/portosaurus)."}]}}
@@ -0,0 +1 @@
1
+ {"authors":[{"name":"Your Name","title":"Author","url":"https://github.com/yourprofile","key":"you","page":null,"count":1}]}
@@ -0,0 +1 @@
1
+ {"metadata":{"permalink":"/blog","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}}
@@ -0,0 +1,16 @@
1
+ {
2
+ "permalink": "/blog/ss",
3
+ "source": "@site/blog/ss.md",
4
+ "title": "ss",
5
+ "description": "",
6
+ "date": "2017-03-31T22:00:00.000Z",
7
+ "tags": [],
8
+ "hasTruncateMarker": false,
9
+ "authors": [],
10
+ "frontMatter": {},
11
+ "unlisted": false,
12
+ "nextItem": {
13
+ "title": "Welcome to the Blog",
14
+ "permalink": "/blog/welcome"
15
+ }
16
+ }
@@ -0,0 +1,34 @@
1
+ {
2
+ "permalink": "/blog/welcome",
3
+ "source": "@site/blog/welcome.md",
4
+ "title": "Welcome to the Blog",
5
+ "description": "Your first blog post! Edit or delete this file to get started.",
6
+ "date": "2017-03-31T22:00:00.000Z",
7
+ "tags": [
8
+ {
9
+ "inline": true,
10
+ "label": "welcome",
11
+ "permalink": "/blog/tags/welcome"
12
+ }
13
+ ],
14
+ "hasTruncateMarker": true,
15
+ "authors": [
16
+ {
17
+ "name": "Your Name",
18
+ "title": "Author",
19
+ "url": "https://github.com/yourprofile",
20
+ "key": "you",
21
+ "page": null
22
+ }
23
+ ],
24
+ "frontMatter": {
25
+ "title": "Welcome to the Blog",
26
+ "authors": [
27
+ "you"
28
+ ],
29
+ "tags": [
30
+ "welcome"
31
+ ]
32
+ },
33
+ "unlisted": false
34
+ }
@@ -0,0 +1 @@
1
+ {"version":{"pluginId":"default","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{},"docs":{"index":{"id":"index","title":"Notes","description":""},"welcome":{"id":"welcome","title":"Welcome","description":"Welcome to your notes! Add markdown or MDX files in this notes/ directory."}}}}