@riebeckite/core 0.0.21 → 0.0.22
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/dist/index.js
CHANGED
|
@@ -1515,9 +1515,9 @@ import remarkDirective from "remark-directive";
|
|
|
1515
1515
|
import remarkFrontmatter from "remark-frontmatter";
|
|
1516
1516
|
import remarkGfm from "remark-gfm";
|
|
1517
1517
|
import remarkMath from "remark-math";
|
|
1518
|
-
import
|
|
1518
|
+
import remarkParse2 from "remark-parse";
|
|
1519
1519
|
import remarkRehype from "remark-rehype";
|
|
1520
|
-
import { unified } from "unified";
|
|
1520
|
+
import { unified as unified2 } from "unified";
|
|
1521
1521
|
import { matter as matter2 } from "vfile-matter";
|
|
1522
1522
|
|
|
1523
1523
|
// src/content/content_dependency_tracker.ts
|
|
@@ -1896,6 +1896,117 @@ function extractFrontmatter(markdown) {
|
|
|
1896
1896
|
return vfile.data.matter ?? {};
|
|
1897
1897
|
}
|
|
1898
1898
|
|
|
1899
|
+
// src/content/markdown_image.ts
|
|
1900
|
+
import remarkParse from "remark-parse";
|
|
1901
|
+
import { unified } from "unified";
|
|
1902
|
+
function extractMarkdownImages(markdown, sourceSlug) {
|
|
1903
|
+
const tree = unified().use(remarkParse).parse(markdown);
|
|
1904
|
+
const definitions = /* @__PURE__ */ new Map();
|
|
1905
|
+
const references = [];
|
|
1906
|
+
const urls = [];
|
|
1907
|
+
visitMarkdownNodes(tree, (node) => {
|
|
1908
|
+
if (node.type === "definition" && typeof node.url === "string") {
|
|
1909
|
+
const identifier = normalizeIdentifier(node.identifier);
|
|
1910
|
+
if (identifier) definitions.set(identifier, node.url);
|
|
1911
|
+
}
|
|
1912
|
+
if (node.type === "image" && typeof node.url === "string") {
|
|
1913
|
+
urls.push(node.url);
|
|
1914
|
+
}
|
|
1915
|
+
if (node.type === "imageReference") {
|
|
1916
|
+
const identifier = normalizeIdentifier(node.identifier);
|
|
1917
|
+
if (identifier) references.push(identifier);
|
|
1918
|
+
}
|
|
1919
|
+
});
|
|
1920
|
+
for (const reference of references) {
|
|
1921
|
+
const url = definitions.get(reference);
|
|
1922
|
+
if (url) urls.push(url);
|
|
1923
|
+
}
|
|
1924
|
+
return uniqueImages(
|
|
1925
|
+
urls.map((url) => resolveMarkdownImage(url, sourceSlug)).filter((image) => image !== null)
|
|
1926
|
+
);
|
|
1927
|
+
}
|
|
1928
|
+
function normalizeMarkdownImages(sourceSlug) {
|
|
1929
|
+
return () => (tree) => {
|
|
1930
|
+
const definitions = /* @__PURE__ */ new Map();
|
|
1931
|
+
const references = /* @__PURE__ */ new Set();
|
|
1932
|
+
visitMarkdownNodes(tree, (node) => {
|
|
1933
|
+
if (node.type === "definition" && typeof node.url === "string") {
|
|
1934
|
+
const identifier = normalizeIdentifier(node.identifier);
|
|
1935
|
+
if (identifier) definitions.set(identifier, node);
|
|
1936
|
+
}
|
|
1937
|
+
if (node.type === "image" && typeof node.url === "string") {
|
|
1938
|
+
const image = resolveMarkdownImage(node.url, sourceSlug);
|
|
1939
|
+
if (image) node.url = image.url;
|
|
1940
|
+
}
|
|
1941
|
+
if (node.type === "imageReference") {
|
|
1942
|
+
const identifier = normalizeIdentifier(node.identifier);
|
|
1943
|
+
if (identifier) references.add(identifier);
|
|
1944
|
+
}
|
|
1945
|
+
});
|
|
1946
|
+
for (const identifier of references) {
|
|
1947
|
+
const definition = definitions.get(identifier);
|
|
1948
|
+
if (!definition || typeof definition.url !== "string") continue;
|
|
1949
|
+
const image = resolveMarkdownImage(definition.url, sourceSlug);
|
|
1950
|
+
if (image) definition.url = image.url;
|
|
1951
|
+
}
|
|
1952
|
+
};
|
|
1953
|
+
}
|
|
1954
|
+
function resolveMarkdownImage(input, sourceSlug) {
|
|
1955
|
+
if (input.startsWith("//") || /^[a-z][a-z0-9+.-]*:/i.test(input)) {
|
|
1956
|
+
return null;
|
|
1957
|
+
}
|
|
1958
|
+
const [pathAndQuery, hash4 = ""] = splitOnce(input, "#");
|
|
1959
|
+
const [rawPath, query = ""] = splitOnce(pathAndQuery, "?");
|
|
1960
|
+
const decodedPath = decodeUriPath(rawPath);
|
|
1961
|
+
if (!decodedPath || !isImagePath(decodedPath)) return null;
|
|
1962
|
+
const path6 = resolveContentAssetPath(sourceSlug, decodedPath);
|
|
1963
|
+
if (!path6) return null;
|
|
1964
|
+
const encodedPath = path6.split("/").map(encodeURIComponent).join("/");
|
|
1965
|
+
const suffix = `${query ? `?${query}` : ""}${hash4 ? `#${hash4}` : ""}`;
|
|
1966
|
+
return { path: path6, url: `/${encodedPath}${suffix}` };
|
|
1967
|
+
}
|
|
1968
|
+
function resolveContentAssetPath(sourceSlug, targetPath) {
|
|
1969
|
+
const sourceDirectory = sourceSlug.includes("/") ? sourceSlug.slice(0, sourceSlug.lastIndexOf("/")) : "";
|
|
1970
|
+
const parts = [
|
|
1971
|
+
...targetPath.startsWith("/") ? [] : sourceDirectory.split("/"),
|
|
1972
|
+
...normalizeContentPath(targetPath).replace(/^\/+/, "").split("/")
|
|
1973
|
+
];
|
|
1974
|
+
const normalized = [];
|
|
1975
|
+
for (const part of parts) {
|
|
1976
|
+
if (!part || part === ".") continue;
|
|
1977
|
+
if (part === "..") {
|
|
1978
|
+
if (normalized.length === 0) return null;
|
|
1979
|
+
normalized.pop();
|
|
1980
|
+
continue;
|
|
1981
|
+
}
|
|
1982
|
+
normalized.push(part);
|
|
1983
|
+
}
|
|
1984
|
+
return normalized.length > 0 ? normalized.join("/").normalize("NFC") : null;
|
|
1985
|
+
}
|
|
1986
|
+
function visitMarkdownNodes(node, visitor) {
|
|
1987
|
+
const markdownNode = node;
|
|
1988
|
+
visitor(markdownNode);
|
|
1989
|
+
for (const child of markdownNode.children ?? [])
|
|
1990
|
+
visitMarkdownNodes(child, visitor);
|
|
1991
|
+
}
|
|
1992
|
+
function normalizeIdentifier(value) {
|
|
1993
|
+
return typeof value === "string" ? value.toLowerCase() : null;
|
|
1994
|
+
}
|
|
1995
|
+
function decodeUriPath(path6) {
|
|
1996
|
+
try {
|
|
1997
|
+
return decodeURI(path6);
|
|
1998
|
+
} catch {
|
|
1999
|
+
return null;
|
|
2000
|
+
}
|
|
2001
|
+
}
|
|
2002
|
+
function splitOnce(value, separator) {
|
|
2003
|
+
const index = value.indexOf(separator);
|
|
2004
|
+
return index < 0 ? [value] : [value.slice(0, index), value.slice(index + 1)];
|
|
2005
|
+
}
|
|
2006
|
+
function uniqueImages(images) {
|
|
2007
|
+
return [...new Map(images.map((image) => [image.path, image])).values()];
|
|
2008
|
+
}
|
|
2009
|
+
|
|
1899
2010
|
// src/plugin/plugin_cache.ts
|
|
1900
2011
|
import { createHash as createHash5, randomUUID as randomUUID2 } from "node:crypto";
|
|
1901
2012
|
import fs3 from "node:fs/promises";
|
|
@@ -2178,9 +2289,9 @@ var Pipeline = class {
|
|
|
2178
2289
|
this.options.onPersistentContentCacheResult?.("bypass");
|
|
2179
2290
|
}
|
|
2180
2291
|
}
|
|
2181
|
-
const processor =
|
|
2292
|
+
const processor = unified2();
|
|
2182
2293
|
const plugins = this.resolvePlugins();
|
|
2183
|
-
this.use(processor,
|
|
2294
|
+
this.use(processor, remarkParse2);
|
|
2184
2295
|
this.use(processor, remarkDirective);
|
|
2185
2296
|
this.use(processor, remarkFrontmatter, ["yaml", "toml"]);
|
|
2186
2297
|
this.use(processor, function loadFrontmatter() {
|
|
@@ -2220,6 +2331,9 @@ var Pipeline = class {
|
|
|
2220
2331
|
...markdownPipelineContext,
|
|
2221
2332
|
recordLinkResolution: dependencyTracker ? (id, value) => dependencyTracker.recordLinkResolution(id, value) : void 0
|
|
2222
2333
|
});
|
|
2334
|
+
if (context.sourceSlug) {
|
|
2335
|
+
this.use(processor, normalizeMarkdownImages(context.sourceSlug));
|
|
2336
|
+
}
|
|
2223
2337
|
this.use(processor, remarkRehype, { allowDangerousHtml: true });
|
|
2224
2338
|
this.use(processor, rehypeRaw);
|
|
2225
2339
|
for (const plugin of plugins) {
|
|
@@ -2464,9 +2578,9 @@ function visitMarkdownLinkNodes(node, visitor) {
|
|
|
2464
2578
|
function normalizeMarkdownLinkUrl(url, context) {
|
|
2465
2579
|
if (!context.sourceSlug) return null;
|
|
2466
2580
|
if (!isMarkdownContentLink(url)) return null;
|
|
2467
|
-
const [pathAndQuery, hash4 = ""] =
|
|
2468
|
-
const [rawPath, query = ""] =
|
|
2469
|
-
const decodedPath =
|
|
2581
|
+
const [pathAndQuery, hash4 = ""] = splitOnce2(url, "#");
|
|
2582
|
+
const [rawPath, query = ""] = splitOnce2(pathAndQuery, "?");
|
|
2583
|
+
const decodedPath = decodeUriPath2(rawPath);
|
|
2470
2584
|
if (!decodedPath?.toLowerCase().endsWith(".md")) return null;
|
|
2471
2585
|
const resolvedSlug = resolveRelativeMarkdownSlug(
|
|
2472
2586
|
context.sourceSlug,
|
|
@@ -2527,14 +2641,14 @@ function resolveRelativeMarkdownSlug(sourceSlug, targetPath) {
|
|
|
2527
2641
|
}
|
|
2528
2642
|
return normalizedParts.join("/").replace(/\.md$/i, "");
|
|
2529
2643
|
}
|
|
2530
|
-
function
|
|
2644
|
+
function decodeUriPath2(path6) {
|
|
2531
2645
|
try {
|
|
2532
2646
|
return decodeURI(path6);
|
|
2533
2647
|
} catch {
|
|
2534
2648
|
return null;
|
|
2535
2649
|
}
|
|
2536
2650
|
}
|
|
2537
|
-
function
|
|
2651
|
+
function splitOnce2(value, separator) {
|
|
2538
2652
|
const index = value.indexOf(separator);
|
|
2539
2653
|
if (index < 0) return [value];
|
|
2540
2654
|
return [value.slice(0, index), value.slice(index + separator.length)];
|
|
@@ -2857,6 +2971,13 @@ var PluginRuntime = class {
|
|
|
2857
2971
|
collectGeneratedOutputs() {
|
|
2858
2972
|
return this.generatedOutputs.all();
|
|
2859
2973
|
}
|
|
2974
|
+
emitCoreAsset(path6, content) {
|
|
2975
|
+
this.generatedOutputs.sinkFor("core").emitAsset({
|
|
2976
|
+
path: path6,
|
|
2977
|
+
content,
|
|
2978
|
+
dependencies: [{ type: "file", path: path6 }]
|
|
2979
|
+
});
|
|
2980
|
+
}
|
|
2860
2981
|
async resolvePage(pathname, manifest, contentIndex) {
|
|
2861
2982
|
const matches = [];
|
|
2862
2983
|
const requestedPathname = normalizePagePath(pathname);
|
|
@@ -4008,9 +4129,14 @@ function readOptionalStableId(value) {
|
|
|
4008
4129
|
var ManifestBuilder = class {
|
|
4009
4130
|
createEntry(slug, markdown, processed, contentIndex, location, publishing) {
|
|
4010
4131
|
const links = extractContentLinks(markdown, contentIndex);
|
|
4011
|
-
const assets =
|
|
4012
|
-
(
|
|
4013
|
-
|
|
4132
|
+
const assets = [
|
|
4133
|
+
...links.filter(
|
|
4134
|
+
(link) => (link.kind === "image" || link.kind === "attachment") && link.slug !== null
|
|
4135
|
+
).map((link) => ({ path: link.slug })),
|
|
4136
|
+
...extractMarkdownImages(markdown, slug).map((image) => ({
|
|
4137
|
+
path: image.path
|
|
4138
|
+
}))
|
|
4139
|
+
];
|
|
4014
4140
|
const contentId = resolveContentStableId(processed.frontmatter);
|
|
4015
4141
|
return {
|
|
4016
4142
|
slug,
|
|
@@ -4139,6 +4265,11 @@ function determineOutputChanges(input) {
|
|
|
4139
4265
|
(input.previousState?.outputs ?? []).map((output) => [output.path, output])
|
|
4140
4266
|
);
|
|
4141
4267
|
const changedContent = collectChangedContent(input);
|
|
4268
|
+
const changedFiles = /* @__PURE__ */ new Set([
|
|
4269
|
+
...input.changeSet.added,
|
|
4270
|
+
...input.changeSet.changed,
|
|
4271
|
+
...input.changeSet.removed
|
|
4272
|
+
]);
|
|
4142
4273
|
const changedTags = collectChangedTags(
|
|
4143
4274
|
input.previousState,
|
|
4144
4275
|
input.manifest,
|
|
@@ -4152,7 +4283,13 @@ function determineOutputChanges(input) {
|
|
|
4152
4283
|
const affected = /* @__PURE__ */ new Map();
|
|
4153
4284
|
const unchanged = [];
|
|
4154
4285
|
for (const output of current) {
|
|
4155
|
-
if (isOutputAffected(
|
|
4286
|
+
if (isOutputAffected(
|
|
4287
|
+
output,
|
|
4288
|
+
changedContent,
|
|
4289
|
+
changedTags,
|
|
4290
|
+
changedFolders,
|
|
4291
|
+
changedFiles
|
|
4292
|
+
)) {
|
|
4156
4293
|
affected.set(output.path, output);
|
|
4157
4294
|
} else {
|
|
4158
4295
|
unchanged.push(output);
|
|
@@ -4225,7 +4362,7 @@ function contentOutput(entry, dependencies) {
|
|
|
4225
4362
|
dependencies: [{ type: "content", slug: entry.slug }, ...dependencies]
|
|
4226
4363
|
};
|
|
4227
4364
|
}
|
|
4228
|
-
function isOutputAffected(output, changedContent, changedTags, changedFolders) {
|
|
4365
|
+
function isOutputAffected(output, changedContent, changedTags, changedFolders, changedFiles) {
|
|
4229
4366
|
for (const dependency of output.dependencies) {
|
|
4230
4367
|
if (dependency.type === "unknown") return true;
|
|
4231
4368
|
if (dependency.type === "global") return changedContent.size > 0;
|
|
@@ -4237,6 +4374,9 @@ function isOutputAffected(output, changedContent, changedTags, changedFolders) {
|
|
|
4237
4374
|
if (dependency.type === "folder" && changedFolders.has(dependency.folder)) {
|
|
4238
4375
|
return true;
|
|
4239
4376
|
}
|
|
4377
|
+
if (dependency.type === "file" && changedFiles.has(dependency.path)) {
|
|
4378
|
+
return true;
|
|
4379
|
+
}
|
|
4240
4380
|
}
|
|
4241
4381
|
return false;
|
|
4242
4382
|
}
|
|
@@ -4592,6 +4732,7 @@ var ContentManager = class {
|
|
|
4592
4732
|
...await this.pluginRuntime.collectDiagnostics(contentIndex)
|
|
4593
4733
|
];
|
|
4594
4734
|
await this.pluginRuntime.runBuildEnd(manifest, contentIndex);
|
|
4735
|
+
await this.emitPublicImageAssets(manifest);
|
|
4595
4736
|
manifest.generatedOutputs = this.pluginRuntime.collectGeneratedOutputs();
|
|
4596
4737
|
const pluginPageOutputs = await this.pluginRuntime.getPageOutputs(
|
|
4597
4738
|
manifest,
|
|
@@ -4834,6 +4975,21 @@ var ContentManager = class {
|
|
|
4834
4975
|
this.isBuildTime = true;
|
|
4835
4976
|
this.pluginRuntime.enableBuildTime();
|
|
4836
4977
|
}
|
|
4978
|
+
async emitPublicImageAssets(manifest) {
|
|
4979
|
+
const imagePaths = new Set(
|
|
4980
|
+
manifest.publicEntries.flatMap(
|
|
4981
|
+
(entry) => entry.assets.map((asset) => normalizeContentPath(asset.path)).filter(isImagePath)
|
|
4982
|
+
)
|
|
4983
|
+
);
|
|
4984
|
+
const entriesByPath = new Map(
|
|
4985
|
+
(await this.source.scan()).map((entry) => [entry.path, entry])
|
|
4986
|
+
);
|
|
4987
|
+
for (const path6 of imagePaths) {
|
|
4988
|
+
const entry = entriesByPath.get(path6);
|
|
4989
|
+
if (entry)
|
|
4990
|
+
this.pluginRuntime.emitCoreAsset(path6, await this.source.read(entry));
|
|
4991
|
+
}
|
|
4992
|
+
}
|
|
4837
4993
|
observability() {
|
|
4838
4994
|
return this.pipelineOptions.observability ?? noopObservability;
|
|
4839
4995
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Node } from "unist";
|
|
2
|
+
type MarkdownImage = {
|
|
3
|
+
readonly path: string;
|
|
4
|
+
readonly url: string;
|
|
5
|
+
};
|
|
6
|
+
export declare function extractMarkdownImages(markdown: string, sourceSlug: string): readonly MarkdownImage[];
|
|
7
|
+
export declare function normalizeMarkdownImages(sourceSlug: string): () => (tree: Node) => void;
|
|
8
|
+
export {};
|
|
@@ -2,7 +2,7 @@ import type { OutputDescriptor } from "../content/output_dependency.js";
|
|
|
2
2
|
import type { PipelineOptions } from "../pipeline.js";
|
|
3
3
|
import type { ContentLocationInput, ContentManifest, ContentManifestEntry, ContentPublicLocation, PluginPageRoute } from "../types/content_manifest.js";
|
|
4
4
|
import type { Diagnostic } from "../types/diagnostic.js";
|
|
5
|
-
import type { GeneratedOutput } from "../types/generated_output.js";
|
|
5
|
+
import type { GeneratedOutput, GeneratedOutputContent } from "../types/generated_output.js";
|
|
6
6
|
import type { OutputDependency } from "../types/output_dependency.js";
|
|
7
7
|
import { type PluginClientEntry } from "../types/plugin_asset.js";
|
|
8
8
|
import type { ResolvedPluginPage } from "../types/plugin_page.js";
|
|
@@ -58,6 +58,7 @@ export declare class PluginRuntime {
|
|
|
58
58
|
collectClientEntries(): PluginClientEntry[];
|
|
59
59
|
/** Returns registered outputs sorted by path for a deterministic build. */
|
|
60
60
|
collectGeneratedOutputs(): GeneratedOutput[];
|
|
61
|
+
emitCoreAsset(path: string, content: GeneratedOutputContent): void;
|
|
61
62
|
resolvePage(pathname: string, manifest: ContentManifest, contentIndex: Map<string, string>): Promise<ResolvedPluginPage | null>;
|
|
62
63
|
getPagePaths(manifest: ContentManifest, contentIndex: Map<string, string>): Promise<readonly string[]>;
|
|
63
64
|
getPageRoutes(manifest: ContentManifest, contentIndex: Map<string, string>): Promise<readonly PluginPageRoute[]>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@riebeckite/core",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.22",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"tsx": "^4.22.4",
|
|
52
|
-
"@riebeckite/test": "0.0.
|
|
52
|
+
"@riebeckite/test": "0.0.22"
|
|
53
53
|
},
|
|
54
54
|
"repository": {
|
|
55
55
|
"type": "git",
|