@hagicode/hagilight 0.9.1-dev.98.1.e071fc7 → 0.9.2-dev.102.1.daf22c1

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 CHANGED
@@ -34,11 +34,26 @@ time from this package's own manifest, not from Astro. Existing
34
34
  feature-package attribution; switch that import to `@hagicode/hagilight/Footer`
35
35
  to opt in while keeping the same `locale` and `links` props.
36
36
 
37
+ ## Build line
38
+
39
+ `hagilight()` adds a build line to the footer's copyright text, after the attribution: `Branch:`, `Commit:` (seven characters, with the full hash in the `title` attribute), and `Built:` (UTC time to the second). The line appears even with `hagilight({ enabled: false })`. Without this integration, `@hagicode/hagilight-core/Footer` renders no build text.
40
+
41
+ The values come from `HAGILIGHT_BUILD_BRANCH` and `HAGILIGHT_BUILD_COMMIT`, then Git, then `unknown`; the core README gives the full order. CI systems often check out a detached HEAD, which reports `Branch: unknown`. Pass the branch in the build step:
42
+
43
+ ```yaml
44
+ - name: Build site
45
+ env:
46
+ HAGILIGHT_BUILD_BRANCH: ${{ github.head_ref || github.ref_name }}
47
+ run: npm run build
48
+ ```
49
+
50
+ `github.head_ref` is set on pull requests and `github.ref_name` on pushes. A shallow clone still reports its commit, because `git rev-parse HEAD` reads the checkout.
51
+
37
52
  ## Body images
38
53
 
39
54
  `hagilight()` registers the content-image plugin from `@hagicode/hagilight-core/content-images`. Markdown and MDX body images then get `loading="lazy"`, `decoding="async"`, and the class `hagilight-content-image`, with the author's values kept. This registration does not depend on `enabled`, so `hagilight({ enabled: false })` still registers the plugin.
40
55
 
41
- Local Markdown (`.md`) body images are also wrapped in a `<picture>` element with AVIF and WebP sources. This needs an image service that can encode AVIF: the default sharp service does, and the passthrough no-op service skips the wrapper with one warning. MDX, site-root, and remote images are not wrapped. Encoding adds build time, which Astro caches. Each `<source>` also carries `src`, `loading`, `decoding`, `width`, and `height` from Astro's output; browsers ignore these on `source`, but they are not valid HTML there. The opt-out below turns this step off too.
56
+ Local body images in `.md` and `.mdx` files are also wrapped in a `<picture>` element with AVIF and WebP sources. The rule is the same for both file types: a relative local image that is not `.svg` or `.gif` and does not resolve into `public/` is wrapped, so a Markdown image in an `.mdx` page renders as `picture` with an inner `<img>`. This needs an image service that can encode AVIF: the default sharp service does, and the passthrough no-op service skips the wrapper with one warning. Site-root and remote images, and raw HTML `<img>` tags, are not wrapped. Encoding adds build time, which Astro caches. In `.md`, each `<source>` also carries `src`, `loading`, `decoding`, `width`, and `height` from Astro's output; in `.mdx`, `<source>` carries only `srcset` and `type`. Browsers ignore the extra attributes on `source`, but they are not valid HTML there. The opt-out below turns this step off too.
42
57
 
43
58
  To opt out, pass either form:
44
59
 
@@ -0,0 +1,2 @@
1
+ import type { MiddlewareHandler } from 'astro';
2
+ export declare const onRequest: MiddlewareHandler;
@@ -0,0 +1,5 @@
1
+ import buildInfo from 'virtual:hagilight/build-info';
2
+ export const onRequest = (context, next) => {
3
+ context.locals.hagilightBuild = buildInfo;
4
+ return next();
5
+ };
@@ -2,12 +2,15 @@ import { existsSync, readdirSync, statSync } from 'node:fs';
2
2
  import { fileURLToPath } from 'node:url';
3
3
  import { extname, isAbsolute, resolve, win32 } from 'node:path';
4
4
  import sitemap from '@astrojs/sitemap';
5
+ import { resolveBuildInfo } from '@hagicode/hagilight-core/build-info-resolver';
5
6
  import { checkContentImageRegistration, registerContentImages } from '@hagicode/hagilight-core/content-images';
6
7
  import { resolveFaviconHeadEntry } from '@hagicode/hagilight-core/favicon';
7
8
  import { resolveRssLocales } from '@hagicode/hagilight-core/rss';
8
9
  import { resolvePlainAstroRssOwner } from '@hagicode/hagilight-core/rss-ownership';
9
10
  const VIRTUAL_RSS_CONFIG = 'virtual:hagilight/rss-config';
10
11
  const VIRTUAL_RSS_CONFIG_RESOLVED = `\0${VIRTUAL_RSS_CONFIG}`;
12
+ const VIRTUAL_BUILD_INFO = 'virtual:hagilight/build-info';
13
+ const VIRTUAL_BUILD_INFO_RESOLVED = `\0${VIRTUAL_BUILD_INFO}`;
11
14
  const PAGE_SOURCE_EXTENSIONS = new Set(['.astro', '.html', '.js', '.jsx', '.md', '.mdx', '.ts', '.tsx']);
12
15
  const packageRoot = new URL('../', import.meta.url);
13
16
  const routeEntrypoint = (name) => fileURLToPath(new URL(name, packageRoot));
@@ -75,6 +78,9 @@ export function hagilight({ enabled = true, rss, contentImages } = {}) {
75
78
  hooks: {
76
79
  'astro:config:setup'({ config, injectRoute, addMiddleware, updateConfig, logger }) {
77
80
  registerContentImages({ config, logger, enabled: contentImagesEnabled });
81
+ const buildInfo = resolveBuildInfo({ root: fileURLToPath(config.root) });
82
+ updateConfig({ vite: { plugins: [createBuildInfoPlugin(buildInfo)] } });
83
+ addMiddleware({ entrypoint: fileURLToPath(new URL('./build-info-middleware.js', import.meta.url)), order: 'pre' });
78
84
  if (!enabled)
79
85
  return;
80
86
  resolveDiscoverySite(config.site);
@@ -240,6 +246,19 @@ function createVirtualPlugin({ modulePath, site, baseUrl, locales, defaultFeedUr
240
246
  },
241
247
  };
242
248
  }
249
+ function createBuildInfoPlugin(buildInfo) {
250
+ return {
251
+ name: '@hagicode/hagilight:build-info',
252
+ resolveId(id) {
253
+ return id === VIRTUAL_BUILD_INFO ? VIRTUAL_BUILD_INFO_RESOLVED : null;
254
+ },
255
+ load(id) {
256
+ if (id !== VIRTUAL_BUILD_INFO_RESOLVED)
257
+ return null;
258
+ return `export default ${JSON.stringify(buildInfo)};`;
259
+ },
260
+ };
261
+ }
243
262
  /** Inject the bundled HagiCode favicon unless the site head already declares an icon. */
244
263
  export function hagilightFavicon(options = {}) {
245
264
  if (!isRecord(options)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hagicode/hagilight",
3
- "version": "0.9.1-dev.98.1.e071fc7",
3
+ "version": "0.9.2-dev.102.1.daf22c1",
4
4
  "type": "module",
5
5
  "description": "Astro integrations and components for HagiCode sites",
6
6
  "repository": {
@@ -40,7 +40,7 @@
40
40
  },
41
41
  "dependencies": {
42
42
  "@astrojs/sitemap": "^3.7.4",
43
- "@hagicode/hagilight-core": "0.9.1-dev.98.1.e071fc7"
43
+ "@hagicode/hagilight-core": "0.9.2-dev.102.1.daf22c1"
44
44
  },
45
45
  "keywords": [
46
46
  "astro-component",