valaxy 0.26.12 → 0.26.13

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.
@@ -1,5 +1,6 @@
1
1
  import type { UserModule } from '../types'
2
2
 
3
+ import { normalizeRepositoryUrl } from '@valaxyjs/utils'
3
4
  import pkg from '../../package.json'
4
5
  import valaxyLogo from '../assets/images/valaxy-logo.png'
5
6
 
@@ -39,7 +40,7 @@ export async function addValaxyTabAndCommand() {
39
40
  icon: 'i-ri-github-fill',
40
41
  action: {
41
42
  type: 'url',
42
- src: pkg.repository.url,
43
+ src: normalizeRepositoryUrl(pkg.repository.url),
43
44
  },
44
45
  },
45
46
  {
@@ -1,7 +1,7 @@
1
1
  import 'node:process';
2
2
  import 'yargs';
3
3
  import 'yargs/helpers';
4
- export { c as cli, d as registerDevCommand, r as run, a as startValaxyDev } from '../../shared/valaxy.DsB_W1aR.mjs';
4
+ export { c as cli, d as registerDevCommand, r as run, a as startValaxyDev } from '../../shared/valaxy.CEmGx65r.mjs';
5
5
  import 'node:os';
6
6
  import 'node:path';
7
7
  import 'consola';
@@ -22,6 +22,7 @@ import 'ora';
22
22
  import 'cross-spawn';
23
23
  import 'mlly';
24
24
  import 'resolve-global';
25
+ import '@valaxyjs/utils';
25
26
  import 'node:fs/promises';
26
27
  import 'dayjs';
27
28
  import 'feed';
@@ -2,7 +2,7 @@ import { ViteSSGOptions } from 'vite-ssg';
2
2
  import * as vite from 'vite';
3
3
  import { UserConfig, InlineConfig, ViteDevServer, PluginOption, Plugin } from 'vite';
4
4
  import Vue from '@vitejs/plugin-vue';
5
- import { Options as Options$2 } from 'beasties';
5
+ import { Options as Options$1 } from 'beasties';
6
6
  import { Hookable } from 'hookable';
7
7
  import { PluginVisualizerOptions } from 'rollup-plugin-visualizer';
8
8
  import { presetWind4, presetAttributify, presetIcons, presetTypography } from 'unocss';
@@ -12,7 +12,7 @@ import Markdown from 'unplugin-vue-markdown/vite';
12
12
  import { EditableTreeNode } from 'unplugin-vue-router';
13
13
  import Router from 'unplugin-vue-router/vite';
14
14
  import Layouts from 'vite-plugin-vue-layouts';
15
- import { Options as Options$1 } from 'vitepress-plugin-group-icons';
15
+ import { groupIconVitePlugin } from 'vitepress-plugin-group-icons';
16
16
  import { D as DefaultTheme, R as RuntimeConfig, a as RedirectItem, V as ValaxyConfig, P as PartialDeep, b as ValaxyAddon, S as SiteConfig, U as UserSiteConfig } from '../shared/valaxy.gqLhCu14.mjs';
17
17
  import { MarkdownEnv } from 'unplugin-vue-markdown/types';
18
18
  import { KatexOptions } from 'katex';
@@ -557,6 +557,12 @@ interface ValaxyExtendConfig {
557
557
  * @default false
558
558
  */
559
559
  fullText: boolean;
560
+ /**
561
+ * @zh 从构建后的 HTML 中提取图片路径(用于解析 Vite 打包后的 hash 文件名)
562
+ * @en Extract image paths from built HTML files (to resolve Vite hashed filenames)
563
+ * @default true
564
+ */
565
+ extractImagePathsFromHTML: boolean;
560
566
  };
561
567
  };
562
568
  /**
@@ -626,7 +632,7 @@ interface ValaxyExtendConfig {
626
632
  /**
627
633
  * @see https://github.com/yuyinws/vitepress-plugin-group-icons
628
634
  */
629
- groupIcons?: Partial<Options$1>;
635
+ groupIcons?: Partial<NonNullable<Parameters<typeof groupIconVitePlugin>[0]>>;
630
636
  /**
631
637
  * unocss presets
632
638
  * @see https://unocss.dev/guide/presets
@@ -703,7 +709,7 @@ interface ValaxyExtendConfig {
703
709
  * beastiesOptions
704
710
  * @see https://github.com/danielroe/beasties
705
711
  */
706
- beastiesOptions?: Options$2;
712
+ beastiesOptions?: Options$1;
707
713
  }
708
714
  type ValaxyApp = ReturnType<typeof createValaxyNode>;
709
715
 
@@ -1,4 +1,4 @@
1
- export { C as ALL_ROUTE, E as EXCERPT_SEPARATOR, G as GLOBAL_STATE, P as PATHNAME_PROTOCOL_RE, V as ViteValaxyPlugins, b as build, c as cli, N as createServer, L as createValaxyPlugin, D as customElements, j as defaultSiteConfig, w as defaultValaxyConfig, F as defaultViteConfig, h as defineAddon, y as defineConfig, k as defineSiteConfig, u as defineTheme, f as defineValaxyAddon, x as defineValaxyConfig, t as defineValaxyTheme, O as encryptContent, g as generateClientRedirects, Q as getGitTimestamp, e as getIndexHtml, M as getServerInfoText, R as isExternal, U as isInstalledGlobally, S as isPath, v as loadConfigFromFile, A as mergeValaxyConfig, m as mergeViteConfigs, p as postProcessForSSG, I as processValaxyOptions, d as registerDevCommand, i as resolveAddonsConfig, Y as resolveImportPath, W as resolveImportUrl, J as resolveOptions, n as resolveSiteConfig, l as resolveSiteConfigFromRoot, o as resolveThemeConfigFromRoot, K as resolveThemeValaxyConfig, q as resolveUserThemeConfig, B as resolveValaxyConfig, z as resolveValaxyConfigFromRoot, r as run, s as ssgBuild, a as startValaxyDev, X as toAtFS, T as transformObject, H as version } from '../shared/valaxy.DsB_W1aR.mjs';
1
+ export { C as ALL_ROUTE, E as EXCERPT_SEPARATOR, G as GLOBAL_STATE, P as PATHNAME_PROTOCOL_RE, V as ViteValaxyPlugins, b as build, c as cli, N as createServer, L as createValaxyPlugin, D as customElements, j as defaultSiteConfig, w as defaultValaxyConfig, F as defaultViteConfig, h as defineAddon, y as defineConfig, k as defineSiteConfig, u as defineTheme, f as defineValaxyAddon, x as defineValaxyConfig, t as defineValaxyTheme, O as encryptContent, g as generateClientRedirects, Q as getGitTimestamp, e as getIndexHtml, M as getServerInfoText, R as isExternal, U as isInstalledGlobally, S as isPath, v as loadConfigFromFile, A as mergeValaxyConfig, m as mergeViteConfigs, p as postProcessForSSG, I as processValaxyOptions, d as registerDevCommand, i as resolveAddonsConfig, Y as resolveImportPath, W as resolveImportUrl, J as resolveOptions, n as resolveSiteConfig, l as resolveSiteConfigFromRoot, o as resolveThemeConfigFromRoot, K as resolveThemeValaxyConfig, q as resolveUserThemeConfig, B as resolveValaxyConfig, z as resolveValaxyConfigFromRoot, r as run, s as ssgBuild, a as startValaxyDev, X as toAtFS, T as transformObject, H as version } from '../shared/valaxy.CEmGx65r.mjs';
2
2
  import 'node:path';
3
3
  import 'fs-extra';
4
4
  import 'consola/utils';
@@ -22,6 +22,7 @@ import 'ora';
22
22
  import 'cross-spawn';
23
23
  import 'mlly';
24
24
  import 'resolve-global';
25
+ import '@valaxyjs/utils';
25
26
  import 'node:fs/promises';
26
27
  import 'dayjs';
27
28
  import 'feed';
@@ -21,6 +21,7 @@ import ora from 'ora';
21
21
  import { spawn } from 'cross-spawn';
22
22
  import { resolvePath } from 'mlly';
23
23
  import { resolveGlobal } from 'resolve-global';
24
+ import { normalizeRepositoryUrl } from '@valaxyjs/utils';
24
25
  import { readFile } from 'node:fs/promises';
25
26
  import dayjs from 'dayjs';
26
27
  import { Feed } from 'feed';
@@ -61,7 +62,7 @@ import net from 'node:net';
61
62
  import { exec } from 'node:child_process';
62
63
  import * as readline from 'node:readline';
63
64
  import qrcode from 'qrcode';
64
- import { render } from 'ejs';
65
+ import ejs from 'ejs';
65
66
 
66
67
  const EXCERPT_SEPARATOR = "<!-- more -->";
67
68
  const PATHNAME_PROTOCOL_RE = /^pathname:\/\//;
@@ -1599,7 +1600,7 @@ async function setupMarkdownPlugins(md, options, base = "/") {
1599
1600
  return md;
1600
1601
  }
1601
1602
 
1602
- const version = "0.26.12";
1603
+ const version = "0.26.13";
1603
1604
 
1604
1605
  const GLOBAL_STATE = {
1605
1606
  valaxyApp: void 0,
@@ -2134,7 +2135,8 @@ const defaultValaxyConfig = {
2134
2135
  modules: {
2135
2136
  rss: {
2136
2137
  enable: true,
2137
- fullText: false
2138
+ fullText: false,
2139
+ extractImagePathsFromHTML: true
2138
2140
  }
2139
2141
  },
2140
2142
  features: {
@@ -2378,7 +2380,9 @@ async function parseAddons(addons, userRoot = process.cwd()) {
2378
2380
  spinner.succeed();
2379
2381
  const resolvedAddons = Object.values(resolvers).filter((item) => item.enable);
2380
2382
  resolvedAddons.forEach((addon, i) => {
2381
- console.log(` ${i === resolvedAddons.length - 1 ? "\u2514\u2500" : "\u251C\u2500"} ${colors.yellow(addon.name)} ${colors.blue(`v${addon.pkg?.version}`)}${addon.global ? colors.cyan(" (global)") : ""} ${colors.dim(addon.pkg.homepage || addon.pkg.repository?.url || addon.pkg.repository || "")}`);
2383
+ const repoUrl = addon.pkg.repository?.url || addon.pkg.repository;
2384
+ const displayUrl = typeof repoUrl === "string" ? normalizeRepositoryUrl(repoUrl) : repoUrl;
2385
+ console.log(` ${i === resolvedAddons.length - 1 ? "\u2514\u2500" : "\u251C\u2500"} ${colors.yellow(addon.name)} ${colors.blue(`v${addon.pkg?.version}`)}${addon.global ? colors.cyan(" (global)") : ""} ${colors.dim(addon.pkg.homepage || displayUrl || "")}`);
2382
2386
  });
2383
2387
  return resolvedAddons;
2384
2388
  }
@@ -3815,6 +3819,34 @@ const markdown = MarkdownIt({
3815
3819
  breaks: true,
3816
3820
  linkify: true
3817
3821
  });
3822
+ async function extractImagePathsFromHTML(htmlPath, DOMAIN) {
3823
+ const imageMap = /* @__PURE__ */ new Map();
3824
+ try {
3825
+ if (!await fs.exists(htmlPath))
3826
+ return imageMap;
3827
+ const html = await fs.readFile(htmlPath, "utf-8");
3828
+ const imgRegex = /<img[^>]+src="([^"]+)"[^>]*>/g;
3829
+ let match;
3830
+ while ((match = imgRegex.exec(html)) !== null) {
3831
+ const src = match[1];
3832
+ const assetMatch = src.match(/\/assets\/(.+)\.([a-zA-Z0-9]+)\.([a-z0-9]+)$/);
3833
+ if (assetMatch) {
3834
+ const [, basename, , ext] = assetMatch;
3835
+ const originalName = `${basename}.${ext}`;
3836
+ imageMap.set(originalName, `${DOMAIN}${src}`);
3837
+ imageMap.set(`./${originalName}`, `${DOMAIN}${src}`);
3838
+ consola.debug(`[RSS] Mapped image: ${originalName} -> ${DOMAIN}${src}`);
3839
+ }
3840
+ }
3841
+ if (imageMap.size > 0) {
3842
+ const uniqueImageCount = imageMap.size / 2;
3843
+ consola.info(`[RSS] Extracted ${uniqueImageCount} image(s) from ${htmlPath}`);
3844
+ }
3845
+ } catch (error) {
3846
+ consola.debug(`Failed to extract image paths from ${htmlPath}:`, error);
3847
+ }
3848
+ return imageMap;
3849
+ }
3818
3850
  async function build(options) {
3819
3851
  const s = ora("RSS Generating ...").start();
3820
3852
  const { config } = options;
@@ -3899,12 +3931,39 @@ async function getPosts(params, options) {
3899
3931
  }
3900
3932
  const fullText = options.config.modules.rss.fullText;
3901
3933
  const rssContent = fullText ? content : excerpt || content.slice(0, 100);
3902
- const html = markdown.render(rssContent).replace('src="/', `src="${DOMAIN}/`);
3903
- if (data.image?.startsWith("/"))
3904
- data.image = DOMAIN + data.image;
3905
3934
  const relativePath = relative$1(join(options.userRoot, "pages"), path);
3906
3935
  const urlPath = relativePath.replace(/\\/g, "/").replace(/\.md$/, "");
3907
3936
  const link = `${DOMAIN}/${urlPath}`;
3937
+ const extractImages = options.config.modules.rss.extractImagePathsFromHTML;
3938
+ let imageMap = /* @__PURE__ */ new Map();
3939
+ if (extractImages) {
3940
+ let htmlPath = resolve(options.userRoot, "dist", `${urlPath}.html`);
3941
+ if (urlPath.endsWith("/index")) {
3942
+ const withoutIndex = urlPath.slice(0, -6);
3943
+ const alternativePath = resolve(options.userRoot, "dist", `${withoutIndex}.html`);
3944
+ if (await fs.exists(alternativePath)) {
3945
+ htmlPath = alternativePath;
3946
+ }
3947
+ }
3948
+ imageMap = await extractImagePathsFromHTML(htmlPath, DOMAIN);
3949
+ }
3950
+ let html = markdown.render(rssContent);
3951
+ html = html.replace(/src="([^"]+)"/g, (_fullMatch, src) => {
3952
+ if (imageMap.has(src)) {
3953
+ return `src="${imageMap.get(src)}"`;
3954
+ }
3955
+ if (src.startsWith("http://") || src.startsWith("https://")) {
3956
+ return _fullMatch;
3957
+ }
3958
+ if (src.startsWith("/")) {
3959
+ return `src="${DOMAIN}${src}"`;
3960
+ }
3961
+ const postDirUrl = `${DOMAIN}/${urlPath.split("/").slice(0, -1).join("/")}`;
3962
+ const cleanSrc = src.startsWith("./") ? src.slice(2) : src;
3963
+ return `src="${postDirUrl}/${cleanSrc}"`;
3964
+ });
3965
+ if (data.image?.startsWith("/"))
3966
+ data.image = DOMAIN + data.image;
3908
3967
  const tip = `<br/><p>${lang === "zh-CN" ? `\u8BBF\u95EE <a href="${link}" target="_blank">${link}</a> ${fullText ? "\u67E5\u770B\u539F\u6587" : "\u9605\u8BFB\u5168\u6587"}\u3002` : `Visit <a href="${link}" target="_blank">${link}</a> to ${fullText ? "view original article" : "read more"}.`}</p>`;
3909
3968
  const item = {
3910
3969
  ...data,
@@ -4530,7 +4589,7 @@ async function genLayoutTemplate({
4530
4589
  if (!template)
4531
4590
  template = defaultPostTemplate;
4532
4591
  const dateFormat = "YYYY-MM-DD HH:mm:ss";
4533
- return render(template, { title, layout, date: date ? dayjs().format(dateFormat) : "" });
4592
+ return ejs.render(template, { title, layout, date: date ? dayjs().format(dateFormat) : "" });
4534
4593
  }
4535
4594
 
4536
4595
  function registerNewCommand(cli) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "valaxy",
3
3
  "type": "module",
4
- "version": "0.26.12",
4
+ "version": "0.26.13",
5
5
  "description": "📄 Vite & Vue powered static blog generator.",
6
6
  "author": {
7
7
  "email": "me@yunyoujun.cn",
@@ -63,18 +63,18 @@
63
63
  "@antfu/install-pkg": "^1.1.0",
64
64
  "@antfu/utils": "^9.3.0",
65
65
  "@clack/prompts": "^0.11.0",
66
- "@iconify-json/ri": "^1.2.6",
66
+ "@iconify-json/ri": "^1.2.7",
67
67
  "@intlify/unplugin-vue-i18n": "^11.0.3",
68
- "@shikijs/transformers": "^3.20.0",
69
- "@types/katex": "^0.16.7",
70
- "@unhead/addons": "^2.1.1",
71
- "@unhead/schema-org": "^2.1.1",
72
- "@unhead/vue": "^2.1.1",
68
+ "@shikijs/transformers": "^3.21.0",
69
+ "@types/katex": "^0.16.8",
70
+ "@unhead/addons": "^2.1.2",
71
+ "@unhead/schema-org": "^2.1.2",
72
+ "@unhead/vue": "^2.1.2",
73
73
  "@vitejs/plugin-vue": "^6.0.3",
74
74
  "@vue/devtools-api": "7.7.2",
75
75
  "@vueuse/core": "^14.1.0",
76
76
  "@vueuse/integrations": "^14.1.0",
77
- "beasties": "^0.3.5",
77
+ "beasties": "^0.4.1",
78
78
  "consola": "^3.4.2",
79
79
  "cross-spawn": "^7.0.6",
80
80
  "css-i18n": "^0.0.5",
@@ -82,10 +82,10 @@
82
82
  "debug": "^4.4.3",
83
83
  "define-config-ts": "^0.1.3",
84
84
  "defu": "^6.1.4",
85
- "ejs": "^3.1.10",
85
+ "ejs": "^4.0.1",
86
86
  "escape-html": "^1.0.3",
87
87
  "fast-glob": "^3.3.3",
88
- "feed": "^5.1.0",
88
+ "feed": "^5.2.0",
89
89
  "floating-vue": "^5.2.2",
90
90
  "fs-extra": "^11.3.3",
91
91
  "fuse.js": "^7.1.0",
@@ -112,35 +112,35 @@
112
112
  "mlly": "^1.8.0",
113
113
  "nprogress": "^0.2.0",
114
114
  "open": "10.1.0",
115
- "ora": "^9.0.0",
115
+ "ora": "^9.1.0",
116
116
  "pascalcase": "^2.0.0",
117
117
  "pathe": "^2.0.3",
118
118
  "pinia": "^3.0.4",
119
119
  "qrcode": "^1.5.4",
120
120
  "resolve-global": "^2.0.0",
121
- "sass": "^1.97.1",
122
- "shiki": "^3.20.0",
121
+ "sass": "^1.97.3",
122
+ "shiki": "^3.21.0",
123
123
  "star-markdown-css": "^0.5.3",
124
124
  "table": "^6.9.0",
125
- "unhead": "^2.1.1",
125
+ "unhead": "^2.1.2",
126
126
  "unocss": "66.5.10",
127
127
  "unplugin-vue-components": "28.0.0",
128
128
  "unplugin-vue-markdown": "^29.2.0",
129
- "unplugin-vue-router": "^0.19.1",
129
+ "unplugin-vue-router": "^0.19.2",
130
130
  "vanilla-lazyload": "^19.1.3",
131
- "vite": "^7.3.0",
131
+ "vite": "^7.3.1",
132
132
  "vite-dev-rpc": "^1.1.0",
133
133
  "vite-plugin-vue-devtools": "^8.0.5",
134
134
  "vite-plugin-vue-layouts": "^0.11.0",
135
135
  "vite-ssg": "^28.2.2",
136
136
  "vite-ssg-sitemap": "^0.10.0",
137
- "vitepress-plugin-group-icons": "^1.6.5",
137
+ "vitepress-plugin-group-icons": "^1.7.1",
138
138
  "vue": "3.5.22",
139
- "vue-i18n": "^11.2.7",
139
+ "vue-i18n": "^11.2.8",
140
140
  "vue-router": "^4.6.4",
141
141
  "yargs": "^18.0.0",
142
- "@valaxyjs/devtools": "0.26.12",
143
- "@valaxyjs/utils": "0.26.12"
142
+ "@valaxyjs/devtools": "0.26.13",
143
+ "@valaxyjs/utils": "0.26.13"
144
144
  },
145
145
  "devDependencies": {
146
146
  "@mdit-vue/plugin-component": "^3.0.2",