@hagicode/hagilight-core 0.8.1-dev.87.1.57ea49d → 0.8.1-dev.91.1.ab66a07
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 +30 -0
- package/dist/content-images.d.ts +86 -0
- package/dist/content-images.js +234 -0
- package/dist/promotions.js +1 -1
- package/package.json +14 -1
package/README.md
CHANGED
|
@@ -35,6 +35,36 @@ import { resolveSiteLinks } from '@hagicode/hagilight-core/links';
|
|
|
35
35
|
const links = resolveSiteLinks('en-US');
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
+
## Content images
|
|
39
|
+
|
|
40
|
+
`@hagicode/hagilight-core/content-images` normalizes the `<img>` elements in Markdown and MDX body content at build time. A body image gets the marker class `hagilight-content-image`, `loading="lazy"`, and `decoding="async"`. Values the author already set are kept, existing classes are kept, and the marker is added once.
|
|
41
|
+
|
|
42
|
+
| Option | Default | Accepted values |
|
|
43
|
+
| --- | --- | --- |
|
|
44
|
+
| `loading` | `lazy` | `lazy` or `eager`, applied only when the image has no `loading` |
|
|
45
|
+
| `decoding` | `async` | `async`, `sync`, or `auto`, applied only when the image has no `decoding` |
|
|
46
|
+
| `className` | `hagilight-content-image` | A class name without whitespace |
|
|
47
|
+
|
|
48
|
+
Images inside a `<picture>` element are skipped. An MDX `class={expression}` gets no marker because its value is not known at build time. Raw HTML `<img>` tags inside a `.md` file are not normalized; use Markdown image syntax or MDX for body images.
|
|
49
|
+
|
|
50
|
+
`hagilight()` from `@hagicode/hagilight-starlight` and `hagilight()` from `@hagicode/hagilight/integration` register the plugin automatically, for the whole site and regardless of integration order. Each one opts out through its `contentImages` option; see those packages' READMEs.
|
|
51
|
+
|
|
52
|
+
To use the plugin without a feature package, add it to the Markdown processor. With the default Sätteri processor:
|
|
53
|
+
|
|
54
|
+
```js
|
|
55
|
+
import { defineConfig } from 'astro/config';
|
|
56
|
+
import { satteri } from '@astrojs/markdown-satteri';
|
|
57
|
+
import { satteriContentImages } from '@hagicode/hagilight-core/content-images';
|
|
58
|
+
|
|
59
|
+
export default defineConfig({
|
|
60
|
+
markdown: {
|
|
61
|
+
processor: satteri({ hastPlugins: [satteriContentImages()] }),
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
With the unified processor, pass `rehypeContentImages()` in `rehypePlugins` instead, from `@astrojs/markdown-remark`'s `unified()`. Integrations that wrap Astro can call `registerContentImages({ config, logger, enabled })` in `astro:config:setup` and `checkContentImageRegistration({ config, logger, enabled })` in `astro:config:done`, both exported from the same entry point.
|
|
67
|
+
|
|
38
68
|
## Promotion platforms
|
|
39
69
|
|
|
40
70
|
The shared banner (`PromotoBanner`, `loadActivePromotions`) displays only promotions whose `platforms` array in Index's `/promote.json` includes `web`, in addition to being enabled, inside their activation window, and matched with `/promote_content.json`. This follows the `platforms` flag documented in the Index README. An entry whose `platforms` is missing, empty, or not an array of strings is not displayed, other values such as `hagicode` are ignored, and matching is exact (`Web` does not match). When no promotion remains, the banner shows its site fallback or stays hidden, as before.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
export declare const CONTENT_IMAGE_CLASS = "hagilight-content-image";
|
|
2
|
+
export type ContentImageLoading = 'lazy' | 'eager';
|
|
3
|
+
export type ContentImageDecoding = 'async' | 'sync' | 'auto';
|
|
4
|
+
export interface ContentImageOptions {
|
|
5
|
+
/** Loading value for body images whose author set none. Defaults to `lazy`. */
|
|
6
|
+
loading?: ContentImageLoading;
|
|
7
|
+
/** Decoding value for body images whose author set none. Defaults to `async`. */
|
|
8
|
+
decoding?: ContentImageDecoding;
|
|
9
|
+
/** Marker class added once to every body image. Defaults to `hagilight-content-image`. */
|
|
10
|
+
className?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface ResolvedContentImageOptions {
|
|
13
|
+
loading: ContentImageLoading;
|
|
14
|
+
decoding: ContentImageDecoding;
|
|
15
|
+
className: string;
|
|
16
|
+
}
|
|
17
|
+
export interface ContentImageAuthorValues {
|
|
18
|
+
hasLoading: boolean;
|
|
19
|
+
hasDecoding: boolean;
|
|
20
|
+
classNames: readonly string[];
|
|
21
|
+
}
|
|
22
|
+
export interface ContentImagePatch {
|
|
23
|
+
loading?: ContentImageLoading;
|
|
24
|
+
decoding?: ContentImageDecoding;
|
|
25
|
+
classNames?: string[];
|
|
26
|
+
}
|
|
27
|
+
export interface MdxAttributeLike {
|
|
28
|
+
type?: string;
|
|
29
|
+
name?: string;
|
|
30
|
+
value?: unknown;
|
|
31
|
+
}
|
|
32
|
+
export interface ContentImageNode {
|
|
33
|
+
type: string;
|
|
34
|
+
tagName?: string;
|
|
35
|
+
name?: string | null;
|
|
36
|
+
properties?: Record<string, unknown>;
|
|
37
|
+
attributes?: MdxAttributeLike[];
|
|
38
|
+
children?: ContentImageNode[];
|
|
39
|
+
}
|
|
40
|
+
export interface SatteriContentImageContext {
|
|
41
|
+
parent(node: unknown): unknown;
|
|
42
|
+
setProperty(node: unknown, key: string, value: unknown): void;
|
|
43
|
+
}
|
|
44
|
+
export interface SatteriContentImageVisitor {
|
|
45
|
+
filter: string[];
|
|
46
|
+
visit(node: ContentImageNode, ctx: SatteriContentImageContext): void;
|
|
47
|
+
}
|
|
48
|
+
export interface SatteriContentImagePlugin {
|
|
49
|
+
name: string;
|
|
50
|
+
element: SatteriContentImageVisitor;
|
|
51
|
+
mdxJsxFlowElement: SatteriContentImageVisitor;
|
|
52
|
+
mdxJsxTextElement: SatteriContentImageVisitor;
|
|
53
|
+
}
|
|
54
|
+
export interface ContentImageRegistrationInput {
|
|
55
|
+
config: {
|
|
56
|
+
markdown?: {
|
|
57
|
+
processor?: unknown;
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
logger: {
|
|
61
|
+
warn(message: string): void;
|
|
62
|
+
};
|
|
63
|
+
enabled: boolean;
|
|
64
|
+
}
|
|
65
|
+
export declare function resolveContentImageOptions(options?: ContentImageOptions): ResolvedContentImageOptions;
|
|
66
|
+
export declare function contentImagePatch(author: ContentImageAuthorValues, options: ResolvedContentImageOptions): ContentImagePatch;
|
|
67
|
+
export declare function hastImagePatch(properties: Record<string, unknown>, options: ResolvedContentImageOptions): ContentImagePatch;
|
|
68
|
+
export interface MdxImagePatch {
|
|
69
|
+
loading?: ContentImageLoading;
|
|
70
|
+
decoding?: ContentImageDecoding;
|
|
71
|
+
className?: string;
|
|
72
|
+
}
|
|
73
|
+
/** A class written as an expression cannot be merged statically, so its marker is left out. */
|
|
74
|
+
export declare function mdxImagePatch(attributes: readonly MdxAttributeLike[], options: ResolvedContentImageOptions): MdxImagePatch;
|
|
75
|
+
/** Unified rehype plugin: `unified` processors and Astro 6 `markdown.rehypePlugins`. */
|
|
76
|
+
export declare function rehypeContentImages(options?: ContentImageOptions): (tree: ContentImageNode) => void;
|
|
77
|
+
/** Sätteri hast plugin: Astro's default Markdown processor, through `hastPlugins`. */
|
|
78
|
+
export declare function satteriContentImages(options?: ContentImageOptions): SatteriContentImagePlugin;
|
|
79
|
+
/**
|
|
80
|
+
* Register the content-image plugin on the active Markdown processor. The first enabled
|
|
81
|
+
* call appends one adapter; an `enabled: false` call opts the whole site out and removes
|
|
82
|
+
* only the adapter it did not append, so the result does not depend on hook order.
|
|
83
|
+
*/
|
|
84
|
+
export declare function registerContentImages({ config, logger, enabled }: ContentImageRegistrationInput): void;
|
|
85
|
+
/** `astro:config:done` re-check: warns once if an enabled site's adapter is missing from the final processor. */
|
|
86
|
+
export declare function checkContentImageRegistration({ config, logger, enabled }: ContentImageRegistrationInput): void;
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
export const CONTENT_IMAGE_CLASS = 'hagilight-content-image';
|
|
2
|
+
function isRecord(value) {
|
|
3
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
4
|
+
}
|
|
5
|
+
export function resolveContentImageOptions(options = {}) {
|
|
6
|
+
if (!isRecord(options))
|
|
7
|
+
throw new TypeError('Hagilight content image options must be an object.');
|
|
8
|
+
const { loading = 'lazy', decoding = 'async', className = CONTENT_IMAGE_CLASS } = options;
|
|
9
|
+
if (loading !== 'lazy' && loading !== 'eager') {
|
|
10
|
+
throw new TypeError('Hagilight content image loading option must be "lazy" or "eager".');
|
|
11
|
+
}
|
|
12
|
+
if (decoding !== 'async' && decoding !== 'sync' && decoding !== 'auto') {
|
|
13
|
+
throw new TypeError('Hagilight content image decoding option must be "async", "sync", or "auto".');
|
|
14
|
+
}
|
|
15
|
+
if (typeof className !== 'string' || className === '' || /\s/u.test(className)) {
|
|
16
|
+
throw new TypeError('Hagilight content image className option must be a non-empty class name without whitespace.');
|
|
17
|
+
}
|
|
18
|
+
return { loading, decoding, className };
|
|
19
|
+
}
|
|
20
|
+
export function contentImagePatch(author, options) {
|
|
21
|
+
const patch = {};
|
|
22
|
+
if (!author.hasLoading)
|
|
23
|
+
patch.loading = options.loading;
|
|
24
|
+
if (!author.hasDecoding)
|
|
25
|
+
patch.decoding = options.decoding;
|
|
26
|
+
if (!author.classNames.includes(options.className)) {
|
|
27
|
+
patch.classNames = [...author.classNames, options.className];
|
|
28
|
+
}
|
|
29
|
+
return patch;
|
|
30
|
+
}
|
|
31
|
+
function splitClassNames(value) {
|
|
32
|
+
return value.split(/\s+/u).filter(Boolean);
|
|
33
|
+
}
|
|
34
|
+
function classNamesOf(value) {
|
|
35
|
+
if (typeof value === 'string')
|
|
36
|
+
return splitClassNames(value);
|
|
37
|
+
if (Array.isArray(value)) {
|
|
38
|
+
return value.filter((item) => typeof item === 'string').flatMap(splitClassNames);
|
|
39
|
+
}
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
function mdxClassNames(attribute) {
|
|
43
|
+
if (attribute === undefined || attribute.value === undefined || attribute.value === null)
|
|
44
|
+
return [];
|
|
45
|
+
return typeof attribute.value === 'string' ? splitClassNames(attribute.value) : undefined;
|
|
46
|
+
}
|
|
47
|
+
export function hastImagePatch(properties, options) {
|
|
48
|
+
return contentImagePatch({
|
|
49
|
+
hasLoading: properties.loading !== undefined,
|
|
50
|
+
hasDecoding: properties.decoding !== undefined,
|
|
51
|
+
classNames: classNamesOf(properties.className),
|
|
52
|
+
}, options);
|
|
53
|
+
}
|
|
54
|
+
/** A class written as an expression cannot be merged statically, so its marker is left out. */
|
|
55
|
+
export function mdxImagePatch(attributes, options) {
|
|
56
|
+
const classNames = mdxClassNames(attributes.find((attribute) => attribute.name === 'class'));
|
|
57
|
+
const patch = contentImagePatch({
|
|
58
|
+
hasLoading: attributes.some((attribute) => attribute.name === 'loading'),
|
|
59
|
+
hasDecoding: attributes.some((attribute) => attribute.name === 'decoding'),
|
|
60
|
+
classNames: classNames ?? [options.className],
|
|
61
|
+
}, options);
|
|
62
|
+
return {
|
|
63
|
+
loading: patch.loading,
|
|
64
|
+
decoding: patch.decoding,
|
|
65
|
+
className: patch.classNames?.join(' '),
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function isMdxJsx(node) {
|
|
69
|
+
return node.type === 'mdxJsxFlowElement' || node.type === 'mdxJsxTextElement';
|
|
70
|
+
}
|
|
71
|
+
function isPicture(node) {
|
|
72
|
+
return (node.type === 'element' && node.tagName === 'picture')
|
|
73
|
+
|| (isMdxJsx(node) && node.name === 'picture');
|
|
74
|
+
}
|
|
75
|
+
function upsertMdxAttribute(attributes, name, value) {
|
|
76
|
+
const existing = attributes.find((attribute) => attribute.name === name);
|
|
77
|
+
if (existing)
|
|
78
|
+
existing.value = value;
|
|
79
|
+
else
|
|
80
|
+
attributes.push({ type: 'mdxJsxAttribute', name, value });
|
|
81
|
+
}
|
|
82
|
+
function applyUnifiedNode(node, options) {
|
|
83
|
+
if (node.type === 'element' && node.tagName === 'img') {
|
|
84
|
+
const properties = (node.properties ??= {});
|
|
85
|
+
const patch = hastImagePatch(properties, options);
|
|
86
|
+
if (patch.loading !== undefined)
|
|
87
|
+
properties.loading = patch.loading;
|
|
88
|
+
if (patch.decoding !== undefined)
|
|
89
|
+
properties.decoding = patch.decoding;
|
|
90
|
+
if (patch.classNames !== undefined)
|
|
91
|
+
properties.className = patch.classNames;
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
if (isMdxJsx(node) && node.name === 'img') {
|
|
95
|
+
const attributes = (node.attributes ??= []);
|
|
96
|
+
const patch = mdxImagePatch(attributes, options);
|
|
97
|
+
if (patch.loading !== undefined)
|
|
98
|
+
upsertMdxAttribute(attributes, 'loading', patch.loading);
|
|
99
|
+
if (patch.decoding !== undefined)
|
|
100
|
+
upsertMdxAttribute(attributes, 'decoding', patch.decoding);
|
|
101
|
+
if (patch.className !== undefined)
|
|
102
|
+
upsertMdxAttribute(attributes, 'class', patch.className);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
function applyUnifiedTree(node, options, inPicture) {
|
|
106
|
+
if (!inPicture)
|
|
107
|
+
applyUnifiedNode(node, options);
|
|
108
|
+
const childrenInPicture = inPicture || isPicture(node);
|
|
109
|
+
for (const child of node.children ?? [])
|
|
110
|
+
applyUnifiedTree(child, options, childrenInPicture);
|
|
111
|
+
}
|
|
112
|
+
/** Unified rehype plugin: `unified` processors and Astro 6 `markdown.rehypePlugins`. */
|
|
113
|
+
export function rehypeContentImages(options = {}) {
|
|
114
|
+
const resolved = resolveContentImageOptions(options);
|
|
115
|
+
return (tree) => {
|
|
116
|
+
applyUnifiedTree(tree, resolved, false);
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
function isInsidePicture(node, ctx) {
|
|
120
|
+
for (let parent = ctx.parent(node); parent; parent = ctx.parent(parent)) {
|
|
121
|
+
if (isPicture(parent))
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
/** Sätteri hast plugin: Astro's default Markdown processor, through `hastPlugins`. */
|
|
127
|
+
export function satteriContentImages(options = {}) {
|
|
128
|
+
const resolved = resolveContentImageOptions(options);
|
|
129
|
+
const mdxVisitor = {
|
|
130
|
+
filter: ['img'],
|
|
131
|
+
visit(node, ctx) {
|
|
132
|
+
if (isInsidePicture(node, ctx))
|
|
133
|
+
return;
|
|
134
|
+
const patch = mdxImagePatch(node.attributes ?? [], resolved);
|
|
135
|
+
if (patch.loading !== undefined)
|
|
136
|
+
ctx.setProperty(node, 'loading', patch.loading);
|
|
137
|
+
if (patch.decoding !== undefined)
|
|
138
|
+
ctx.setProperty(node, 'decoding', patch.decoding);
|
|
139
|
+
if (patch.className !== undefined)
|
|
140
|
+
ctx.setProperty(node, 'class', patch.className);
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
return {
|
|
144
|
+
name: 'hagilight:content-images',
|
|
145
|
+
element: {
|
|
146
|
+
filter: ['img'],
|
|
147
|
+
visit(node, ctx) {
|
|
148
|
+
if (isInsidePicture(node, ctx))
|
|
149
|
+
return;
|
|
150
|
+
const patch = hastImagePatch(node.properties ?? {}, resolved);
|
|
151
|
+
if (patch.loading !== undefined)
|
|
152
|
+
ctx.setProperty(node, 'loading', patch.loading);
|
|
153
|
+
if (patch.decoding !== undefined)
|
|
154
|
+
ctx.setProperty(node, 'decoding', patch.decoding);
|
|
155
|
+
if (patch.classNames !== undefined)
|
|
156
|
+
ctx.setProperty(node, 'className', patch.classNames);
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
mdxJsxFlowElement: mdxVisitor,
|
|
160
|
+
mdxJsxTextElement: mdxVisitor,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
const RECORD_KEY = Symbol.for('hagilight.content-images');
|
|
164
|
+
function recordOf(processor) {
|
|
165
|
+
const holder = processor;
|
|
166
|
+
holder[RECORD_KEY] ??= { optedOut: false, warned: new Set() };
|
|
167
|
+
return holder[RECORD_KEY];
|
|
168
|
+
}
|
|
169
|
+
function pluginListOf(processor) {
|
|
170
|
+
const hastPlugins = processor.options?.hastPlugins;
|
|
171
|
+
const rehypePlugins = processor.options?.rehypePlugins;
|
|
172
|
+
if (processor.name === 'satteri' && Array.isArray(hastPlugins))
|
|
173
|
+
return hastPlugins;
|
|
174
|
+
if (processor.name === 'unified' && Array.isArray(rehypePlugins))
|
|
175
|
+
return rehypePlugins;
|
|
176
|
+
return undefined;
|
|
177
|
+
}
|
|
178
|
+
function warnOnce(record, key, logger, message) {
|
|
179
|
+
if (record.warned.has(key))
|
|
180
|
+
return;
|
|
181
|
+
record.warned.add(key);
|
|
182
|
+
logger.warn(message);
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Register the content-image plugin on the active Markdown processor. The first enabled
|
|
186
|
+
* call appends one adapter; an `enabled: false` call opts the whole site out and removes
|
|
187
|
+
* only the adapter it did not append, so the result does not depend on hook order.
|
|
188
|
+
*/
|
|
189
|
+
export function registerContentImages({ config, logger, enabled }) {
|
|
190
|
+
const processor = config.markdown?.processor;
|
|
191
|
+
if (!processor) {
|
|
192
|
+
if (enabled) {
|
|
193
|
+
logger.warn('Hagilight content images need a Markdown processor, but the Astro config has none. Body images are left unchanged.');
|
|
194
|
+
}
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
const record = recordOf(processor);
|
|
198
|
+
if (!enabled) {
|
|
199
|
+
record.optedOut = true;
|
|
200
|
+
if (record.list && record.entry !== undefined) {
|
|
201
|
+
const index = record.list.indexOf(record.entry);
|
|
202
|
+
if (index !== -1)
|
|
203
|
+
record.list.splice(index, 1);
|
|
204
|
+
}
|
|
205
|
+
record.entry = undefined;
|
|
206
|
+
record.list = undefined;
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
if (record.optedOut || record.entry !== undefined)
|
|
210
|
+
return;
|
|
211
|
+
const list = pluginListOf(processor);
|
|
212
|
+
if (!list) {
|
|
213
|
+
warnOnce(record, 'unsupported', logger, `Hagilight content images cannot run on the "${String(processor.name)}" Markdown processor. Body images are left unchanged.`);
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
const plugin = processor.name === 'satteri' ? satteriContentImages() : rehypeContentImages;
|
|
217
|
+
list.push(plugin);
|
|
218
|
+
record.entry = plugin;
|
|
219
|
+
record.list = list;
|
|
220
|
+
}
|
|
221
|
+
/** `astro:config:done` re-check: warns once if an enabled site's adapter is missing from the final processor. */
|
|
222
|
+
export function checkContentImageRegistration({ config, logger, enabled }) {
|
|
223
|
+
if (!enabled)
|
|
224
|
+
return;
|
|
225
|
+
const processor = config.markdown?.processor;
|
|
226
|
+
if (!processor)
|
|
227
|
+
return;
|
|
228
|
+
const record = recordOf(processor);
|
|
229
|
+
if (record.optedOut || record.warned.has('unsupported'))
|
|
230
|
+
return;
|
|
231
|
+
if (record.entry !== undefined && pluginListOf(processor)?.includes(record.entry))
|
|
232
|
+
return;
|
|
233
|
+
warnOnce(record, 'lost', logger, `Hagilight content images were not found in the final "${String(processor.name)}" Markdown processor. Body images are left unchanged.`);
|
|
234
|
+
}
|
package/dist/promotions.js
CHANGED
|
@@ -148,7 +148,7 @@ function localeCandidates(locale) {
|
|
|
148
148
|
candidates.push('zh-cn', 'zh-hant', 'zh');
|
|
149
149
|
}
|
|
150
150
|
candidates.push('en-us', 'en');
|
|
151
|
-
return
|
|
151
|
+
return Array.from(new Set(candidates));
|
|
152
152
|
}
|
|
153
153
|
function localized(value, locale) {
|
|
154
154
|
const values = new Map(Object.entries(value).map(([key, text]) => [key.toLowerCase(), text]));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hagicode/hagilight-core",
|
|
3
|
-
"version": "0.8.1-dev.
|
|
3
|
+
"version": "0.8.1-dev.91.1.ab66a07",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Shared TypeScript utilities, components, and assets for HagiCode Astro and Starlight sites",
|
|
6
6
|
"repository": {
|
|
@@ -46,10 +46,18 @@
|
|
|
46
46
|
"types": "./dist/promotions.d.ts",
|
|
47
47
|
"default": "./dist/promotions.js"
|
|
48
48
|
},
|
|
49
|
+
"./promoto-banner": {
|
|
50
|
+
"types": "./dist/promoto-banner.d.ts",
|
|
51
|
+
"default": "./dist/promoto-banner.js"
|
|
52
|
+
},
|
|
49
53
|
"./analytics-events": {
|
|
50
54
|
"types": "./dist/analytics-events.d.ts",
|
|
51
55
|
"default": "./dist/analytics-events.js"
|
|
52
56
|
},
|
|
57
|
+
"./content-images": {
|
|
58
|
+
"types": "./dist/content-images.d.ts",
|
|
59
|
+
"default": "./dist/content-images.js"
|
|
60
|
+
},
|
|
53
61
|
"./Copyright": "./Copyright.astro",
|
|
54
62
|
"./PromotoBanner": "./PromotoBanner.astro",
|
|
55
63
|
"./GoogleAnalytics": "./GoogleAnalytics.astro",
|
|
@@ -69,6 +77,11 @@
|
|
|
69
77
|
"peerDependencies": {
|
|
70
78
|
"astro": "^6.0.7 || ^7.3.5"
|
|
71
79
|
},
|
|
80
|
+
"peerDependenciesMeta": {
|
|
81
|
+
"astro": {
|
|
82
|
+
"optional": true
|
|
83
|
+
}
|
|
84
|
+
},
|
|
72
85
|
"devDependencies": {
|
|
73
86
|
"astro": "^7.3.5"
|
|
74
87
|
},
|