@astrojs/markdown-remark 2.0.1 → 2.1.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.
@@ -1,5 +1,5 @@
1
- @astrojs/markdown-remark:build: cache hit, replaying output a66e40aa1dc7052c
1
+ @astrojs/markdown-remark:build: cache hit, replaying output a9a85fd17740b5e6
2
2
  @astrojs/markdown-remark:build: 
3
- @astrojs/markdown-remark:build: > @astrojs/markdown-remark@2.0.1 build /home/runner/work/astro/astro/packages/markdown/remark
3
+ @astrojs/markdown-remark:build: > @astrojs/markdown-remark@2.1.0 build /home/runner/work/astro/astro/packages/markdown/remark
4
4
  @astrojs/markdown-remark:build: > astro-scripts build "src/**/*.ts" && tsc -p tsconfig.json
5
5
  @astrojs/markdown-remark:build: 
package/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # @astrojs/markdown-remark
2
2
 
3
+ ## 2.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#6344](https://github.com/withastro/astro/pull/6344) [`694918a56`](https://github.com/withastro/astro/commit/694918a56b01104831296be0c25456135a63c784) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Add a new experimental flag (`experimental.assets`) to enable our new core Assets story.
8
+
9
+ This unlocks a few features:
10
+
11
+ - A new built-in image component and JavaScript API to transform and optimize images.
12
+ - Relative images with automatic optimization in Markdown.
13
+ - Support for validating assets using content collections.
14
+ - and more!
15
+
16
+ See [Assets (Experimental)](https://docs.astro.build/en/guides/assets/) on our docs site for more information on how to use this feature!
17
+
18
+ - [#6213](https://github.com/withastro/astro/pull/6213) [`afbbc4d5b`](https://github.com/withastro/astro/commit/afbbc4d5bfafc1779bac00b41c2a1cb1c90f2808) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Updated compilation settings to disable downlevelling for Node 14
19
+
20
+ ### Patch Changes
21
+
22
+ - Updated dependencies [[`fec583909`](https://github.com/withastro/astro/commit/fec583909ab62829dc0c1600e2387979365f2b94), [`b087b83fe`](https://github.com/withastro/astro/commit/b087b83fe266c431fe34a07d5c2293cc4ab011c6), [`694918a56`](https://github.com/withastro/astro/commit/694918a56b01104831296be0c25456135a63c784), [`a20610609`](https://github.com/withastro/astro/commit/a20610609863ae3b48afe96819b8f11ae4f414d5), [`a4a74ab70`](https://github.com/withastro/astro/commit/a4a74ab70cd2aa0d812a1f6b202c4e240a8913bf), [`75921b3cd`](https://github.com/withastro/astro/commit/75921b3cd916d439f6392c487c21532fde35ed13), [`afbbc4d5b`](https://github.com/withastro/astro/commit/afbbc4d5bfafc1779bac00b41c2a1cb1c90f2808)]:
23
+ - astro@2.1.0
24
+ - @astrojs/prism@2.1.0
25
+
3
26
  ## 2.0.1
4
27
 
5
28
  ### Patch Changes
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { toRemarkInitializeAstroData } from "./frontmatter-injection.js";
2
2
  import { loadPlugins } from "./load-plugins.js";
3
3
  import { rehypeHeadingIds } from "./rehype-collect-headings.js";
4
- import toRemarkContentRelImageError from "./remark-content-rel-image-error.js";
4
+ import toRemarkCollectImages from "./remark-collect-images.js";
5
5
  import remarkPrism from "./remark-prism.js";
6
6
  import scopedStyles from "./remark-scoped-styles.js";
7
7
  import remarkShiki from "./remark-shiki.js";
@@ -13,6 +13,7 @@ import markdownToHtml from "remark-rehype";
13
13
  import remarkSmartypants from "remark-smartypants";
14
14
  import { unified } from "unified";
15
15
  import { VFile } from "vfile";
16
+ import { rehypeImages } from "./rehype-images.js";
16
17
  import { rehypeHeadingIds as rehypeHeadingIds2 } from "./rehype-collect-headings.js";
17
18
  export * from "./types.js";
18
19
  const markdownConfigDefaults = {
@@ -28,6 +29,7 @@ const markdownConfigDefaults = {
28
29
  gfm: true,
29
30
  smartypants: true
30
31
  };
32
+ const isPerformanceBenchmark = Boolean(process.env.ASTRO_PERFORMANCE_BENCHMARK);
31
33
  async function renderMarkdown(content, opts) {
32
34
  var _a;
33
35
  let {
@@ -39,32 +41,37 @@ async function renderMarkdown(content, opts) {
39
41
  remarkRehype = markdownConfigDefaults.remarkRehype,
40
42
  gfm = markdownConfigDefaults.gfm,
41
43
  smartypants = markdownConfigDefaults.smartypants,
42
- contentDir,
43
44
  frontmatter: userFrontmatter = {}
44
45
  } = opts;
45
46
  const input = new VFile({ value: content, path: fileURL });
46
47
  const scopedClassName = (_a = opts.$) == null ? void 0 : _a.scopedClassName;
47
48
  let parser = unified().use(markdown).use(toRemarkInitializeAstroData({ userFrontmatter })).use([]);
48
- if (gfm) {
49
- parser.use(remarkGfm);
50
- }
51
- if (smartypants) {
52
- parser.use(remarkSmartypants);
49
+ if (!isPerformanceBenchmark && gfm) {
50
+ if (gfm) {
51
+ parser.use(remarkGfm);
52
+ }
53
+ if (smartypants) {
54
+ parser.use(remarkSmartypants);
55
+ }
53
56
  }
54
57
  const loadedRemarkPlugins = await Promise.all(loadPlugins(remarkPlugins));
55
58
  const loadedRehypePlugins = await Promise.all(loadPlugins(rehypePlugins));
56
59
  loadedRemarkPlugins.forEach(([plugin, pluginOpts]) => {
57
60
  parser.use([[plugin, pluginOpts]]);
58
61
  });
59
- if (scopedClassName) {
60
- parser.use([scopedStyles(scopedClassName)]);
61
- }
62
- if (syntaxHighlight === "shiki") {
63
- parser.use([await remarkShiki(shikiConfig, scopedClassName)]);
64
- } else if (syntaxHighlight === "prism") {
65
- parser.use([remarkPrism(scopedClassName)]);
62
+ if (!isPerformanceBenchmark) {
63
+ if (scopedClassName) {
64
+ parser.use([scopedStyles(scopedClassName)]);
65
+ }
66
+ if (syntaxHighlight === "shiki") {
67
+ parser.use([await remarkShiki(shikiConfig, scopedClassName)]);
68
+ } else if (syntaxHighlight === "prism") {
69
+ parser.use([remarkPrism(scopedClassName)]);
70
+ }
71
+ if (opts.experimentalAssets) {
72
+ parser.use([toRemarkCollectImages(opts.resolveImage)]);
73
+ }
66
74
  }
67
- parser.use([toRemarkContentRelImageError({ contentDir })]);
68
75
  parser.use([
69
76
  [
70
77
  markdownToHtml,
@@ -78,7 +85,13 @@ async function renderMarkdown(content, opts) {
78
85
  loadedRehypePlugins.forEach(([plugin, pluginOpts]) => {
79
86
  parser.use([[plugin, pluginOpts]]);
80
87
  });
81
- parser.use([rehypeHeadingIds, rehypeRaw]).use(rehypeStringify, { allowDangerousHtml: true });
88
+ if (opts.experimentalAssets) {
89
+ parser.use(rehypeImages(await opts.imageService, opts.assetsDir));
90
+ }
91
+ if (!isPerformanceBenchmark) {
92
+ parser.use([rehypeHeadingIds]);
93
+ }
94
+ parser.use([rehypeRaw]).use(rehypeStringify, { allowDangerousHtml: true });
82
95
  let vfile;
83
96
  try {
84
97
  vfile = await parser.process(input);
@@ -0,0 +1,2 @@
1
+ import type { MarkdownVFile } from './types.js';
2
+ export declare function rehypeImages(imageService: any, assetsDir: URL | undefined): () => (tree: any, file: MarkdownVFile) => void;
@@ -0,0 +1,71 @@
1
+ import sizeOf from "image-size";
2
+ import { join as pathJoin } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { visit } from "unist-util-visit";
5
+ import { pathToFileURL } from "url";
6
+ function rehypeImages(imageService, assetsDir) {
7
+ return () => function(tree, file) {
8
+ visit(tree, (node) => {
9
+ var _a;
10
+ if (!assetsDir)
11
+ return;
12
+ if (node.type !== "element")
13
+ return;
14
+ if (node.tagName !== "img")
15
+ return;
16
+ if ((_a = node.properties) == null ? void 0 : _a.src) {
17
+ if (file.dirname) {
18
+ if (!isRelativePath(node.properties.src) && !isAliasedPath(node.properties.src))
19
+ return;
20
+ let fileURL;
21
+ if (isAliasedPath(node.properties.src)) {
22
+ fileURL = new URL(stripAliasPath(node.properties.src), assetsDir);
23
+ } else {
24
+ fileURL = pathToFileURL(pathJoin(file.dirname, node.properties.src));
25
+ }
26
+ const fileData = sizeOf(fileURLToPath(fileURL));
27
+ fileURL.searchParams.append("origWidth", fileData.width.toString());
28
+ fileURL.searchParams.append("origHeight", fileData.height.toString());
29
+ fileURL.searchParams.append("origFormat", fileData.type.toString());
30
+ let options = {
31
+ src: {
32
+ src: fileURL,
33
+ width: fileData.width,
34
+ height: fileData.height,
35
+ format: fileData.type
36
+ },
37
+ alt: node.properties.alt
38
+ };
39
+ const imageURL = imageService.getURL(options);
40
+ node.properties = Object.assign(node.properties, {
41
+ src: imageURL,
42
+ ...imageService.getHTMLAttributes !== void 0 ? imageService.getHTMLAttributes(options) : {}
43
+ });
44
+ }
45
+ }
46
+ });
47
+ };
48
+ }
49
+ function isAliasedPath(path) {
50
+ return path.startsWith("~/assets");
51
+ }
52
+ function stripAliasPath(path) {
53
+ return path.replace("~/assets/", "");
54
+ }
55
+ function isRelativePath(path) {
56
+ return startsWithDotDotSlash(path) || startsWithDotSlash(path);
57
+ }
58
+ function startsWithDotDotSlash(path) {
59
+ const c1 = path[0];
60
+ const c2 = path[1];
61
+ const c3 = path[2];
62
+ return c1 === "." && c2 === "." && c3 === "/";
63
+ }
64
+ function startsWithDotSlash(path) {
65
+ const c1 = path[0];
66
+ const c2 = path[1];
67
+ return c1 === "." && c2 === "/";
68
+ }
69
+ export {
70
+ rehypeImages
71
+ };
@@ -0,0 +1,4 @@
1
+ import type { VFile } from 'vfile';
2
+ declare type OptionalResolveImage = ((path: string) => Promise<string>) | undefined;
3
+ export default function toRemarkCollectImages(resolveImage: OptionalResolveImage): () => (tree: any, vfile: VFile) => Promise<void>;
4
+ export {};
@@ -0,0 +1,28 @@
1
+ import { visit } from "unist-util-visit";
2
+ function toRemarkCollectImages(resolveImage) {
3
+ return () => async function(tree, vfile) {
4
+ if (typeof (vfile == null ? void 0 : vfile.path) !== "string")
5
+ return;
6
+ const imagePaths = /* @__PURE__ */ new Set();
7
+ visit(tree, "image", function raiseError(node) {
8
+ imagePaths.add(node.url);
9
+ });
10
+ if (imagePaths.size === 0) {
11
+ vfile.data.imagePaths = [];
12
+ return;
13
+ } else if (resolveImage) {
14
+ const mapping = /* @__PURE__ */ new Map();
15
+ for (const path of Array.from(imagePaths)) {
16
+ const id = await resolveImage(path);
17
+ mapping.set(path, id);
18
+ }
19
+ visit(tree, "image", function raiseError(node) {
20
+ node.url = mapping.get(node.url);
21
+ });
22
+ }
23
+ vfile.data.imagePaths = Array.from(imagePaths);
24
+ };
25
+ }
26
+ export {
27
+ toRemarkCollectImages as default
28
+ };
package/dist/types.d.ts CHANGED
@@ -38,10 +38,12 @@ export interface MarkdownRenderingOptions extends AstroMarkdownOptions {
38
38
  $?: {
39
39
  scopedClassName: string | null;
40
40
  };
41
- /** Used to prevent relative image imports from `src/content/` */
42
- contentDir: URL;
43
41
  /** Used for frontmatter injection plugins */
44
42
  frontmatter?: Record<string, any>;
43
+ experimentalAssets?: boolean;
44
+ imageService?: any;
45
+ assetsDir?: URL;
46
+ resolveImage?: (path: string) => Promise<string>;
45
47
  }
46
48
  export interface MarkdownHeading {
47
49
  depth: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astrojs/markdown-remark",
3
- "version": "2.0.1",
3
+ "version": "2.1.0",
4
4
  "type": "module",
5
5
  "author": "withastro",
6
6
  "license": "MIT",
@@ -17,11 +17,12 @@
17
17
  "./dist/internal.js": "./dist/internal.js"
18
18
  },
19
19
  "peerDependencies": {
20
- "astro": "^2.0.2"
20
+ "astro": "^2.1.0"
21
21
  },
22
22
  "dependencies": {
23
- "@astrojs/prism": "^2.0.0",
23
+ "@astrojs/prism": "^2.1.0",
24
24
  "github-slugger": "^1.4.0",
25
+ "image-size": "^1.0.2",
25
26
  "import-meta-resolve": "^2.1.0",
26
27
  "rehype-raw": "^6.1.1",
27
28
  "rehype-stringify": "^9.0.3",
@@ -42,7 +43,7 @@
42
43
  "@types/mdast": "^3.0.10",
43
44
  "@types/mocha": "^9.1.1",
44
45
  "@types/unist": "^2.0.6",
45
- "astro-scripts": "0.0.10",
46
+ "astro-scripts": "0.0.14",
46
47
  "chai": "^4.3.6",
47
48
  "mdast-util-mdx-expression": "^1.3.1",
48
49
  "mocha": "^9.2.2"
package/src/index.ts CHANGED
@@ -8,7 +8,7 @@ import type {
8
8
  import { toRemarkInitializeAstroData } from './frontmatter-injection.js';
9
9
  import { loadPlugins } from './load-plugins.js';
10
10
  import { rehypeHeadingIds } from './rehype-collect-headings.js';
11
- import toRemarkContentRelImageError from './remark-content-rel-image-error.js';
11
+ import toRemarkCollectImages from './remark-collect-images.js';
12
12
  import remarkPrism from './remark-prism.js';
13
13
  import scopedStyles from './remark-scoped-styles.js';
14
14
  import remarkShiki from './remark-shiki.js';
@@ -21,6 +21,7 @@ import markdownToHtml from 'remark-rehype';
21
21
  import remarkSmartypants from 'remark-smartypants';
22
22
  import { unified } from 'unified';
23
23
  import { VFile } from 'vfile';
24
+ import { rehypeImages } from './rehype-images.js';
24
25
 
25
26
  export { rehypeHeadingIds } from './rehype-collect-headings.js';
26
27
  export * from './types.js';
@@ -39,6 +40,9 @@ export const markdownConfigDefaults: Omit<Required<AstroMarkdownOptions>, 'draft
39
40
  smartypants: true,
40
41
  };
41
42
 
43
+ // Skip nonessential plugins during performance benchmark runs
44
+ const isPerformanceBenchmark = Boolean(process.env.ASTRO_PERFORMANCE_BENCHMARK);
45
+
42
46
  /** Shared utility for rendering markdown */
43
47
  export async function renderMarkdown(
44
48
  content: string,
@@ -53,7 +57,6 @@ export async function renderMarkdown(
53
57
  remarkRehype = markdownConfigDefaults.remarkRehype,
54
58
  gfm = markdownConfigDefaults.gfm,
55
59
  smartypants = markdownConfigDefaults.smartypants,
56
- contentDir,
57
60
  frontmatter: userFrontmatter = {},
58
61
  } = opts;
59
62
  const input = new VFile({ value: content, path: fileURL });
@@ -64,12 +67,13 @@ export async function renderMarkdown(
64
67
  .use(toRemarkInitializeAstroData({ userFrontmatter }))
65
68
  .use([]);
66
69
 
67
- if (gfm) {
68
- parser.use(remarkGfm);
69
- }
70
-
71
- if (smartypants) {
72
- parser.use(remarkSmartypants);
70
+ if (!isPerformanceBenchmark && gfm) {
71
+ if (gfm) {
72
+ parser.use(remarkGfm);
73
+ }
74
+ if (smartypants) {
75
+ parser.use(remarkSmartypants);
76
+ }
73
77
  }
74
78
 
75
79
  const loadedRemarkPlugins = await Promise.all(loadPlugins(remarkPlugins));
@@ -79,18 +83,22 @@ export async function renderMarkdown(
79
83
  parser.use([[plugin, pluginOpts]]);
80
84
  });
81
85
 
82
- if (scopedClassName) {
83
- parser.use([scopedStyles(scopedClassName)]);
84
- }
86
+ if (!isPerformanceBenchmark) {
87
+ if (scopedClassName) {
88
+ parser.use([scopedStyles(scopedClassName)]);
89
+ }
85
90
 
86
- if (syntaxHighlight === 'shiki') {
87
- parser.use([await remarkShiki(shikiConfig, scopedClassName)]);
88
- } else if (syntaxHighlight === 'prism') {
89
- parser.use([remarkPrism(scopedClassName)]);
90
- }
91
+ if (syntaxHighlight === 'shiki') {
92
+ parser.use([await remarkShiki(shikiConfig, scopedClassName)]);
93
+ } else if (syntaxHighlight === 'prism') {
94
+ parser.use([remarkPrism(scopedClassName)]);
95
+ }
91
96
 
92
- // Apply later in case user plugins resolve relative image paths
93
- parser.use([toRemarkContentRelImageError({ contentDir })]);
97
+ if (opts.experimentalAssets) {
98
+ // Apply later in case user plugins resolve relative image paths
99
+ parser.use([toRemarkCollectImages(opts.resolveImage)]);
100
+ }
101
+ }
94
102
 
95
103
  parser.use([
96
104
  [
@@ -107,7 +115,14 @@ export async function renderMarkdown(
107
115
  parser.use([[plugin, pluginOpts]]);
108
116
  });
109
117
 
110
- parser.use([rehypeHeadingIds, rehypeRaw]).use(rehypeStringify, { allowDangerousHtml: true });
118
+ if (opts.experimentalAssets) {
119
+ parser.use(rehypeImages(await opts.imageService, opts.assetsDir));
120
+ }
121
+ if (!isPerformanceBenchmark) {
122
+ parser.use([rehypeHeadingIds]);
123
+ }
124
+
125
+ parser.use([rehypeRaw]).use(rehypeStringify, { allowDangerousHtml: true });
111
126
 
112
127
  let vfile: MarkdownVFile;
113
128
  try {
@@ -144,7 +159,7 @@ function prefixError(err: any, prefix: string) {
144
159
  const wrappedError = new Error(`${prefix}${err ? `: ${err}` : ''}`);
145
160
  try {
146
161
  wrappedError.stack = err.stack;
147
- // @ts-ignore
162
+ // @ts-expect-error
148
163
  wrappedError.cause = err;
149
164
  } catch (error) {
150
165
  // It's ok if we could not set the stack or cause - the message is the most important part
@@ -1,7 +1,8 @@
1
1
  import { type Expression, type Super } from 'estree';
2
2
  import Slugger from 'github-slugger';
3
3
  import { type MdxTextExpression } from 'mdast-util-mdx-expression';
4
- import { visit, type Node } from 'unist-util-visit';
4
+ import { type Node } from 'unist';
5
+ import { visit } from 'unist-util-visit';
5
6
 
6
7
  import { InvalidAstroDataError, safelyGetAstroData } from './frontmatter-injection.js';
7
8
  import type { MarkdownAstroData, MarkdownHeading, MarkdownVFile, RehypePlugin } from './types.js';
@@ -0,0 +1,78 @@
1
+ import sizeOf from 'image-size';
2
+ import { join as pathJoin } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { visit } from 'unist-util-visit';
5
+ import { pathToFileURL } from 'url';
6
+ import type { MarkdownVFile } from './types.js';
7
+
8
+ export function rehypeImages(imageService: any, assetsDir: URL | undefined) {
9
+ return () =>
10
+ function (tree: any, file: MarkdownVFile) {
11
+ visit(tree, (node) => {
12
+ if (!assetsDir) return;
13
+ if (node.type !== 'element') return;
14
+ if (node.tagName !== 'img') return;
15
+
16
+ if (node.properties?.src) {
17
+ if (file.dirname) {
18
+ if (!isRelativePath(node.properties.src) && !isAliasedPath(node.properties.src)) return;
19
+
20
+ let fileURL: URL;
21
+ if (isAliasedPath(node.properties.src)) {
22
+ fileURL = new URL(stripAliasPath(node.properties.src), assetsDir);
23
+ } else {
24
+ fileURL = pathToFileURL(pathJoin(file.dirname, node.properties.src));
25
+ }
26
+
27
+ const fileData = sizeOf(fileURLToPath(fileURL));
28
+ fileURL.searchParams.append('origWidth', fileData.width!.toString());
29
+ fileURL.searchParams.append('origHeight', fileData.height!.toString());
30
+ fileURL.searchParams.append('origFormat', fileData.type!.toString());
31
+
32
+ let options = {
33
+ src: {
34
+ src: fileURL,
35
+ width: fileData.width,
36
+ height: fileData.height,
37
+ format: fileData.type,
38
+ },
39
+ alt: node.properties.alt,
40
+ };
41
+
42
+ const imageURL = imageService.getURL(options);
43
+ node.properties = Object.assign(node.properties, {
44
+ src: imageURL,
45
+ ...(imageService.getHTMLAttributes !== undefined
46
+ ? imageService.getHTMLAttributes(options)
47
+ : {}),
48
+ });
49
+ }
50
+ }
51
+ });
52
+ };
53
+ }
54
+
55
+ function isAliasedPath(path: string) {
56
+ return path.startsWith('~/assets');
57
+ }
58
+
59
+ function stripAliasPath(path: string) {
60
+ return path.replace('~/assets/', '');
61
+ }
62
+
63
+ function isRelativePath(path: string) {
64
+ return startsWithDotDotSlash(path) || startsWithDotSlash(path);
65
+ }
66
+
67
+ function startsWithDotDotSlash(path: string) {
68
+ const c1 = path[0];
69
+ const c2 = path[1];
70
+ const c3 = path[2];
71
+ return c1 === '.' && c2 === '.' && c3 === '/';
72
+ }
73
+
74
+ function startsWithDotSlash(path: string) {
75
+ const c1 = path[0];
76
+ const c2 = path[1];
77
+ return c1 === '.' && c2 === '/';
78
+ }
@@ -0,0 +1,32 @@
1
+ import type { Image } from 'mdast';
2
+ import { visit } from 'unist-util-visit';
3
+ import type { VFile } from 'vfile';
4
+
5
+ type OptionalResolveImage = ((path: string) => Promise<string>) | undefined;
6
+
7
+ export default function toRemarkCollectImages(resolveImage: OptionalResolveImage) {
8
+ return () =>
9
+ async function (tree: any, vfile: VFile) {
10
+ if (typeof vfile?.path !== 'string') return;
11
+
12
+ const imagePaths = new Set<string>();
13
+ visit(tree, 'image', function raiseError(node: Image) {
14
+ imagePaths.add(node.url);
15
+ });
16
+ if (imagePaths.size === 0) {
17
+ vfile.data.imagePaths = [];
18
+ return;
19
+ } else if (resolveImage) {
20
+ const mapping = new Map<string, string>();
21
+ for (const path of Array.from(imagePaths)) {
22
+ const id = await resolveImage(path);
23
+ mapping.set(path, id);
24
+ }
25
+ visit(tree, 'image', function raiseError(node: Image) {
26
+ node.url = mapping.get(node.url)!;
27
+ });
28
+ }
29
+
30
+ vfile.data.imagePaths = Array.from(imagePaths);
31
+ };
32
+ }
package/src/types.ts CHANGED
@@ -58,10 +58,12 @@ export interface MarkdownRenderingOptions extends AstroMarkdownOptions {
58
58
  $?: {
59
59
  scopedClassName: string | null;
60
60
  };
61
- /** Used to prevent relative image imports from `src/content/` */
62
- contentDir: URL;
63
61
  /** Used for frontmatter injection plugins */
64
62
  frontmatter?: Record<string, any>;
63
+ experimentalAssets?: boolean;
64
+ imageService?: any;
65
+ assetsDir?: URL;
66
+ resolveImage?: (path: string) => Promise<string>;
65
67
  }
66
68
 
67
69
  export interface MarkdownHeading {
package/tsconfig.json CHANGED
@@ -3,8 +3,8 @@
3
3
  "include": ["src"],
4
4
  "compilerOptions": {
5
5
  "allowJs": true,
6
- "target": "ES2020",
7
- "module": "ES2020",
6
+ "target": "ES2021",
7
+ "module": "ES2022",
8
8
  "outDir": "./dist"
9
9
  }
10
10
  }
@@ -1,8 +0,0 @@
1
- import type { VFile } from 'vfile';
2
- /**
3
- * `src/content/` does not support relative image paths.
4
- * This plugin throws an error if any are found
5
- */
6
- export default function toRemarkContentRelImageError({ contentDir }: {
7
- contentDir: URL;
8
- }): () => (tree: any, vfile: VFile) => void;
@@ -1,41 +0,0 @@
1
- import { visit } from "unist-util-visit";
2
- import { pathToFileURL } from "url";
3
- function toRemarkContentRelImageError({ contentDir }) {
4
- return function remarkContentRelImageError() {
5
- return (tree, vfile) => {
6
- if (typeof (vfile == null ? void 0 : vfile.path) !== "string")
7
- return;
8
- const isContentFile = pathToFileURL(vfile.path).href.startsWith(contentDir.href);
9
- if (!isContentFile)
10
- return;
11
- const relImagePaths = /* @__PURE__ */ new Set();
12
- visit(tree, "image", function raiseError(node) {
13
- if (isRelativePath(node.url)) {
14
- relImagePaths.add(node.url);
15
- }
16
- });
17
- if (relImagePaths.size === 0)
18
- return;
19
- const errorMessage = `Relative image paths are not supported in the content/ directory. Place local images in the public/ directory and use absolute paths (see https://docs.astro.build/en/guides/images/#in-markdown-files)
20
- ` + [...relImagePaths].map((path) => JSON.stringify(path)).join(",\n");
21
- throw errorMessage;
22
- };
23
- };
24
- }
25
- function isRelativePath(path) {
26
- return startsWithDotDotSlash(path) || startsWithDotSlash(path);
27
- }
28
- function startsWithDotDotSlash(path) {
29
- const c1 = path[0];
30
- const c2 = path[1];
31
- const c3 = path[2];
32
- return c1 === "." && c2 === "." && c3 === "/";
33
- }
34
- function startsWithDotSlash(path) {
35
- const c1 = path[0];
36
- const c2 = path[1];
37
- return c1 === "." && c2 === "/";
38
- }
39
- export {
40
- toRemarkContentRelImageError as default
41
- };
@@ -1,53 +0,0 @@
1
- import type { Image } from 'mdast';
2
- import { visit } from 'unist-util-visit';
3
- import { pathToFileURL } from 'url';
4
- import type { VFile } from 'vfile';
5
-
6
- /**
7
- * `src/content/` does not support relative image paths.
8
- * This plugin throws an error if any are found
9
- */
10
- export default function toRemarkContentRelImageError({ contentDir }: { contentDir: URL }) {
11
- return function remarkContentRelImageError() {
12
- return (tree: any, vfile: VFile) => {
13
- if (typeof vfile?.path !== 'string') return;
14
-
15
- const isContentFile = pathToFileURL(vfile.path).href.startsWith(contentDir.href);
16
- if (!isContentFile) return;
17
-
18
- const relImagePaths = new Set<string>();
19
- visit(tree, 'image', function raiseError(node: Image) {
20
- if (isRelativePath(node.url)) {
21
- relImagePaths.add(node.url);
22
- }
23
- });
24
- if (relImagePaths.size === 0) return;
25
-
26
- const errorMessage =
27
- `Relative image paths are not supported in the content/ directory. Place local images in the public/ directory and use absolute paths (see https://docs.astro.build/en/guides/images/#in-markdown-files)\n` +
28
- [...relImagePaths].map((path) => JSON.stringify(path)).join(',\n');
29
-
30
- // Throw raw string to use `astro:markdown` default formatting
31
- throw errorMessage;
32
- };
33
- };
34
- }
35
-
36
- // Following utils taken from `packages/astro/src/core/path.ts`:
37
-
38
- function isRelativePath(path: string) {
39
- return startsWithDotDotSlash(path) || startsWithDotSlash(path);
40
- }
41
-
42
- function startsWithDotDotSlash(path: string) {
43
- const c1 = path[0];
44
- const c2 = path[1];
45
- const c3 = path[2];
46
- return c1 === '.' && c2 === '.' && c3 === '/';
47
- }
48
-
49
- function startsWithDotSlash(path: string) {
50
- const c1 = path[0];
51
- const c2 = path[1];
52
- return c1 === '.' && c2 === '/';
53
- }